--- /dev/null
+1 Notes on the Free Translation Project
+***************************************
+
+Free software is going international! The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that free software will gradually become able to speak many
+languages. A few packages already provide translations for their
+messages.
+
+ If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site. But you do _not_
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work on translations can contact the appropriate team.
+
+ When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used. The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+1.1 Quick configuration advice
+==============================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+ ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed. So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation. Future versions of GNU `gettext' will
+very likely convey even more functionality. So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+ So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+1.2 INSTALL Matters
+===================
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language. Most such
+packages use GNU `gettext'. Other packages have their own ways to
+internationalization, predating GNU `gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system already
+provides the GNU `gettext' functions. If not, the included GNU
+`gettext' library will be used. This library is wholly contained
+within this package, usually in the `intl/' subdirectory, so prior
+installation of the GNU `gettext' package is _not_ required.
+Installers may use special options at configuration time for changing
+the default behaviour. The commands:
+
+ ./configure --with-included-gettext
+ ./configure --disable-nls
+
+will, respectively, bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
+
+ When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this. This might not be desirable. You should use
+the more recent version of the GNU `gettext' library. I.e. if the file
+`intl/VERSION' shows that the library which comes with this package is
+more recent, you should use
+
+ ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+ The configuration process will not test for the `catgets' function
+and therefore it will not be used. The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
+
+ Internationalized packages usually have many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+1.3 Using This Package
+======================
+
+As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
+and `CC' is an ISO 3166 two-letter country code. For example, let's
+suppose that you speak German and live in Germany. At the shell
+prompt, merely execute `setenv LANG de_DE' (in `csh'),
+`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
+This can be done from your `.login' or `.profile' file, once and for
+all.
+
+ You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries. For
+example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
+country code serves to distinguish the dialects.
+
+ The locale naming convention of `LL_CC', with `LL' denoting the
+language and `CC' denoting the country, is the one use on systems based
+on GNU libc. On other systems, some variations of this scheme are
+used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
+locales supported by your system for your country by running the command
+`locale -a | grep '^LL''.
+
+ Not all programs have translations for all languages. By default, an
+English message is shown in place of a nonexistent translation. If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
+for the purpose of message handling, but you still need to have `LANG'
+set to the primary language; this is required by other parts of the
+system libraries. For example, some Swedish users who would rather
+read translations in German than English for when Swedish is not
+available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
+
+ Special advice for Norwegian users: The language code for Norwegian
+bokma*l changed from `no' to `nb' recently (in 2003). During the
+transition period, while some message catalogs for this language are
+installed under `nb' and some older ones under `no', it's recommended
+for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
+older translations are used.
+
+ In the `LANGUAGE' environment variable, but not in the `LANG'
+environment variable, `LL_CC' combinations can be abbreviated as `LL'
+to denote the language's main dialect. For example, `de' is equivalent
+to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
+(Portuguese as spoken in Portugal) in this context.
+
+1.4 Translating Teams
+=====================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list. The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
+area.
+
+ If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+`-request' appended. For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate
+_actively_ in translations, or at solving translational difficulties,
+rather than merely lurking around. If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation@iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skill are praised more than
+programming skill, here.
+
+1.5 Available Packages
+======================
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of April
+2005. The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+ Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB
+ +-------------------------------------------------+
+ GNUnet | |
+ a2ps | [] [] [] [] [] |
+ aegis | () |
+ ant-phone | () |
+ anubis | [] |
+ ap-utils | |
+ aspell | [] [] [] [] |
+ bash | [] [] |
+ batchelor | [] |
+ bfd | |
+ bibshelf | [] |
+ binutils | [] |
+ bison | [] [] |
+ bluez-pin | [] [] [] [] |
+ clisp | [] [] |
+ console-tools | [] [] |
+ coreutils | [] [] [] [] |
+ cpio | |
+ cpplib | [] [] [] |
+ darkstat | [] () [] |
+ dialog | [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] |
+ doodle | [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] |
+ error | [] [] [] [] |
+ fetchmail | [] () [] [] [] |
+ fileutils | [] [] |
+ findutils | [] [] [] |
+ flex | [] [] [] |
+ fslint | [] |
+ gas | |
+ gawk | [] [] [] |
+ gbiff | [] |
+ gcal | [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] |
+ gettext-runtime | [] [] [] [] |
+ gettext-tools | [] [] |
+ gimp-print | [] [] [] [] |
+ gip | |
+ gliv | [] |
+ glunarclock | |
+ gmult | [] [] |
+ gnubiff | () |
+ gnucash | [] () () [] |
+ gnucash-glossary | [] () |
+ gpe-aerial | [] [] |
+ gpe-beam | [] [] |
+ gpe-calendar | [] [] |
+ gpe-clock | [] [] |
+ gpe-conf | [] [] |
+ gpe-contacts | |
+ gpe-edit | [] |
+ gpe-go | [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] |
+ gpe-taskmanager | [] [] |
+ gpe-timesheet | [] |
+ gpe-today | [] [] |
+ gpe-todo | [] [] |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] |
+ gpsdrive | () () |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] |
+ gretl | |
+ gsasl | [] |
+ gss | |
+ gst-plugins | [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] () |
+ gtkspell | [] [] [] |
+ hello | [] [] [] [] |
+ id-utils | [] [] |
+ impost | |
+ indent | [] [] |
+ iso_3166 | |
+ iso_3166_1 | [] [] [] [] [] |
+ iso_3166_2 | |
+ iso_3166_3 | [] |
+ iso_4217 | |
+ iso_639 | |
+ jpilot | [] |
+ jtag | |
+ jwhois | |
+ kbd | [] [] [] [] |
+ latrine | () |
+ ld | [] |
+ libc | [] [] [] [] [] |
+ libextractor | |
+ libgpewidget | [] [] [] |
+ libgsasl | |
+ libiconv | [] [] [] [] [] |
+ libidn | |
+ lifelines | [] () |
+ lilypond | [] |
+ lingoteach | |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] |
+ make | [] [] |
+ man-db | [] () [] [] |
+ minicom | [] [] |
+ mysecretdiary | [] [] |
+ nano | [] () [] |
+ nano_1_0 | [] () [] [] |
+ opcodes | [] |
+ parted | [] [] [] [] |
+ psmisc | |
+ ptx | [] [] [] |
+ pwdutils | |
+ python | |
+ radius | [] |
+ recode | [] [] [] [] [] |
+ rpm | [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] [] [] |
+ sed | [] [] |
+ sh-utils | [] [] |
+ shared-mime-info | [] [] |
+ sharutils | [] [] [] [] [] |
+ silky | |
+ skencil | [] () |
+ sketch | [] () |
+ solfege | [] |
+ soundtracker | [] [] |
+ sp | [] |
+ stardict | [] |
+ tar | |
+ texinfo | [] [] |
+ textutils | [] [] [] |
+ tin | () () |
+ tp-robot | [] |
+ tuxpaint | [] [] [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] [] [] |
+ vorbis-tools | [] [] [] [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] |
+ wget | [] [] [] [] [] [] |
+ xchat | [] [] [] [] |
+ xkeyboard-config | |
+ xpad | |
+ +-------------------------------------------------+
+ af am ar az be bg bs ca cs cy da de el en en_GB
+ 10 0 0 2 7 4 0 41 43 3 52 90 20 1 15
+
+ eo es et eu fa fi fr ga gl he hr hu id is it
+ +-----------------------------------------------+
+ GNUnet | |
+ a2ps | [] [] [] () |
+ aegis | |
+ ant-phone | [] |
+ anubis | [] |
+ ap-utils | [] |
+ aspell | [] [] |
+ bash | [] [] [] [] |
+ batchelor | [] [] |
+ bfd | [] |
+ bibshelf | [] [] [] |
+ binutils | [] [] |
+ bison | [] [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] |
+ clisp | [] [] |
+ console-tools | |
+ coreutils | [] [] [] [] [] |
+ cpio | [] [] |
+ cpplib | [] [] |
+ darkstat | [] () [] [] [] |
+ dialog | [] [] [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] [] [] [] [] [] |
+ doodle | [] [] |
+ e2fsprogs | [] [] [] |
+ enscript | [] [] |
+ error | [] [] [] [] [] |
+ fetchmail | [] |
+ fileutils | [] [] [] [] [] [] |
+ findutils | [] [] [] [] [] |
+ flex | [] [] [] |
+ fslint | [] |
+ gas | [] [] |
+ gawk | [] [] [] [] |
+ gbiff | [] |
+ gcal | [] [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] |
+ gettext-tools | [] [] [] |
+ gimp-print | [] [] |
+ gip | [] [] [] |
+ gliv | () |
+ glunarclock | [] [] [] |
+ gmult | [] [] [] |
+ gnubiff | () () |
+ gnucash | [] () [] |
+ gnucash-glossary | [] [] |
+ gpe-aerial | [] [] |
+ gpe-beam | [] [] |
+ gpe-calendar | [] [] [] [] |
+ gpe-clock | [] [] [] |
+ gpe-conf | [] |
+ gpe-contacts | [] |
+ gpe-edit | [] [] |
+ gpe-go | [] [] |
+ gpe-login | [] [] [] |
+ gpe-ownerinfo | [] [] [] [] [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] [] |
+ gpe-taskmanager | [] [] [] |
+ gpe-timesheet | [] [] [] [] |
+ gpe-today | [] [] [] [] |
+ gpe-todo | [] [] [] |
+ gphoto2 | [] [] [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | () () [] () |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] [] [] [] [] [] [] |
+ gretl | [] [] [] |
+ gsasl | [] [] [] |
+ gss | [] |
+ gst-plugins | [] [] [] |
+ gstreamer | [] |
+ gtick | [] [] [] [] [] |
+ gtkspell | [] [] [] [] [] [] |
+ hello | [] [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ id-utils | [] [] [] [] |
+ impost | [] [] |
+ indent | [] [] [] [] [] [] [] [] [] [] [] |
+ iso_3166 | [] [] [] |
+ iso_3166_1 | [] [] [] [] [] [] [] |
+ iso_3166_2 | [] |
+ iso_3166_3 | [] |
+ iso_4217 | [] [] [] |
+ iso_639 | [] [] [] [] |
+ jpilot | [] [] |
+ jtag | [] |
+ jwhois | [] [] [] [] [] |
+ kbd | [] [] |
+ latrine | [] [] [] |
+ ld | [] [] |
+ libc | [] [] [] [] [] |
+ libextractor | |
+ libgpewidget | [] [] [] [] [] |
+ libgsasl | [] [] |
+ libiconv | [] [] [] [] [] [] [] [] [] [] [] |
+ libidn | [] [] |
+ lifelines | () |
+ lilypond | [] |
+ lingoteach | [] [] [] |
+ lynx | [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] [] |
+ make | [] [] [] [] [] [] [] |
+ man-db | () |
+ minicom | [] [] [] [] |
+ mysecretdiary | [] [] [] |
+ nano | [] [] () [] [] |
+ nano_1_0 | [] [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] [] [] |
+ psmisc | [] [] |
+ ptx | [] [] [] [] [] [] [] [] [] |
+ pwdutils | |
+ python | |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] [] |
+ rpm | [] |
+ screem | |
+ scrollkeeper | [] [] [] |
+ sed | [] [] [] [] [] |
+ sh-utils | [] [] [] [] [] [] [] |
+ shared-mime-info | [] [] [] [] [] [] |
+ sharutils | [] [] [] [] [] [] [] |
+ silky | [] |
+ skencil | [] [] |
+ sketch | [] [] |
+ solfege | [] |
+ soundtracker | [] [] [] |
+ sp | [] |
+ stardict | [] |
+ tar | [] [] [] [] [] |
+ texinfo | [] [] [] |
+ textutils | [] [] [] [] [] |
+ tin | [] () |
+ tp-robot | [] [] |
+ tuxpaint | [] [] [] [] [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | [] [] |
+ util-linux | [] [] [] [] [] [] |
+ vorbis-tools | [] [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] [] [] [] [] |
+ wget | [] [] [] [] [] [] [] [] [] [] |
+ xchat | [] [] [] [] [] |
+ xkeyboard-config | |
+ xpad | [] [] [] |
+ +-----------------------------------------------+
+ eo es et eu fa fi fr ga gl he hr hu id is it
+ 13 85 21 15 2 35 115 45 17 8 6 40 27 1 45
+
+ ja ko ku lg lt lv mk mn ms mt nb nl nn no nso
+ +-----------------------------------------------+
+ GNUnet | |
+ a2ps | () [] [] () |
+ aegis | () |
+ ant-phone | [] |
+ anubis | [] [] [] |
+ ap-utils | |
+ aspell | [] [] |
+ bash | [] |
+ batchelor | [] |
+ bfd | |
+ bibshelf | |
+ binutils | |
+ bison | [] [] [] |
+ bluez-pin | [] |
+ clisp | [] |
+ console-tools | |
+ coreutils | [] [] |
+ cpio | |
+ cpplib | |
+ darkstat | [] [] |
+ dialog | [] |
+ diffutils | [] [] [] |
+ doodle | |
+ e2fsprogs | |
+ enscript | [] |
+ error | [] |
+ fetchmail | [] [] |
+ fileutils | [] [] |
+ findutils | [] |
+ flex | [] [] |
+ fslint | [] |
+ gas | |
+ gawk | [] [] |
+ gbiff | [] |
+ gcal | |
+ gcc | |
+ gettext-examples | [] [] |
+ gettext-runtime | [] [] [] |
+ gettext-tools | [] [] |
+ gimp-print | [] [] |
+ gip | [] |
+ gliv | [] |
+ glunarclock | [] [] |
+ gmult | [] |
+ gnubiff | |
+ gnucash | () () [] |
+ gnucash-glossary | [] |
+ gpe-aerial | [] |
+ gpe-beam | [] |
+ gpe-calendar | [] |
+ gpe-clock | [] |
+ gpe-conf | [] |
+ gpe-contacts | |
+ gpe-edit | [] |
+ gpe-go | [] |
+ gpe-login | [] |
+ gpe-ownerinfo | [] |
+ gpe-sketchbook | [] |
+ gpe-su | [] |
+ gpe-taskmanager | [] [] |
+ gpe-timesheet | [] |
+ gpe-today | [] |
+ gpe-todo | [] |
+ gphoto2 | [] [] |
+ gprof | |
+ gpsdrive | () () () |
+ gramadoir | () |
+ grep | [] [] [] |
+ gretl | |
+ gsasl | [] |
+ gss | |
+ gst-plugins | [] |
+ gstreamer | [] |
+ gtick | [] |
+ gtkspell | [] [] |
+ hello | [] [] [] [] [] [] [] [] |
+ id-utils | [] |
+ impost | |
+ indent | [] [] |
+ iso_3166 | [] |
+ iso_3166_1 | [] [] |
+ iso_3166_2 | [] |
+ iso_3166_3 | [] |
+ iso_4217 | [] [] [] |
+ iso_639 | [] [] [] |
+ jpilot | () () () |
+ jtag | |
+ jwhois | [] |
+ kbd | [] |
+ latrine | [] |
+ ld | |
+ libc | [] [] [] [] [] |
+ libextractor | |
+ libgpewidget | [] |
+ libgsasl | [] |
+ libiconv | [] |
+ libidn | |
+ lifelines | [] |
+ lilypond | [] |
+ lingoteach | [] |
+ lynx | [] [] |
+ m4 | [] [] |
+ mailutils | |
+ make | [] [] [] |
+ man-db | () |
+ minicom | [] |
+ mysecretdiary | [] |
+ nano | [] [] |
+ nano_1_0 | [] [] [] |
+ opcodes | [] |
+ parted | [] [] |
+ psmisc | [] [] |
+ ptx | [] [] [] |
+ pwdutils | |
+ python | |
+ radius | |
+ recode | [] |
+ rpm | [] [] |
+ screem | [] |
+ scrollkeeper | [] [] [] |
+ sed | [] [] |
+ sh-utils | [] [] |
+ shared-mime-info | [] [] [] [] |
+ sharutils | [] [] |
+ silky | [] |
+ skencil | |
+ sketch | |
+ solfege | [] [] |
+ soundtracker | |
+ sp | () |
+ stardict | [] [] |
+ tar | [] [] |
+ texinfo | [] [] [] |
+ textutils | [] [] [] |
+ tin | |
+ tp-robot | [] |
+ tuxpaint | [] [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] |
+ vorbis-tools | [] |
+ wastesedge | [] |
+ wdiff | [] [] |
+ wget | [] [] |
+ xchat | [] [] [] [] |
+ xkeyboard-config | [] |
+ xpad | [] |
+ +-----------------------------------------------+
+ ja ko ku lg lt lv mk mn ms mt nb nl nn no nso
+ 33 11 1 1 1 2 2 3 11 0 15 96 7 5 0
+
+ or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
+ +-------------------------------------------------+
+ GNUnet | |
+ a2ps | () [] [] [] [] [] [] |
+ aegis | () () |
+ ant-phone | [] |
+ anubis | [] [] [] |
+ ap-utils | () |
+ aspell | [] [] |
+ bash | [] [] [] |
+ batchelor | [] |
+ bfd | |
+ bibshelf | |
+ binutils | [] [] |
+ bison | [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] [] [] |
+ clisp | [] |
+ console-tools | [] |
+ coreutils | [] [] [] [] |
+ cpio | [] [] |
+ cpplib | |
+ darkstat | [] [] [] [] [] [] |
+ dialog | [] [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] [] |
+ doodle | [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] |
+ error | [] [] [] |
+ fetchmail | [] () [] [] [] |
+ fileutils | [] [] [] [] [] |
+ findutils | [] [] [] [] [] [] |
+ flex | [] [] [] [] [] |
+ fslint | [] [] [] |
+ gas | |
+ gawk | [] [] [] [] |
+ gbiff | [] |
+ gcal | [] |
+ gcc | |
+ gettext-examples | [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] [] [] |
+ gimp-print | [] [] |
+ gip | [] [] [] |
+ gliv | [] [] [] |
+ glunarclock | [] [] [] [] [] [] |
+ gmult | [] [] [] [] |
+ gnubiff | () [] |
+ gnucash | () [] [] [] [] |
+ gnucash-glossary | [] [] [] |
+ gpe-aerial | [] [] [] [] [] [] |
+ gpe-beam | [] [] [] [] [] [] |
+ gpe-calendar | [] [] [] [] [] [] [] |
+ gpe-clock | [] [] [] [] [] [] [] |
+ gpe-conf | [] [] [] [] [] [] |
+ gpe-contacts | [] [] [] |
+ gpe-edit | [] [] [] [] [] [] [] |
+ gpe-go | [] [] [] [] [] |
+ gpe-login | [] [] [] [] [] [] [] |
+ gpe-ownerinfo | [] [] [] [] [] [] [] |
+ gpe-sketchbook | [] [] [] [] [] [] [] |
+ gpe-su | [] [] [] [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] [] [] [] |
+ gpe-timesheet | [] [] [] [] [] [] [] |
+ gpe-today | [] [] [] [] [] [] [] |
+ gpe-todo | [] [] [] [] [] [] [] |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | [] |
+ gramadoir | [] |
+ grep | [] [] [] [] [] [] [] |
+ gretl | [] |
+ gsasl | [] [] [] [] [] |
+ gss | [] [] [] |
+ gst-plugins | [] [] [] [] |
+ gstreamer | [] [] [] [] |
+ gtick | [] [] [] |
+ gtkspell | [] [] [] [] [] [] |
+ hello | [] [] [] [] [] [] [] |
+ id-utils | [] [] [] [] |
+ impost | |
+ indent | [] [] [] [] [] [] |
+ iso_3166 | [] [] [] [] [] |
+ iso_3166_1 | [] [] [] [] |
+ iso_3166_2 | |
+ iso_3166_3 | [] [] [] |
+ iso_4217 | [] [] |
+ iso_639 | [] [] [] |
+ jpilot | |
+ jtag | [] |
+ jwhois | [] [] [] () () |
+ kbd | [] [] [] |
+ latrine | [] [] |
+ ld | [] |
+ libc | [] [] [] [] [] |
+ libextractor | [] |
+ libgpewidget | [] [] [] [] [] [] |
+ libgsasl | [] [] [] |
+ libiconv | [] [] [] [] [] [] [] [] [] [] |
+ libidn | [] () |
+ lifelines | [] [] |
+ lilypond | [] |
+ lingoteach | [] |
+ lynx | [] [] [] |
+ m4 | [] [] [] [] [] |
+ mailutils | [] [] [] |
+ make | [] [] [] [] |
+ man-db | [] [] |
+ minicom | [] [] [] [] |
+ mysecretdiary | [] [] [] [] |
+ nano | [] [] [] |
+ nano_1_0 | [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] [] [] |
+ psmisc | [] [] |
+ ptx | [] [] [] [] [] [] |
+ pwdutils | [] |
+ python | |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] |
+ rpm | [] [] [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] [] |
+ sed | [] [] [] [] [] [] [] [] |
+ sh-utils | [] [] [] |
+ shared-mime-info | [] [] [] [] [] |
+ sharutils | [] [] [] |
+ silky | [] |
+ skencil | [] [] [] |
+ sketch | [] [] [] |
+ solfege | |
+ soundtracker | [] [] |
+ sp | |
+ stardict | [] [] |
+ tar | [] [] [] [] |
+ texinfo | [] [] [] [] |
+ textutils | [] [] [] |
+ tin | |
+ tp-robot | [] |
+ tuxpaint | [] [] [] [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] [] |
+ vorbis-tools | [] [] |
+ wastesedge | |
+ wdiff | [] [] [] [] [] [] |
+ wget | [] [] [] [] [] [] [] [] [] |
+ xchat | [] [] [] [] [] [] |
+ xkeyboard-config | |
+ xpad | |
+ +-------------------------------------------------+
+ or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
+ 1 0 48 30 58 6 79 71 5 45 13 12 50 86 0
+
+ tg th tk tr uk ven vi wa xh zh_CN zh_TW zu
+ +--------------------------------------------+
+ GNUnet | | 0
+ a2ps | [] [] [] | 19
+ aegis | | 0
+ ant-phone | [] | 4
+ anubis | [] | 9
+ ap-utils | () | 1
+ aspell | [] [] [] | 13
+ bash | | 10
+ batchelor | [] [] | 7
+ bfd | | 1
+ bibshelf | [] | 5
+ binutils | [] | 6
+ bison | [] | 17
+ bluez-pin | [] [] [] [] [] | 24
+ clisp | | 7
+ console-tools | [] | 4
+ coreutils | [] | 16
+ cpio | [] [] | 6
+ cpplib | [] [] | 7
+ darkstat | [] () () | 15
+ dialog | [] [] [] | 25
+ diffutils | [] [] [] [] | 28
+ doodle | [] | 5
+ e2fsprogs | [] | 8
+ enscript | [] | 12
+ error | [] [] [] | 16
+ fetchmail | [] | 12
+ fileutils | [] [] [] | 18
+ findutils | [] [] | 17
+ flex | [] [] | 15
+ fslint | [] | 7
+ gas | [] | 3
+ gawk | [] | 14
+ gbiff | | 4
+ gcal | [] | 5
+ gcc | [] | 3
+ gettext-examples | [] [] [] [] | 20
+ gettext-runtime | [] [] [] [] [] | 25
+ gettext-tools | [] [] [] | 17
+ gimp-print | [] | 11
+ gip | [] | 8
+ gliv | [] | 6
+ glunarclock | [] [] | 13
+ gmult | [] [] [] | 13
+ gnubiff | [] | 3
+ gnucash | () [] | 10
+ gnucash-glossary | [] | 8
+ gpe-aerial | [] [] | 13
+ gpe-beam | [] [] | 13
+ gpe-calendar | [] [] [] [] | 18
+ gpe-clock | [] [] [] [] | 17
+ gpe-conf | [] [] | 12
+ gpe-contacts | [] [] | 6
+ gpe-edit | [] [] [] [] | 15
+ gpe-go | [] [] | 11
+ gpe-login | [] [] [] [] [] | 18
+ gpe-ownerinfo | [] [] [] [] | 19
+ gpe-sketchbook | [] [] | 14
+ gpe-su | [] [] [] | 16
+ gpe-taskmanager | [] [] [] | 17
+ gpe-timesheet | [] [] [] [] | 17
+ gpe-today | [] [] [] [] [] | 19
+ gpe-todo | [] [] [] | 16
+ gphoto2 | [] [] | 17
+ gprof | [] [] | 10
+ gpsdrive | | 2
+ gramadoir | [] | 6
+ grep | [] [] [] [] | 32
+ gretl | | 4
+ gsasl | [] [] | 12
+ gss | [] | 5
+ gst-plugins | [] [] | 16
+ gstreamer | [] [] [] | 14
+ gtick | [] | 11
+ gtkspell | [] [] [] | 20
+ hello | [] [] [] [] | 37
+ id-utils | [] [] | 13
+ impost | [] | 3
+ indent | [] [] [] | 24
+ iso_3166 | [] [] [] | 12
+ iso_3166_1 | [] [] | 20
+ iso_3166_2 | | 2
+ iso_3166_3 | [] [] | 8
+ iso_4217 | [] [] | 10
+ iso_639 | [] [] | 12
+ jpilot | [] [] [] | 6
+ jtag | | 2
+ jwhois | [] [] [] | 12
+ kbd | [] [] | 12
+ latrine | [] [] | 8
+ ld | [] | 5
+ libc | [] [] | 22
+ libextractor | | 1
+ libgpewidget | [] [] | 17
+ libgsasl | [] | 7
+ libiconv | [] [] [] [] [] | 32
+ libidn | [] [] | 5
+ lifelines | | 4
+ lilypond | [] | 5
+ lingoteach | | 5
+ lynx | [] [] | 14
+ m4 | [] [] | 17
+ mailutils | [] | 7
+ make | [] [] | 18
+ man-db | | 5
+ minicom | | 11
+ mysecretdiary | [] [] | 12
+ nano | | 11
+ nano_1_0 | [] [] | 17
+ opcodes | [] | 7
+ parted | [] [] [] | 17
+ psmisc | [] | 7
+ ptx | [] [] | 23
+ pwdutils | | 1
+ python | | 0
+ radius | [] | 6
+ recode | [] [] | 22
+ rpm | [] [] | 11
+ screem | | 1
+ scrollkeeper | [] [] | 23
+ sed | [] [] | 19
+ sh-utils | [] | 15
+ shared-mime-info | [] [] | 19
+ sharutils | [] [] [] | 20
+ silky | | 3
+ skencil | | 6
+ sketch | | 6
+ solfege | | 4
+ soundtracker | [] | 8
+ sp | [] | 3
+ stardict | [] [] [] [] | 10
+ tar | [] [] | 13
+ texinfo | [] [] | 14
+ textutils | [] [] [] | 17
+ tin | | 1
+ tp-robot | [] [] | 7
+ tuxpaint | [] [] [] [] | 34
+ unicode-han-tra... | | 0
+ unicode-transla... | | 2
+ util-linux | [] [] | 17
+ vorbis-tools | [] | 10
+ wastesedge | | 1
+ wdiff | [] [] | 22
+ wget | [] [] [] [] | 31
+ xchat | [] [] [] | 22
+ xkeyboard-config | | 1
+ xpad | [] | 5
+ +--------------------------------------------+
+ 72 teams tg th tk tr uk ven vi wa xh zh_CN zh_TW zu
+ 147 domains 0 0 1 78 29 0 71 16 0 41 20 0 1711
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer. There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+ If April 2005 seems to be old, you may fetch a more recent copy of
+this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
+matrix with full percentage details can be found at
+`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
+
+1.6 Using `gettext' in new packages
+===================================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU `gettext' in your
+package. Of course you have to respect the GNU Library General Public
+License which covers the use of the GNU `gettext' library. This means
+in particular that even non-free programs can use `libintl' as a shared
+library, whereas only free software can use `libintl' as a static
+library or use modified versions of `libintl'.
+
+ Once the sources are changed appropriately and the setup can handle
+the use of `gettext' the only thing missing are the translations. The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project. Therefore the information given above
+applies also for every other Free Software Project. Contact
+`translation@iro.umontreal.ca' to make the `.pot' files available to
+the translation teams.
+
--- /dev/null
+Wed Feb 16 10:06:17 IST 2000
+
+Gawk was written by Paul Rubin, and finished by Paul Finlason and
+Richard Stallman.
+
+David Trueman and Arnold Robbins took it over, with David doing most
+of the work to make it compatible with new awk.
+
+Circa 1994, Arnold Robbins took over maintenance.
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Tue Jul 26 21:44:54 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Copyright dates on all relevant files updated to 2005.
+
+Wed Jul 6 17:09:02 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Minor cleanups:
+
+ * io.c (do_index): Remove unused variables `mbclen', `mbs1' and `mbs2'.
+ * node.c (wstrstr): Remove unsed variable `j'.
+ (dump_wstr): `#ifdef' out, not currently needed.
+ * eval.c (op_assign): Move decl of `t1' and `t2' into a separate block for
+ the `! HAVE_FMOD' case. Keeps the compiler quiet. Similar for `ltemp'.
+
+Wed Jul 6 16:51:31 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (close_io): Now takes pointer to boolean parameter indicating
+ if there was a problem closing standard output or standard error.
+ Update it in the right places.
+ * awk.h (close_io): Update the declaration.
+ * main.c (main): New variable `stdio_problem'. Pass it to `close_io'.
+ Check the result and exit non-zero if there was a problem.
+ (usage, version): Print warning message if problems with stdout.
+
+ Unrelated:
+
+ * main.c (main): For call to `setlocale' for LC_MESSAGES, just use
+ `#ifdef LC_MESSAGES'. Per Bruno Haible <bruno@clisp.org>.
+
+Wed Jul 6 16:44:58 2005 Jim Meyering <jim@meyering.net>
+
+ * main.c (init_fds): If any of the STDIN_FILENO, STDOUT_FILENO,
+ STDERR_FILENO are initially closed, reopen them with permissions
+ contrary to common usage so that any reasonable attempt to use
+ them will evoke the same sort of error as reading or writing to
+ a closed file descriptor would.
+
+Mon Jul 4 09:38:29 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ More multibyte fixes from Kimura Koichi, <kimura.koichi@canon.co.jp>.
+
+ * node.c (format_val, r_dupnode): Spell `wstptr' correctly.
+ * regex_internal.c (build_wcs_upper_buffer): Label `offsets_needed' should not
+ be inside `#ifdef _LIBC'.
+ * regcomp.c (build_charclass): Fix declaration of `class_name' in prototype to
+ not be unsigned.
+
+Thu Jun 30 11:52:34 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (tree_eval): Node_not: Remember to print the exclamation
+ point! Thanks to Dan Nielsen <Dan.Nielsen@corporate.ge.com>
+ for the bug report.
+ * mbsupport.h: Fix spelling of HAVE_ISWUPPER. Thanks to
+ Kimura Koichi, <kimura.koichi@canon.co.jp>.
+
+Sun Jun 26 16:37:59 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Unrelated changes:
+
+ * builtin.c (do_length): Allow array argument to length().
+ Returns number of elements in array.
+
+ * awkgram.y (yylex): Ignore carriage returns in source code. Sigh.
+
+Wed Jun 15 22:12:15 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (isnondecimal): Check loc.decimal_point before using it.
+ Avoids problems with command line assignment when locale info may
+ not be set up all the way yet.
+
+Wed Jun 15 21:59:54 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (make_str_node): If working with multibyte characters, while
+ parsing string constants, keep multibyte characters together. This avoids
+ problems in cases where one of the bytes is backslash. Initial patch
+ supplied by Kimura Koichi, <kimura.koichi@canon.co.jp>.
+
+Tue Jun 14 21:50:37 2005 Andrew J. Schorr <ajschorr@users.sourceforge.net>
+
+ Use Exponentiation By Squaring for integer powers for ^ and ^=.
+
+ * eval.c (calc_exp, cal_exp_posint): New functions.
+ (r_tree_eval): Use them.
+
+Fri Jun 3 12:15:54 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Further change the hack at the end so that
+ it works on Mac OS X `sed'. Sigh.
+
+Thu Jun 2 22:44:01 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (TYPE_SOCKLEN_T): Use `int' as default type if can't
+ figure one out.
+ * awkgram.y: Warn that `//' is not a C++ comment. (:-)
+
+Thu Jun 2 20:55:27 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ From: Benno Schulenberg <benno@nietvergeten.nl>
+
+ * eval.c (func_call): Take message out of gettext call since it's for debugging.
+ * ext.c (get_actual_argument): Fix formatting of message.
+
+Wed May 25 09:19:37 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Change hack at end that fixes Makefile to keep
+ version.c to use `sed' and not `ed'. More portable to OS/2, probably
+ other systems.
+
+Mon May 23 09:01:26 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Portability help from Jim Meyering.
+
+ * io.c: Rework ifdefs for <inttypes.h> and <stdint.h>. Test them
+ individually.
+ * configure.ac: Add AC_C_RESTRICT and code for socklen_t from rsync.
+ Check for isascii and btowc for regex.
+
+Sat May 14 22:49:54 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * wait_any (errno): Remove decl.
+ * gawk_popen: The pipe-simulated but not VMS or DOS version. Remove
+ decl/use of `strdup' in favor of `emalloc' and `strcpy'.
+
+Wed May 11 18:33:30 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ All files: Updated address of FSF to:
+
+ 51 Franklin Street, Fifth Floor
+ Cambridge, MA 02110-1301
+
+Wed May 11 18:19:03 2005 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Use AM_GNU_GETTEXT([external]).
+ Reflect upgrade to gettext-0.14.4.
+ Reflect renaming of `jm_'-prefixed macros.
+ (AC_CONFIG_FILES): Remove intl/Makefile.
+
+ * Makefile.am (SUBDIRS): Remove intl.
+ (AM_CPPFLAGS): Remove -Iintl.
+
+Wed May 11 11:42:06 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Straighten out mess with `isblank' which is C99 <ctype.h> function.
+
+ * configure.ac: Remove check for `isblank' in call to AC_CHECK_FUNCS.
+ * regex_internal.h: #ifdef out definition of `isblank' and provide `is_blank'
+ function a la dfa.c.
+ * field.c: Ditto.
+ * regcomp.c: #ifdef use of `isblank' and add `is_blank' use instead.
+
+Mon May 9 08:29:37 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add type check for `socklen_t', fixes compile
+ warning on AMD/64 Linux.
+ * io.c (socketopen): Change type of socket lenght variables
+ to `socklen_t' from `size_t'.
+
+Thu May 5 22:00:03 2005 John E. Haque <j.eh@mchsi.com>
+
+ * io.c (iop_alloc): Let a input processor hook installed via
+ `register_open_hooks' open its own fd in case gawk does not know
+ how to open it.
+ (iop_open): Call `os_close_on_exec' after `iop_alloc'.
+ ADR: If `iop_alloc' returns NULL but the fd is valid, close
+ the fd to avoid an fd leak.
+
+Mon May 2 08:05:59 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (update_ERRNO): Don't use `return' in a `void' function.
+ * awk.h (AWKNUM): Back out use of `long double' based on LDBL_MANT_DIG.
+ * builtin.c (tmp_integer): Back out extra ifdefs.
+
+Fri Apr 29 13:01:05 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Look for `isblank' function.
+ * field.c: Add define for `isblank' if we don't have it.
+
+Fri Apr 29 12:01:33 2005 Julian Foad <julianfoad@btopenworld.com>
+
+ From grep. Doesn't seem to affect awk.
+
+ * dfa.c (lex): Fix bug #9519: "echo do^re | grep do^re" was
+ failing to find a match. [Towards end, set `lasttok' before
+ returning `c'.]
+
+Fri Apr 29 00:28:46 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Jump through an amazingly convoluted hoop to get
+ config.status to keep version.c upon `make distclean'. Seems to
+ work though.
+
+Thu Apr 28 23:40:02 2005 Stepan Kasal <kasal@ucw.cz>
+
+ * configure.ac (PRINTF_HAS_F_FORMAT): Some cosmetic changes.
+ (custom.h): Don't cat custom.h at the end of config.h; instead, use
+ AH_BOTTOM([#include "custom.h"])
+ * awklib/Makefile.am (AM_CPPFLAGS): Add $(top_srcdir) so that
+ custom.h can be found.
+
+Thu Apr 28 23:21:22 2005 Jim Meyering <jim@meyering.net>
+
+ * field.c (set_FIELDWIDTHS): Tighten up the code to accept FIELDWIDTHS
+ values in [1..INT_MAX], e.g., detect overflow and invalid strings,
+ and reject strings starting with `-'.
+
+Thu Apr 28 23:05:33 2005 Stepan Kasal <kasal@ucw.cz>
+
+ * dfa.c (parse_bracket_exp_mb): Shorten one part of the code, to get
+ closer to grep's copy.
+
+Thu Apr 28 23:00:58 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * builtin.c (format_tree) [#if VAXCRTL]: For floating point
+ formatting, reject zero_flag if using old VAXCRTL run-time
+ library to avoid getting erroneous results which appear as if
+ numerically incorrect (due to an embedded space in some cases,
+ extra trailing zeroes in others) rather than just misformatted.
+ `hsprint' test still fails, but not as badly.
+
+Thu Apr 28 19:12:03 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (reflags2str): Add three new RE_ flags from current regex.h
+ to bring the table up to date.
+
+ * builtin.c (format_tree): Save 2 spare bytes instead of one. Suggested
+ by Stepan Kasal.
+
+Thu Apr 28 18:16:09 2005 Andrew J. Schorr <ajschorr@users.sourceforge.net>
+
+ * awk.h (IOBUF): Add new fields `opaque', `get_record', and `close_func',
+ to support insertion of an alternate input processor. This is used
+ by the XML extension.
+ (register_deferred_variable, register_open_hook, update_ERRNO_saved):
+ Declare new functions.
+ (load_environ, load_procinfo): Remove declarations -- these functions
+ are no longer global, since we use register_deferred_variable instead.
+ * awkgram.y (register_deferred_variable): New function to allow
+ calling code to register special variable names that trigger a callback
+ upon the first reference. This is now used to implement ENVIRON
+ and PROCINFO.
+ (variable): Search the list of deferred variables instead of hardcoded
+ tests for ENVIRON and PROCINFO.
+ * eval.c (set_BINMODE): Fix spelling of "arbitrary" in warning message.
+ (update_ERRNO_saved): New function that allows the caller to specify
+ the errno value instead of using the current value.
+ (update_ERRNO): Implement by calling update_ERRNO_saved(errno).
+ * io.c (iop_close): Call `iop->close_func' if non-NULL.
+ (close_redir): Should save `errno' value, otherwise `lintwarn' messages
+ might update it. Then use `update_ERRNO_saved' to set ERRNO.
+ (do_getline): Call `update_ERRNO_saved' to set ERRNO based on the
+ error code returned by the redirect function (instead of the current
+ value of errno). Similarly, use `update_ERRNO_saved' to set ERRNO
+ based on the value returned by `get_a_record'. But add a special
+ check to avoid updating ERRNO if `get_a_record' returns an error
+ code value of -1 (this is used by the XML extension which already
+ sets ERRNO before returning).
+ (register_open_hook): New function to register a function to be
+ called whenever a new data file is opened. This can be used to
+ install a special input processor (as in the XML extension).
+ (iop_alloc): Call registered open hook.
+ (get_a_record): If a `get_record' method has been set, call that instead.
+ * main.c (init_vars): Use `register_deferred_variable' to implement
+ ENVIRON and PROCINFO.
+ (load_environ, load_procinfo): Now static instead of global.
+ * doc/gawk.texi: Document new internal functions `update_ERRNO_saved',
+ `register_deferred_variable', and `register_open_hook'.
+
+Thu Apr 28 10:50:10 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_find, do_delete): Change incorrect uses of STREQN
+ to memcmp.
+ * builtin.c (do_index): Same.
+ * field.c (set_FS): Same.
+ * io.c (redirect, getredirect, do_close, set_RS): Same.
+ * re.c (reisstring): Same.
+
+Wed Apr 27 21:35:57 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Allow for long double. Initial changes from Jean-Marc Saffroy
+ <jean-marc.saffroy@ext.bull.net>.
+
+ * awk.h (AWKNUM): If have long doubles (LDBL_MANT_DIG), define AWKNUM
+ as long double, otherwise just use double.
+ * builtin.c (format_tree): Change type of tmpval to double.
+ (do_strtonum): Same for `d' and types used in casts.
+ (tmp_integer): Don't do bit shifting if have long doubles.
+
+ Unrelated, from Andrew J. Schorr:
+
+ * io.c (close_one): Check for RED_FILE|RED_WRITE, not just RED_FILE.
+
+Mon Apr 25 12:23:18 2005 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * eval.c (r_tree_eval): In Node_assign_concat case, when copying string
+ constants, include the terminating zero byte.
+
+Fri Apr 1 06:26:31 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to Automake 1.9.5.
+
+ * INSTALL, aclocal.m4, depcomp, install-sh, missing,
+ mkinstalldirs, ylwrap: Updated.
+
+ Unrelated:
+
+ * builtin.c (do_tolower, do_toupper): Remove old code
+ based on 8-bit character table.
+
+Wed Feb 23 08:23:22 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bisonfix.awk: New file, fixes continued #ifdef for dumb compilers.
+ * Makefile.am (awkgram.c): Fix rule to use it.
+ (EXTRA_DIST): Include bisonfix.awk.
+
+Tue Feb 22 21:18:50 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.h: Remove include of config.h and move it to ...
+ * random.c: Here. Move include of random.h back to where it was.
+
+ * regcomp.c, regex.c, regexec.c: NUKED all use of alloca not inside
+ `_LIBC' ifdef. Hooray!
+
+Sat Feb 19 20:13:28 2005 Pat Rankin <rankin@pactechdata.com>
+
+ Workarounds for bugs and missing C89 features in old VAX C compiler.
+
+ * regex_internal.h "mbsupport.h": Suppress inclusion if NO_MBSUPPORT
+ is defined.
+ [MB_CUR_MAX]: Define as 1 if mbsupport.h hasn't defined it.
+ [ER_ERRMSG, ERRMSG_TYPE, ERRMSG_OFFSET, ERRMSG_SEPARATOR]: New macros
+ conditionalized upon gawk's NO_TOKEN_PASTING macro.
+ * regcomp.c: Use them.
+ (parse_dup_op): Use alternate initialization of start_token if
+ RE_TOKEN_INIT_BUG is defined.
+ * regexec.c (proceed_next_node): Compare push_fail_stack() result
+ explicitly against REG_NOERROR rather than implicitly against 0.
+
+Sat Feb 19 20:05:50 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * dfa.c "mbsupport.h": Suppress inclusion if NO_MBSUPPORT is defined.
+
+Wed Feb 16 20:43:07 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * awk.h "mbsupport.h": Suppress inclusion if NO_MBSUPPORT is defined.
+ * regex.h <sys/types.h>: Guard inclusion with HAVE_SYS_TYPES_H.
+ * regex.c <sys/types.h>: Likewise.
+ * random.c "random.h": include this first to get config.h setup.
+ <fcntl.h>: Guard inclusion with HAVE_FCNTL_H.
+ <unistd.h>: Guard inclusion with HAVE_UNISTD_H.
+ * io.c [#if defined(MSDOS) ||... defined(__CYGWIN__)]: Splice the
+ backslash continuation back into one long line.
+
+Wed Feb 16 10:11:21 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (unref, format_val): Add assertions checking that both
+ `tmp->wstptr != NULL' and `(tmp->flags & WSTRCUR) != 0' before
+ freeing `tmp->wstptr'. Thanks to kimura.koichi@canon.co.jp.
+
+ * random.c (HAVE_UNISTD_H): Conditionalize include of <unistd.h>.
+ Thanks to Scott Deifik <scottd@amgen.com>.
+
+Sun Feb 13 18:24:50 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (socketopen): Move `#ifdef MSG_PEEK' up to above
+ declarations too. Thanks to Michal Jaegermann.
+
+ * config.guess, config.sub: Updated from Savannah.
+
+Thu Feb 10 15:48:48 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.c (re_dfa_add_node): Remove variable `type'
+ and just use `token.type' directly in RE_ENABLE_I18N code below.
+ Saves a compiler warning, and a good compiler will handle it anyway.
+ * regexec.c (check_arrival_add_next_nodes): Move decl of `err'
+ inside #ifdef RE_ENABLE_I18N code where it's used.
+ * awkgram.y (yylex): Add casts to int before use of `strlen' results
+ for printf-style precision. Avoid a compiler warning.
+ * io.c (redirect, do_close): Same for use of tmp->stlen.
+
+ Thanks to Michal Jaegermann <michal@harddata.com>.
+
+Wed Feb 9 10:19:15 2005 Stepan Kasal <kasal@ucw.cz>
+
+ * Makefile.am (datadir, libexecdir): Removed.
+ (awkdatadir): Renamed to pkgdatadir.
+ (pkgdatadir, LDADD): Use the make syntax to refer to other variables,
+ not @...@.
+
+Wed Feb 9 10:05:46 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (r_dupnode): Assign NULL to r->wstr after `getnode'.
+ Fix count of bytes to copy in call to `memcpy'.
+ Thanks to Kimura Koichi, <kimura.koichi@canon.co.jp>.
+
+Tue Feb 8 19:26:22 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * regcomp.c (init_dfa): Avoid strcasecmp() since regex.c doesn't
+ use awk.h and none of the assorted other included header files
+ are guaranteed to declare it.
+ (parse_expression): Modify casts for the string arguments passed to
+ build_charclass_op() to fix char * vs unsigned char * mismatch.
+ (parse_bracket_exp): Likewise add cast for the string argument
+ passed to build_charclass().
+
+Mon Feb 7 15:04:09 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (make_scalar): Don't use P() macro in definition.
+ Thanks to Juergen Kahrs <Juergen.Kahrs@barco.com>.
+
+Wed Feb 2 16:36:19 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Call `close_io', without its result affecting
+ the exit status. Super small, super dark corner.
+
+ See test/exitval2.awk.
+
+Tue Feb 1 11:58:29 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.h (__APPLE_CC__): Removed test and definition of __restrict.
+ Not needed for current MacOS X compiler.
+
+Sun Jan 30 13:56:37 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fresh merge with CVS regex routines. Fixes handling of \B.
+ See tests/gnureop3.awk and also
+ http://sources.redhat.com/bugzilla/show_bug.cgi?id=693.
+
+ CVS base versions:
+
+ * regcomp.c: Version 1.92, Thu Jan 27 19:05:20 2005.
+ * regexec.c: Version 1.77, Thu Jan 27 19:06:34 2005.
+ * regex_internal.c: Version 1.49, Thu Jan 27 19:07:15 2005.
+ * regex_internal.h: Version 1.60, Wed Jan 26 22:40:50 2005.
+ * regexec.c: Version 1.77, Thu Jan 27 19:06:34 2005.
+
+Sat Jan 22 22:30:40 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Reinstate patch of 18 Nov 2001, for VMS, at least:
+
+ * random.c (srandomdev): ifdef-out. Lots of compile time
+ problems on multiple platforms, and gawk doesn't even
+ use the routine. The heck with fine-grained solutions.
+
+Thu Jan 20 14:15:32 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (LEX_FOR): Free NAME tokens in transformation of
+ `for (iggy in foo) delete foo[iggy]' into `delete foo'.
+ Thanks and a tip of the hatlo to Valgrind.
+
+ * dfa.c (_): Clean up stuff here by just including "gettext.h".
+ Per Bruno Haible.
+
+Wed Jan 19 18:29:23 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yylex): Improve parsing of numeric constants
+ and hex values, via a push from Paul Eggert. See test/hex.awk.
+
+ * regex_internal.c (re_node_set_alloc): If `size' is 0, just
+ zero out the structure. From valgrind.
+
+Tue Jan 18 17:23:25 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Make gawk multibyte aware. This means that index(), length(),
+ substr() and match() all work in terms of characters, not bytes.
+
+ * awk.h (NODE): Add `wsp' and `wslen' elements to value for wide
+ string.
+ (WSTRCUR, wstptr, wstlen, force_wstring): New macros.
+ (str2wstr, wstrstr, wcasestrstr): New declarations.
+ * builtin.c (do_index, do_length, do_substr, do_match): Handle wide
+ strings.
+ * eval.c (flags2str): Add WSTRCUR.
+ * node.c (format_val, r_dupnode, mk_number, make_str_node, unref):
+ Add code to deal with wide strings.
+ (str2wstr, dump_wstr, wstrstr, wcasestrstr): New functions.
+
+Sun Jan 16 15:10:35 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.h (int32_t): Define this type.
+
+Thu Jan 13 14:38:13 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Cause `configure --disable-nls' to still allow locale-correct
+ formating of numeric values.
+
+ * builtin.c (format_tree): Change #ifdefs to only test HAVE_LOCALE_H.
+ Improve code for ' flag so that extraneous separator is not included if
+ number of digits is multiple of locale separater count (3, 6, 9, etc.)
+ * dfa.c (dfaparse): Change ifdef to only test #ifdef LC_COLLATE.
+ * eval.c (fmt_ok): Remove ENABLE_NLS from #ifdef test.
+ * gettext.h: Include <locale.h> on both sides of test. Should really
+ be factored out.
+ * main.c (loc): Remove ENABLE_NLS from #ifdef test.
+ (main): Same in call to localeconv().
+ * node.c (isnondecimal): Remove ENABLE_NLS from #ifdef test.
+
+ Unrelated:
+
+ * regcomp.c (init_dfa): Change `codeset' to `codeset_name' in two
+ places.
+
+Mon Jan 10 11:49:56 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Annual sync with glibc.
+
+ * getopt_int.h: New file.
+ * Makefile.am (base_sources): Add it.
+ * getopt.h, getopt.c, getopt1.c: Updated.
+ * regcomp.c, regex.c, regex.h, regex_internal.c, regex_internal.h,
+ regexec.c: Updated.
+
+ Original versions:
+
+ getopt_int.h, 1.1, Tue Mar 9 10:31:19 2004
+ getopt1.c, 1.10, Tue Mar 9 10:35:37 2004
+ getopt.h, 1.21, Fri Mar 19 00:19:32 2004
+ getopt.c, 1.53, Wed Mar 10 23:13:26 2004
+ regcomp.c, 1.87, Mon Dec 6 02:56:42 2004
+ regex.c, 1.126, Fri Jan 30 05:19:58 2004
+ regex.h, 1.33, Thu Nov 18 23:50:57 2004
+ regex_internal.c, 1.46, Thu Jan 6 20:59:49 2005
+ regex_internal.h, 1.57, Mon Dec 27 16:29:05 2004
+ regexec.c, 1.75, Mon Dec 27 16:29:52 2004
+
+ * regex.h: Add check for __APPLE_CC__ and definition of __restrict.
+ * regex.c: Add check for _MSC_VER and include <stdio.h>.
+ * regex_internal.h (_RE_ENABLE_I18N): Change test.
+ (re_realloc): Add check/fix for SunOS 4.1.x.
+ * regex_internal.c (build_wcs_upper_buffer): ifdef label
+ `offsets_needed', add cast in call to `wcrtomb'.
+ * regcomp.c (build_charclass, build_charclass_op): Remove `unsigned'
+ from declarations of `char *' params.
+ (regerror): Remove use of mempcpy.
+ (peek_token): Disallow \s and \S for gawk.
+ (build_charclass): Change decl of `class_name' and use it directly.
+ Nuke variable `name'.
+ (build_charclass_op): Change decl of `class_name' and `extra'.
+
+Thu Jan 6 16:44:32 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Improve autoconfiscation stuff for wide character use.
+
+ * builtin.c (do_tolower, do_toupper): Conditionally compile
+ call to `wide_tolower_toupper'.
+ (wide_tolower_toupper): Conditionally compile typedefs and function.
+ * mbsupport.h: Add check for having `wint_t', and `iswlower',
+ `iswupper', `towlower' and `towupper'.
+ * configure.ac (HAVE_WINT_T): Add test.
+ (AC_CHECK_FUNCS): Add `wint_t', `iswlower', `iswupper', `towlower'
+ and `towupper'.
+
+ Unrelated change:
+
+ * hard-locale.h (hard_locale): Add decl of `xmalloc' to prevent
+ redeclaration problems on some compilers.
+
+Wed Jan 5 10:20:17 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to Bison 2.0.
+
+ * bisonfix.sed: Removed, no longer needed.
+ * Makefile.am (EXTRA_DIST): Removed bisonfix.sed.
+ (awkgram.c): Fix build rule.
+ * awkgram.c: Regenerated.
+
+Tue Jan 4 18:47:56 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to Automake 1.9.4.
+
+ * alocal.m4, config.guess, config.sub, install-sh: Updated.
+
+Mon Jan 3 14:08:27 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to Automake 1.9.3.
+
+ * INSTALL, alocal.m4, config.guess, config.sub, depcomp,
+ install-sh, missing, ylwrap: Updated.
+
+Mon Jan 3 11:23:36 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix obscure issue. ^ in RS should only match at the very
+ beginning of the input. Essentially, the file is one long
+ string. To do this, use the `not_bol' flag in the `struct
+ pattern_buffer'. Thanks to Stepan Kasal for pointing out the
+ problem and to Andreas Schwab for pointing out the mechanism
+ for a solution.
+
+ * awk.h (RE_NEED_START, RE_NO_BOL): New flags for `research'.
+ (IOP_AT_START): New flag for IOBUF.
+ (research): Last parameter is now `flags'.
+ * builtin.c (do_match, sub_common): Change calls to `research'.
+ * eval.c (interpret, match_op): Same.
+ * field.c (re_parse_field): Same.
+ * io.c (spec_setup): Add IOP_AT_START flag.
+ (iop_alloc): Same.
+ (rsrescan): Modify logic to check IOP_AT_START and if not on to
+ add RE_NO_BOL to flags value in call to `research'.
+ (get_a_record): Clear IOP_AT_START upon return from `*matchrec'.
+ (iopflags2str): Add IOP_AT_START to table. Also IOP_CLOSED,
+ which was missing. (Ooops.)
+ * re.c (research): Last paramater is now flags. Modify logic to
+ handle RE_NO_BOL case by setting the right bit initially. Clean
+ up control flow so that it's cleared before returning. If RE_NO_BOL,
+ don't bother with the dfa matcher, as it doesn't have an analogous
+ capability.
+
+Wed Dec 22 12:33:48 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ For --exec, don't allow x=y assignments where filenames would be.
+ Do allow -v. This is because we assume --exec is used mainly for
+ CGI stuff and we don't want var assigns to affect the code.
+
+ Suggested by Stepan Kasal; motivated by reading about web security.
+
+ * main.c (disallow_var_assigns): New variable.
+ (main): Set the var for --exec.
+ (arg_assign): Check it appropriately.
+
+Sun Dec 19 17:27:09 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_gensub): Make `global' flag smarter, such that
+ a string numeric constant (e.g., "3") acts like a numeric
+ constant.
+ * node.c (r_force_number): Not really related: Only set NUMCUR
+ if we actually convert some digits.
+
+Sun Dec 19 16:08:50 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c: Synchronize with what's happening in GNU grep
+ development. Effectively only minor whitespace changes and some
+ slight code motion of ifdefs and includes.
+ * hard-locale.h: New file, extracted from old dfa.c.
+ * Makefile.am (base_sources): Add hard-locale.h.
+
+Sun Dec 19 11:13:45 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (socketopen): Change type of `readle' and `namelen'
+ variables to size_t. For QNX, but a good idea anyway. Thanks
+ to `Anthony' (rz1a@mail.ru).
+
+Mon Dec 6 11:11:22 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Undid change of Mar 9 2004, to add gofast patch. It gets things
+ wrong for gawk. This removes the bandaid of ifdef-ing out the
+ main check. Eventually this'll all get straightened out in the
+ GNU grep code.
+
+ * dfa.c (buf_offset): Removed.
+ (SKIP_REMAINS_MB_IF_INITIAL_STATE): Removed use of buf_offset, do
+ free `mblen_buf', `inputwcs'.
+ (match_anychar, match_mb_charset, transit_state_consume_1char,
+ transit_state): Remove use of buf_offset in mblen_buf.
+ (dfaexec): Use `free' and `malloc', not `realloc'.
+
+Mon Dec 6 10:55:37 2004 Fumitoshi UKAI <ukai@debian.or.jp>
+
+ Forwarded from james@nocrew.org, the Debian contact.
+
+ * dfa.c (parse_bracket_exp_mb):
+ 1. Build range correctly when IGNORECASE for [a-a] to also get 'A'.
+ 2. For [:lower:] and [:upper:], if ignoring case, set type string
+ to "alpha". This parallels code in the regex routines.
+ 3. Reset wc1 to EOF when parsing bracket expressions.
+
+Mon Nov 29 18:36:25 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect): When allocating a new struct redirect, set
+ rp->pid to -1, not 0, so that code checking for EOF on an
+ input pipe works correctly.
+
+Thu Nov 25 14:22:41 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * Makefile.am (MAINTAINERCLEANFILES): Add.
+ * version.in (version_string): Use PACKAGE_STRING.
+
+Tue Nov 23 17:27:38 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * re.c: Fix a typo in a comment.
+
+Mon Nov 22 16:47:00 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yylex): Add lint check for tawk style modifiers on
+ regexes, /.../i and /.../s. Not that it'll help anyone.
+
+Wed Oct 27 14:25:18 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * builtin.c (do_tolower, do_toupper): Fix the wide char handling,
+ especially when the lowercased char doesn't ocuppy the same
+ number of bytes as its uppercase equivalent. Make use of ...
+ (wide_tolower_toupper): ... this new static function.
+
+Mon Oct 25 11:51:14 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (bchunk, bchunk_one, cksize): Change type of `olen'
+ to size_t from long. It is the 21st century now, after all...
+ Thanks to Stepan Kasal.
+
+Mon Oct 11 10:49:09 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yylex): Improve lint warnings for non-decimal constants.
+ * node.c (isnondecimal): Made a little smarter, thanks to Stepan Kasal.
+
+Thu Oct 7 21:59:38 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (dfamust): Redo fix of 22 Sep to match code from
+ current GNU grep.
+
+Sun Oct 3 23:06:00 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (isnondecimal): Made smarter, so that 0xEE does
+ register as non-decimal. Added parameter to indicate use of
+ locale's decimal point and changed declaration and callers.
+
+Tue Sep 28 18:38:17 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (isnondecimal): New function, now smarter.
+ * awk.h (isnondecimal): Changed from macro to function.
+
+Wed Sep 22 11:24:46 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (dfamust): At end, check results of `malloc'.
+ Based on bug report from Sorav Bansal <sbansal@stanford.edu>
+ for grep.
+
+Mon Sep 20 13:18:18 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ New --exec option. Needed for gawk CGI scripts to prevent
+ arbitrary options and/or source getting passed in from the web.
+
+ * main.c (optab): New long option, --exec.
+ (main): Catch it. Like -f but end option processing.
+ (usage): Add it to the usage message.
+
+ Thanks to John DuBois and Don Stokes for their input.
+
+ Unrelated:
+
+ * dfa.c (dfaexec): Disabled caching into buffer that bypasses
+ multibyte initialization, since it can get things wrong. Thanks
+ to Andreas Schwab <schwab@suse.de>.
+
+Mon Sep 20 12:59:42 2004 Andreas Schwab <schwab@suse.de>
+
+ * awkgram.y (nextc): Check for end of lexer buffer before
+ advancing ring buffer index.
+
+Wed Sep 8 09:54:53 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Force LC_NUMERIC locale to "C" before parsing
+ the program, since a variable assignment with -v can leave the
+ locale set incorrectly.
+
+ Thanks to Sirix <sirix@poczta.onet.pl> for reporting the problem.
+
+Wed Aug 25 18:55:30 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (UPDATE_YEAR): New constant at top of file, where we
+ won't miss it.
+ (copyleft): Use it.
+
+Sun Aug 22 17:26:39 2004 Stepan Kasal <kasal@ucw.cz>
+
+ Define gawk_mb_cur_max even if there is no mbs support, as
+ ``const int'' and assign 1 to it.
+ This fixes a bug in re.c where #ifdef MBS_SUPPORT was missing.
+
+ * awk.h (gawk_mb_cur_max): Declare.
+ * main.c (gawk_mb_cur_max): Define.
+ * awkgram.y (nextc_is_1stbyte): Without mbs support, define to 1.
+ * builtin.c (index_multibyte_buffer): Define a dummy function
+ when there is no mbs support.
+ * awkgram.y, builtin.c, re.c: Remove some `#ifdef MBS_SUPPORT'.
+
+Sun Aug 15 22:08:04 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Import current FreeBSD random.c. Make it work for gawk.
+ Needed for cases where long is more than 32 bits.
+
+ * random.c: Imported from FreeBSD. Header includes tweaked.
+ * random.h: Typdef gawk_uint32_t appropriately and #define uint32_t
+ to it.
+ * configure.ac: Add calls to AC_CHECK_SIZEOF for unsigned int
+ and unsigned long.
+
+ Started with
+ http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdlib/random.c
+ Thanks to Andreas Schwab <schwab@suse.de> for the pointer.
+
+Thu Aug 12 13:09:53 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (copyleft): Fix copyright year.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Aug 2 12:17:40 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Fix the hack. Do the sed on `Makefile',
+ not `Makefile.in'. Sigh.
+
+Sun Aug 1 14:48:30 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: MAJOR HACK: At end, remove version.c from Makefile.in
+ variable `CONFIG_CLEAN_FILES' so that `make distclean' doesn't
+ remove version.c.
+
+Mon Jul 19 17:07:27 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.sub: Updated from Savannah CVS.
+
+Fri Jul 16 10:59:07 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (make_regexp): Bracket code using `gawk_mb_cur_max'
+ inside `#ifdef MBS_SUPPORT'.
+
+Thu Jul 15 12:36:25 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (parse_bracket_exp_mb): If doing case folding,
+ include the other case for regular characters inside [...].
+
+ * re.c (make_regexp): Smarten up handling of IGNORECASE,
+ particularly for multibyte character sets. Sigh.
+
+Wed Jul 14 16:25:23 2004 John Haque <mary1john8@earthlink.net>
+
+ * eval.c (interpret): For `Node_K_return', use `copynode'
+ and not `dupnode' for non-PERM, non-TEMP values.
+ (func_call): Don't add TEMP flag to returned value.
+
+ These two fix a problem uncovered by the July 8 change in
+ `assoc_lookup'.
+
+Wed Jul 14 16:14:09 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (node_common): Add check `lexeme >= lexptr_begin',
+ from valgrind run.
+
+Wed Jul 14 16:00:51 2004 John Haque <mary1john8@earthlink.net>
+
+ * io.c (rsrescan): Fix off by one error at end of record.
+
+Thu Jul 8 16:59:51 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * awkgram.y (output_redir): Make sure not to dereference NULL
+ pointer. The bug was triggered by the following code:
+
+ gawk 'BEGIN{print "date" |& getline}'
+
+ No test case created, beacuse of the following:
+ Correct interpretation involves executing "1" or "0" -- as the user
+ may have defined this, we would have to override this in the test
+ script. It's not worth the hassle.
+
+Thu Jul 8 12:59:49 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (load_casetable): Name changed from `load_ignorecase'.
+ * eval.c (load_casetable): Name changed from `load_ignorecase'.
+ Fix all uses.
+
+Thu Jul 8 12:32:13 2004 John Haque <mary1john8@earthlink.net>
+
+ * awkgram.y (get_src_buf): Fix off-by-one error to avoid "does not end
+ in newline" messages.
+ * array.c (assoc_lookup): Small performance hack: for TEMP subs nodes,
+ use its string memory for ahname.
+ * ext.c (get_actual_argument): Minor code cleanup.
+ * builtin.c (do_lshift, do_rshift, do_and, do_or, do_xor, do_compl):
+ fixed to issue "non-numeric argument" lint warnings before using
+ `force_number'.
+
+Mon Jun 21 16:53:35 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ More changes from John Haque to rationalize extension functions.
+
+ * awk.h (get_curfunc_arg_count): Name changed from
+ `get_curfunc_parm_count'.
+ * eval.c (get_curfunc_arg_count): Ditto, body redone to count actual
+ args passed at call time.
+ * ext.c (get_argument): Update range check.
+ (get_actual_argument): Simplify the code.
+
+Mon Jun 14 14:01:16 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Changes from John Haque and ADR to rationalize extension functions.
+
+ * awk.h (check_special, get_curfunc_parm_count, get_actual_argument):
+ new function declarations.
+ (get_scalar_argument, get_array_argument): new macros.
+ * awkgram.y (check_special): new function.
+ (yylex): Use `check_special' to search `tokentab'.
+ (dump_funcs): Always count functions, in order to get dynamic ones.
+ Removed bogus use of `static' on `tab' variable.
+ * eval.c (struct fcall): Change type of `count' to `size_t'.
+ (get_curfunc_parm_count): New function.
+ (push_args): Set `r->rnode' to NULL for local variable.
+ * ext.c (make_builtin): Add sanity checking for presence and
+ name of new function, and that it's not a redefinition.
+ (get_argument): Check that requested arg is within range of actual
+ number of parameters. Also clean up logic for Node_var_new,
+ Node_var_array, Node_array_ref.
+ (get_actual_argument): New function.
+ * profile.c (pp_builtin): Better handling of dynamic extension function.
+
+Sun Jun 13 14:32:22 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect): Conditionalize checking for process recovery
+ on `#ifdef PIPES_SIMULATED'. Needed for MS-DOS and VMS.
+ * builtin.c (tmp_integer): Change bracketing of magic test to
+ `#ifdef HAVE_UINTMAX_T' which is more general and more correct.
+
+Wed Jun 9 21:36:01 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (make_regexp): Add dfa matching into IGNORECASE handling.
+
+Tue Jun 8 15:38:56 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (casetable): Remove `const'.
+ * eval.c (casetable): Remove `const'.
+ (load_ignorecase): New function. Loads locale-correct values in
+ upper 128 bytes.
+ (set_IGNORECASE): Call `load_ignorecase'.
+
+Tue Jun 8 14:04:19 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (get_src_buf): Make sure that value from
+ `optimal_bufsize' is reasonable. Increase it if not.
+
+Tue Jun 8 13:54:28 2004 John E. Haque <mary1john8@earthlink.net>
+
+ * awkgram.y (statement:LEX_FOR): Fix bug in loop to `delete a'
+ optimization.
+ * io.c (format_tree): Check for out of range values for
+ positional specifiers.
+
+Mon Jun 7 17:02:48 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (tmp_integer): Bracket the magic test inside
+ `#ifndef VMS'.
+
+ * awk.h (child_catcher): Remove declaration.
+ * main.c (main): Remove `signal' calls for SIGCLD, SIGCHLD.
+ * io.c (child_died, child_signo, child_catcher): Removed.
+ (get_a_record): Remove code checking for death of child.
+ (redirect): If `rp' matches and is at EOF and type is input
+ pipe, and `rp->pid' is not -1, call `wait_any' to reap the
+ child. This is a heuristic, but it works pretty well.
+
+Sun Jun 6 18:35:17 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Restore use of `memmove' instead of
+ memcpy. Otherwise some tests break on some systems. We think.
+ (child_died): Don't reset signal handler; breaks on some S5 systems.
+ (get_a_record): Reset handler if child_died. Still flaky on Solaris.
+ * configure.ac (version.c): Made from version.in again, for
+ non-Unix systems.
+ * Makefile.am (base_sources): Add version.c back.
+ * version.in: Include config.h for definition of const.
+ * main.c (version_string): Add back declaration, don't
+ include "version.i".
+ (main): Don't install child_catcher on Sun. (HACK)
+
+Thu Jun 3 14:06:06 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (version_string): Removed declaration, since
+ version.i is included directly.
+ * version.in: Removed test for definition of const.
+
+Tue Jun 1 19:23:53 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * Makefile.am (base_sources): Don't mention version.c, so that
+ it doesn't get distributed.
+ * po/POTFILES.in: remove version.c
+ * configure.ac: Create version.i from version.in.
+ * main.c: include version.i.
+
+Tue Jun 1 18:33:32 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix problem reported by Stephen Marchant <Stephen.Marchant@Cognex.com>
+ on Thu, 30 Oct 2003 13:11:42 -0500.
+
+ * regex_internal.h (re_realloc): Allow for SunOS pre-Standard C
+ `realloc' which doesn't accept NULL pointers.
+ * awk.h (erealloc): Same.
+
+ Unrelated. Change suggested by Peter Sobisch <petersob@gmx.net>, have
+ PROCINFO["version"] be the version of gawk:
+
+ * main.c (load_procinfo): Add in version.
+
+ Unrelated: Avoid warning:
+
+ * main.c (main): Cast calls to `bindtextdomain' and `textdomain' to
+ void. Avoids diagnostic with `configure --disable-nls'.
+ * dfa.c (check_matching_with_multibyte_ops): Remove unneeded nested
+ #ifdef, per Scott Deifik (scottd@amgen.com). Also fix some spelling
+ errors in comments.
+
+Tue Jun 1 18:26:45 2004 Paul Eggert <eggert@twinsun.com>
+
+ Fix a bug reported by Mike Romaniw <msr@micromonumental.com>
+ to bug-gnu-utils on 2003-09-27: compl(compl(0xf0f)) returned 0xfff
+ on hosts with 64-bit uintmax_t and 64-bit IEEE-764 double, due to
+ rounding errors.
+
+ * doc/gawk.texi (Bitwise Functions): Leading nonzero bits are
+ removed in order to fit the result into a C 'double' without rounding
+ error.
+ * builtin.c: Include <float.h> if available.
+ (FLT_RADIX, FLT_MANT_DIG, DBL_MANT_DIG): Define if not already defined.
+ (AWKSMALL_MANT_DIG, AWKNUM_MANT_DIG, AWKNUM_FRACTION_BITS): New macros.
+ (tmp_integer): New function.
+ (do_lshift, do_rshift, do_and, do_or, do_xor, do_compl): Use them.
+
+Tue Jun 1 17:40:47 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * eval.c (push_args): Set var_value to Nnull_string for
+ local variables.
+
+Mon May 31 11:49:20 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * replace.c: #undef DEBUG before including mktime.c, it has
+ different meaning there.
+
+Mon May 31 08:25:30 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (get_actual): Add extra error message for `delete f'
+ inside body of function `f'.
+
+Mon May 3 09:53:34 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in, */Makefile.in: Updated to automake 1.8.4.
+ * config.guess, config.sub: Same.
+ * aclocal.m4, depcomp, install-sh: Same.
+
+Mon May 3 09:24:45 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Look for missing `strtoul'.
+ * replace.c: Include missing_d/stroul.c if not HAVE_STRTOUL.
+ * io.c (devopen): Use `strtoul' instead of `strtod' for
+ extracting fd number from "/dev/fd/N". (Thanks to Jim Meyering.)
+ * field.c (set_FIELDWIDTHS): Use `strtoul' instead of `strtod'
+ when parsing FIELDWIDTHS values. (Thanks to Jim Meyering.)
+
+Mon Apr 19 20:12:57 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in, */Makefile.in: Updated to automake 1.8.3.
+ * config.guess, config.sub: Same.
+
+2004-03-18 Stepan Kasal <kasal@ucw.cz>
+
+ * eval.c (make_scalar): Comment clarification.
+
+ * array.c (get_actual): Remove the condition ``canfatal''
+ before ``cant_happen()''; if the data are consistent, we
+ simply cannot get there with a non-func Node_param_list,
+ no matter whether we are called via get_array or not.
+
+ * awkgram.y (variable): Make one longer message, to help translators.
+
+Tue Mar 9 17:34:10 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Adapted `gofast' patch from Redhat Enterprise version of grep
+ to current dfa.c.
+
+ * dfa.c (buf_offset): New variable.
+ (SKIP_REMAINS_MB_IF_INITIAL_STATE): Modified to use it, don't
+ free `mblen_buf', `inputwcs'.
+ (match_anychar, match_mb_charset, transit_state_consume_1char,
+ transit_state): Use buf_offset in mblen_buf.
+ (dfaexec): Realloc things instead of free and malloc.
+
+Thu Mar 4 16:46:55 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AC_FUNC_MBRTOWC): Added.
+ (AC_CHECK_FUNCS): Removed `mbrtwoc'.
+ (REGEX_MALLOC): Removed. Not needed for new regex* routines.
+
+ * re.c (research): Removed comment and check for return of -2
+ since that was for old regex using alloca or REGEX_MALLOC.
+
+Wed Mar 3 17:10:16 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (close_one): Don't close stdout or stderr; can happen if
+ /dev/stdout or /dev/stderr are used in redirection and all the
+ open files get used.
+
+Sun Feb 29 12:17:37 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (build_charclass, build_charclass_op): Change type of
+ `class_name' parameter to `const char *' from `const unsigned char *'
+ and adjust callers.
+
+Thu Feb 26 15:20:22 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (get_src_buf): Rewritten to better manage input and
+ supplying newlines on command line programs. Fixes problems reading
+ source files on Cygwin.
+
+ Unrelated fixes from mary1john8@earthlink.net:
+
+ * node.c (format_val): For no malloc case, free s->stptr if necessary.
+ * io.c (nextfile): Add missing call to `unref(FILENAME_node->var_value)'
+ for no files case.
+ (close_redir): Remove file from redirection list even if fp is
+ stdout or stderr.
+
+Tue Feb 24 12:11:34 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.c (build_wcs_upper_buffer): Enclose `offsets_needed'
+ label in `#ifdef _LIBC' to silence `unused label' compiler warning.
+
+Tue Feb 24 11:57:18 2004 Nelson H.F. Beebe <beebe@math.utah.edu>
+
+ * regcomp.c (parse_expression): Add cast to (unsigned char *) in calls
+ to `build_charclass_op'.
+ * regex_internal.c (build_wcs_buffer): Add cast to char* in call to
+ `wcrtomb'.
+ * regex_internal.h (bitset_not, bitset_merge, bitset_not_merge,
+ bitset_mask, re_string_char_size_a, re_string_wchar_at,
+ re_string_elem_size_at): Change to use prototypes.
+ (re_string_char_size_at, re_string_wchar_at, re_string_elem_size_at):
+ Declare as `internal_function'.
+
+ * Makefile.am: Add rule to make .i files. This assists in debugging.
+ * awk.h (m_tree_eval): Add casts to NULL. (Some compilers are just
+ dumb. ADR)
+
+Mon Feb 23 15:58:39 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Clean up occupied process slots of children that have died:
+
+ * awk.h (child_catcher): New function, declare it.
+ * main.c (main): Catch SIGCHLD/SIGCLD with `child_catcher'.
+ * io.c (child_died): New static variable.
+ (child_catcher): New function, sets `child_died', reinstalls self
+ as signal handler.
+ (close_rp): New function: isolates actual fp/iop closing logic.
+ (close_redir): Call `close_rp'.
+ (get_a_record): Check `child_died' and call `wait_any(0)' if so.
+ Add descriptive comment.
+
+ Unrelated clean up:
+
+ * eval.c (fcalls): Renamed from `fcall_list'. All uses changed.
+ (pop_fcall, push_args, dump_fcall_stack): Adjusted to use indexing
+ on `fcalls' instead of a pointer into it. Avoids hassles if `fcalls'
+ is realloc-ed during recursive tree_evals. Thanks to BWK.
+
+ * config.guess, config.sub: Updated from Savannah.
+
+2004-02-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1.
+
+Wed Feb 18 12:40:09 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (rule): Use `msg' not `warning' for `must have an
+ an action part' message. `warning' is wrong, since it's a real error.
+
+Mon Feb 16 12:17:39 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c, eval.c, builtin.c: Change test for `#ifdef HAVE_LOCALE_H'
+ to `#if ENABLE_NLS && defined(HAVE_LOCALE_H)' so that builds with
+ `configure --disable-nls' will actually work on non-glibc systems.
+
+Thu Feb 12 02:05:34 2004 Stepan Kasal <kasal@ucw.cz>
+
+ Lots of misc changes from Stepan Kasal integrated.
+
+ * array.c: Various variables and parameters of static functions
+ changed from int to long, in order to prevent overflow.
+
+ * eval.c (make_scalar): New function; takes care of everything
+ that has to be done when a node of type Node_var_new or
+ Node_array_ref changes to a scalar variable.
+ (tree_eval, get_lhs): Call it.
+ (tree_eval): From now on, tree_eval(NULL) doesn't work;
+ it reports an internal error.
+ * awk.h (m_tree_eval): Likewise for the two macro versions.
+ * awkgram.y (statement): Make sure the Node_K_return's lnode is
+ always the return value, never NULL.
+
+ * Makefile.am (install-exec-hook, uninstall-links): Make use of
+ $(VERSION).
+ (INCLUDES): Renamed to AM_CPPFLAGS.
+ (AM_CPPFLAGS): The file libintl.h is generated in the
+ build subdirectory intl, not in the directory $(srcdir)/intl.
+ (diffout): New target is an alias for ``make -C test diffout.''
+ * awklib/Makefile.am (INCLUDES): Renamed to AM_CPPFLAGS.
+
+ * README_d/README.hpux: Change the whitespace in the appended patch,
+ so that it applies to the current source.
+ * posix/gawkmisc.c: Change a tab to a space (needed for the above).
+
+ Make version control more in the style of current autotools:
+
+ * configure.ac: Remove obsolete versions of macros:
+ AM_INIT_AUTOMAKE doesn't need any parameters.
+ AC_OUTPUT shouldn't have any parameters either.
+ Its parameters go to a new macro: AC_CONFIG_FILES.
+ AC_CONFIG_HEADERS moved near the end of the file.
+ * configure.ac: Add [version.c:version.in] to AC_CONFIG_FILES
+ * version.in: Modify for autoconf substitutions.
+ * version.c: Remove, it's generated at configure time now.
+ * fixvers, patchlev.h, unsupported/tandem/ptchlvl.h: Nuke and ...
+ * Makefile.am, main.c: ... forget them.
+
+Mon Feb 9 12:57:00 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h builtin.c eval.c field.c (HUGE): Changed to `UNLIMITED'.
+ Avoids possible conflict with constant in svid-mode math.h. Thanks to
+ Roman.Putanowicz@iecn.u-nancy.fr for pointing out the problem.
+
+Fri Feb 6 12:09:55 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Check for `wctype', `wcscoll' and `iswctype'.
+ * mbsupport.h: New file. Merges and centralizes testing for MBS support.
+ * Makefile.am (base_sources): Add mbsupport.h to list.
+ * dfa.c, dfa.h, awk.h (MBS_SUPPORT): Include "mbsupport.h" and use the
+ test there.
+ * regex_internal (RE_ENABLE_I18N): Same.
+
+ * Makefile.am (CLEANFILES): Added.
+
+Thu Feb 5 18:05:12 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (HAVE_WCTYPE_T): New test code added.
+ * dfa.h (wctype_t): Define if system doesn't. Needed here too
+ for other files that include dfa.h.
+ * dfa.c (wctype_t): Define if system doesn't.
+ (lex): Manually fill in arrays used for char class range testing
+ so will work on c89 and older compilers.
+ (parse_bracket_exp_mb): Split up an assignment to avoid type complaints.
+
+ * main.c (main): When checking for `close_io' failure, only set
+ `exit_val' to 1 if not already exiting.
+
+ * regcomp.c (regerror): Remove use of mempcpy. Generates too
+ many compiler warnings.
+ * configure.ac (AC_CHECK_FUNCS): Don't bother checking for it.
+
+Wed Feb 4 17:34:47 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.h (__THROW): Only define it if C++. The __GNU_PREREQ
+ macro is a major headache.
+
+2004-02-02 Paolo Bonzini <bonzini@gnu.org>
+
+ * regexec.c (check_matching): Add P_MATCH_FIRST parameter.
+ (re_search_internal): Pass new parameter to check_matching.
+ (check_matching): Unless a parenthesized group is found at the
+ beginning of the regexp, advance P_MATCH_FIRST until we entered
+ a state different from the initial state.
+
+Mon Feb 2 15:52:37 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (research): Change last param to re_search to pass
+ NULL if `need_start' is false. May give us a marginal speed gain.
+
+Thu Jan 29 17:04:51 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (sub_common): Fix logic for `&' in replacement for
+ multibyte case. Simplify code a bit.
+
+Tue Jan 20 10:41:45 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add check for `memmove'.
+ * replace.c: Include missing_d/memmove.c if don't have `memmove'.
+
+Sun Jan 18 12:01:29 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (sub_common): Add comment and support for 2001 POSIX
+ behavior when --posix in effect. The masses have been
+ clamoring for this one.
+
+2004-01-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.13.1.
+ * intl/*: Updated to 0.13.1.
+
+Fri Jan 16 08:16:38 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.h, getopt.c, getopt1.c: Synced to GLIBC version:
+ getopt.c: 1.51
+ getopt.h: 1.18
+ getopt1.c: 1.9
+
+Thu Jan 15 15:28:48 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ Here we go again:
+
+ * regcomp.c, regex.h, regex.c, regex_internal.h, regex_internal.c,
+ regexec.c: Sync to GLIBC version, but with bug fixes. GLIBC
+ CVS versions:
+
+ regcomp.c: 1.76
+ regexec.c: 1.55
+ regex.c: 1.125
+ regex.h: 1.30
+ regex_internal.c: 1.39
+ regex_internal.h: 1.45
+ regexec.c: 1.55
+
+ * acinclude.m4: Removed, not needed for automake 1.8.x.
+ * configure.ac: Updated to autoconf 2.59.
+
+ Everything else updated to automake 1.8x and autoconf 2.59.
+
+Wed Jan 14 14:26:36 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c, dfa.h: Updated manually with most of the changes in
+ grep 2.5.1. That version lost the ability to match newlines
+ in the data, so the merge had to be done by hand. Sigh.
+
+2004-01-12 Paolo Bonzini <bonzini@gnu.org>
+
+ ALLOCA patch from
+ http://sources.redhat.com/ml/libc-alpha/2004-01/msg00099.html
+ added.
+
+ * regcomp.c [_LIBC && !RE_ENABLE_I18N]:
+ Drop code to support this, it is never true.
+ (build_range_exp) [!_LIBC]: Do not create a range
+ in MBCSET for a single-byte character set.
+ (build_range_exp) [_LIBC]: Do not create a range
+ in MBCSET for a single-byte character set without
+ collation elements.
+ (init_dfa): Do not conditionalize on _LIBC, it
+ just makes the code less clear.
+ (parse_bracket_exp): Use NON_MATCH variable in
+ addition to "mbcset->non_match", not as an
+ alternative.
+ (build_charclass_op): rename NOT parameter to
+ NON_MATCH, use it instead of declaring a variable.
+ (parse_bracket_exp) [!_LIBC]: Pass NULL for MBCSET
+ if the character set is single-byte.
+
+Wed Jan 7 15:23:04 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (mk_rexp): Set n->re_cnt to 1. Makes reinstated
+ dfa code actually take effect! Don't know how I missed this.
+
+ Unrelated: sync regex code to glibc.
+
+ * regcomp.c, regex.h, regex.c, regex_internal.h, regex_internal.c,
+ regexec.c: Sync to GLIBC version, but with bug fixes. GLIBC
+ CVS versions:
+
+ regcomp.c: 1.74
+ regex.c: 1.124
+ regex.h: 1.30
+ regex_internal.c: 1.39
+ regex_internal.h: 1.43
+ regexec.c: 1.55
+
+ * regcomp.c (peek_token): Temporarily, we hope, disable \s and \S
+ operators. Too much trouble to document right now.
+ * dfa.c (lex): Add code for \s and \S but disable it until
+ next release.
+
+Wed Dec 24 15:28:57 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_tree_eval): For Node_assign_concat, add
+ call `free_temp(r)'. Thanks to mary1john8@earthlink.net.
+
+Mon Dec 1 10:25:52 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ CONSTVAL not needed if we test PERM instead. Thanks to
+ mary1john8@earthlink.net. See test/concat3.awk.
+
+ * awk.h [CONSTVAL]: Removed.
+ * eval.c (flag2str): Removed CONSTVAL from table.
+ (r_tree_eval): For Node_assign_concat, it's enough to check
+ if l->flags has PERM clear.
+ * awkgram.y (yylex): Removed use of CONSTVAL for YSTRING and YNUMBER.
+
+Mon Nov 3 16:33:26 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (get_src_buf): Replace `memmove' with `memcpy' for
+ marginal portability gain to older systems.
+ * io.c (get_a_record): Ditto.
+
+Sun Nov 2 15:59:27 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [CONSTVAL]: Renamed from `STRCONST'.
+ * eval.c (flags2str): Fix in table.
+ (r_tree_eval): For Node_assign_concat, check for the flag for
+ both left and right hand sides. Also add a `force_string' call
+ for the right hand side and the left hand side.
+ * awkgram.y (yylex): Change flag value for YSTRING and add use
+ of flag for YNUMBER.
+
+Wed Oct 29 14:23:29 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [STRCONST]: New flag value.
+ * eval.c (flags2str): Add it to table.
+ (r_tree_eval): For Node_assign_concat, check for the flag so that
+ we don't clobber string constants given:
+ s = ""
+ s = s something
+ * awkgram.y (yylex): For YSTRING, set STRCONST flag.
+
+Tue Oct 28 18:00:00 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Force SUBSEP to always have a string value. Per bug report
+ from mary1john8@earthlink.net.
+
+ * awk.h (NODETYPE): New type, Node_SUBSEP.
+ (set_SUBSEP): Add declaration.
+ * awkgram.y (isnoeffect, isassignable): Add Node_SUBSPEP case.
+ * array.c (set_SUBSEP): New function.
+ * eval.c (nodetypes): Add Node_SUBSEP.
+ (r_tree_eval, r_get_lhs): Add code for Node_SUBSEP.
+ * main.c (varinit): Use Node_SUBSEP as type for SUBSEP.
+ * profile.c (tree_eval, pp_lhs, is_scalar, prec_level): Handle
+ Node_SUBSEP.
+
+Tue Oct 7 09:26:33 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (NODETYPE): New member `Node_assign_concat'.
+ * awkgram.y (exp): Look for case of `x = x y' and if so, create a
+ Node_assign_concat.
+ * eval.c (interpret): Add case for Node_assign_concat.
+ * profile.c (prec_level): Ditto.
+ (tree_eval): Ditto. For variables, call new function `vname' to
+ print name; handles varname field for -v variables, which end up
+ including the value.
+ (vname): New function.
+
+Wed Sep 24 17:32:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Speed up `avoid_dfa' kludge, at least a little:
+
+ * awk.h (struct Regexp): Add `has_anchor' member. Make it and
+ `dfa' member shorts; keeps space the same.
+ * re.c (make_regexp): Set `has_anchor' member correctly.
+ (avoid_dfa): Test for `has_anchor' member instead of searching
+ for it each time.
+
+Sun Sep 21 18:34:32 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (state): Only needs to be 256 bytes, initstate() can't
+ use any more than that. Well whadayaknow.
+ (do_rand, do_srand): Call `setstate' after calling `initstate'.
+
+Tue Sep 16 15:44:29 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (interpret): For Node_K_switch, add kludge_need_start stuff
+ as used in `match_op'. Sigh.
+ * re.c (make_regexp): Add `no_dfa' variable, which is true if
+ GAWK_NO_DFA exists in the environment. This enables run time
+ testing of things with/without the dfa matcher.
+
+Mon Sep 15 18:36:38 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ After much soul searching, reinstated old dfa code. The performance
+ of the new regex is just disastrous. Sigh.
+
+ * awk.h (re_cnt): Reinstated old definition.
+ (struct Regexp): Added `dfareg' and `dfa' members.
+ (make_regexp): New last parameter in function, changed decl.
+ (avoid_dfa): Added declaration.
+ * awkgram.y (regexp, mk_rexp): Added use of `re_cnt'. Fixed call
+ to `make_regexp'.
+ * Makefile.am: Add dfa.h and dfa.c.
+ * eval.c (match_op): Complexified: added call to `avoid_dfa' and
+ `kludge_need_start' variable where used to pass FALSE as last parameter
+ of research().
+ * field.c (set_FS): Fixed call to `make_regexp'.
+ * io.c (get_a_record, set_RS): Fixed calls to `make_regexp'.
+ * re.c (make_regexp): Added last paramter (`dfa') to function.
+ Complexified the code.
+ (re_update): Fixed call to `make_regexp'.
+ (research): Complexified the code, added calls to dfa stuff.
+ (dfaerror): New function.
+ (re_update): Fixed call to `make_regexp'.
+ (avoid_dfa): New function.
+
+Tue Sep 9 15:57:38 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (get_src_buf): Fix calculation of `offset' when shifting
+ source lines around. In general, improve handling of things when
+ moving the source code line around. What a mess this code is.
+
+Mon Sep 8 19:08:55 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (fmt_ok): Make provision for %F format and printf %'f flag
+ here too.
+
+2003-07-23 Christophe Bisiere <bisiere@univ-tlse1.fr> (tiny change)
+
+ * posix/regex.h (RE_TRANSLATE_TYPE): Define it to "unsigned char,"
+ to avoid problems at hosts with signed char.
+ * posix/regexec.c (re_search_internal): Don't say
+ "unsigned RE_TRANSLATE_TYPE."
+
+Thu Aug 28 11:09:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (nextfile): Change use of variable `files' to make it
+ clearer that it's a boolean flag.
+
+Tue Aug 26 22:58:15 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (useropen): Add `defined (HAVE_GETGROUPS)' as first test
+ in `#ifdef'. Brings things in sync with same test in main.c and awk.h.
+
+Tue Aug 26 22:49:37 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dbug.h: New file.
+
+ * array.c, awkgram.y, builtin.c, eval.c, ext.c, field.c, io.c,
+ main.c, msg.c, node.c, profile.c, re.c: Converted to use
+ Fred Fish's `dbug' library. By default compiled out, thus
+ not affecting speed.
+
+ For the nonce, the `dbug' library itself is not shipped with
+ gawk, since I expect no-one else but me to be using it.
+
+Thu Aug 21 23:15:36 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (numfiles): Change extern decl to long, to match what's
+ in main.c. Keeps things working on 64-bit systems. Thanks to bug
+ report from Jan Oravec <jan.oravec@6com.sk>.
+
+Wed Aug 20 14:53:47 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (genflags2str): Move test for out-of-space inside test
+ for is the bit set.
+
+Mon Aug 11 11:26:51 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (parse_bracket_exp): If `build_charclass' fails, just pass
+ its value on as the return value.
+
+Sun Aug 10 16:59:14 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (build_range_exp): Make sure we don't
+ get WEOF on range characters.
+
+Tue Aug 5 21:49:32 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (get_actual): In `case Node_param_list' add test for
+ `&& (symbol->flags & FUNC) == 0' to the if.
+
+Sun Jul 13 18:28:38 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Further bug fix:
+
+ * awkgram.y (variable): Give the new variable an lnode
+ of Nnull_string if it's not an array, even if it is
+ a Node_var_new.
+
+Fri Jul 11 09:32:21 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Bug fix:
+
+ * eval.c (r_tree_eval): For Node_array_ref, set
+ tree->orig_array->var_value to Nnull_string too.
+
+ Unrelated i18n and POSIX change:
+
+ * configure.ac: Add check for local printf supporting %F format.
+ * awk.h (loc): New variable declaration.
+ * main.c (loc): Defined.
+ (main): Call `localeconv' to set loc.
+ * io.c (format_tree): Add support for printf quote flag, %'d for
+ decimal formats (not %e, %E), adds thousand separator into value.
+
+2003-07-10 Paul Eggert <eggert@twinsun.com>
+
+ * io.c (two_way_open): If /bin/sh cannot be executed, exit
+ with status 126 consistently.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Mon Jul 7 09:55:49 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (copyleft, usage): Make sure to fflush output fp. Per Jim
+ Meyering, if error, exit non-zero.
+ * ext.c (get_argument): Fix array paramater handling.
+
+2003-07-06 Paul Eggert <eggert@twinsun.com>
+
+ * builtin.c (do_substr): Issue better diagnostics when
+ d_substr and d_length are NaN, or when 0 < d_length < 1.
+ Be careful when comparing double to SIZE_MAX, as
+ the comparison might return the "wrong" answer when
+ `(double) SIZE_MAX' is a number that is not equal to
+ SIZE_MAX.
+ (do_gensub): Watch out for HOW values that are out of range
+ or are NaN.
+ (do_dcngettext): dcngettext wants an argument of type
+ unsigned long, not long, so use a value of that type.
+
+Fri Jul 4 10:58:02 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Make option letter 'D' fall through into default
+ unknown case if not debugging. Let's us have just one version of
+ `optlist'.
+
+Thu Jun 26 15:25:57 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (get_actual): Undo Stepan Kasal change of 2003-06-17.
+ See test/match2.awk.
+
+Wed Jun 25 15:26:08 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_rand): Change calculation so that result
+ obeys constraint: 0 <= N < 1. This is per history and POSIX.
+ Thanks to Nelson Beebe (beebe@math.utah.edu) for reporting
+ this issue.
+
+Mon Jun 23 15:13:39 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (rs1scan): Per advice from Bruno Haible, it's safe
+ to skip the multibyte checking code if RS is '\n'. See
+ the comment in the code. Big performance improvement for
+ multibyte locales.
+
+2003-06-20 Stepan Kasal <kasal@ucw.cz>
+
+ * eval.c (comp_func): if memcmp returns 0, we have to compare
+ the lengths.
+
+2003-06-19 Stepan Kasal <kasal@ucw.cz>
+
+ * eval.c (interpret) <Node_K_arrayfor>: use NULL, not 0, to
+ initialize the variable list.
+ (comp_func): array indices no longer are string values,
+ you have to use ahname_str, ahname_len.
+
+Tue Jun 17 11:53:46 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (get_actual): Make check for isparam
+ smarter: also check for FUNC flag.
+
+2003-06-17 Stepan Kasal <kasal@ucw.cz>
+
+ * array.c (get_actual): even if canfatal is FALSE, don't
+ tolerate existence of things which can't happen.
+
+Mon Jun 16 16:21:44 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Removed m4/Makefile.
+ * m4/Makefile.am: Removed.
+
+2003-06-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * configure.ac (AC_OUTPUT): Add m4/Makefile.
+ (AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
+
+Sun Jun 15 20:45:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Enhance logic to fill buffers to include
+ `|| no_data_left(iop)'.
+ (rs1scan): Fix logic for setting recm fields for multibyte
+ character case.
+
+2003-06-10 Stepan Kasal <kasal@ucw.cz>
+
+ * awkgram.y (release_all_vars): do not try to release a value of
+ Node_var_new; after get_lhs, use the lhs directly, do not try
+ to do (*lhs)->var_value; the Node_var case doesn't need
+ special treatment.
+ * builtin.c (do_match): `get_param' is successful iff it returns
+ Node_var_array---if the variable was new, get_param has already
+ changed the type.
+ * field.c (do_split): likewise.
+
+Sun Jun 15 19:36:35 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (r_dupnode): Typo fix in hash tables: stptr -> ahname_str.
+ Thanks to mary1john8@earthlink.net.
+ * array.c (get_actual): Add `if (canfatal)' before call to
+ `cant_happen'.
+
+Sun Jun 15 19:25:49 2003 Patrick T.J. McPhee <ptjm@interlog.com>
+
+ * awk.h (memcpy_ulong): Add ! WIN32 to ifdefs.
+
+Mon Jun 9 18:38:20 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h (hpux): Added stuff to (hopefully) get `tzset'
+ declared on HP/UX 10 and up.
+
+Mon Jun 9 17:12:24 2003 Patrick T.J. McPhee <ptjm@interlog.com>
+
+ * awk.h (ATTRIBUTE_EXPORTED): New macro for dynamic libs on Windows32.
+ * CONVMFTidx, stack_ptr, do_lint, lintfunc: Now have this attribute.
+
+Mon Jun 9 13:11:33 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Clean up of Stepan's patches.
+
+ * array.c (get_actual): Renamed from r_get_array. Added second
+ param canfatal if routine should print fatal message when not an array.
+ (get_actual): Renamed 'prm' to `isparam'.
+ (array_vname): Add static msglen var; only realloc string if it grows.
+ Don't use `s += sprintf(...)'. No good on old systems where sprintf
+ returns char *. Minor formatting cleanups.
+ (do_adump): Restored separate `a' and `r' variables; helps for debugging.
+
+ * awk.h (SCALAR, UNINITIALIZED): Removed entirely, renumbered other flags.
+ (get_array, get_param): New macros, calls get_actual.
+ (get_actual): Declaration changed from that of r_get_array.
+
+ * awkgram.y (release_all_vars): Restored previous version of code; new
+ version isn't right for Node_xx variables.
+ (variable): Minor code cleanup for readability.
+
+ * builtin.c (do_match): Use get_param and print our own message when
+ third parameter is not an array.
+
+ * eval.c: Added a few comments here and there, removed some no longer
+ needed comments.
+
+ * field.c (do_split): Use get_param and print our own message when
+ second parameter is not an array.
+
+Mon Jun 9 11:46:21 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (do_delete): Initialize hash1 and last to keep gcc -Wall happy.
+ * io.c (rsnullscan): Comment out label skip_leading for same reason.
+
+Wed May 28 08:31:23 CEST 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * eval.c (forloops_active, in_function): Nuked.
+ (pop_all_forloops, pop_fcall_stack): are now inline.
+
+Wed May 28 07:58:35 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * field.c, awk.h (Null_field): no longer static.
+ * field.c (init_fields): initial value of $0 can be Nnull_string,
+ no need to copy it.
+ * eval.c (r_get_lhs) <Node_field_spec>: test for uninitialized field,
+ which is Nnull_string for $0 and Null_field for $(>0).
+ * builtin.c (do_print_rec): test for uninitialized $0.
+
+Tue May 27 17:03:02 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * awk.h (Node_var_new): New node type for variables which can be
+ either scalar or array. From now on, Node_var is always scalar.
+ (Node_gvar_ref): Nuked, its role can be taken by Node_array_ref.
+ (orig_var): removed, orig_array is enough.
+ (SCALAR, UNINITIALIZED): Flags nuked.
+ (var_uninitialized): new macro to distinguish uninitialized vars;
+ used in several other macros.
+ * array.c (r_get_array, array_vname, do_adump): adapt to the
+ above changes.
+ * awkgram.y, eval.c, field.c, main.c, node.c, profile.c: ditto.
+
+Tue May 27 14:27:50 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * array.c (r_get_array): New function, which goes all the way
+ through Node_param_list to actual Node_var_array; if it encounters
+ non scalar Node_var, it changes it to Node_var_array.
+ (in_array, do_delete, do_delete_loop, do_adump, assoc_sort_inplace):
+ Use get_array.
+ (assoc_lookup): The parameter must be a Node_var_array.
+ * awk.h (get_array, r_get_array): Declare the new function and define
+ a macro to speed it up.
+ * builtin.c (do_match): Use get_array.
+ * eval.c (interpret) <Node_K_arrayfor>: ditto.
+ (r_get_lhs) <Node_K_arrayfor>: ditto.
+ * field.c (do_split): ditto.
+
+Tue May 27 08:23:51 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ Changed node->vname meaning for type Node_array_ref and Node_gvar_ref.
+ It contains only the reference name; one has to (recursively) follow
+ node->prev_array to find out the call history for the array.
+
+ * array.c (array_vname): New function to print the array name.
+ (assoc_lookup, do_delete): Use array_vname.
+ * eval.c (interpret, r_tree_eval, r_get_lhs): Use array_vname.
+ (push_args, pop_fcall): Things have simplified.
+ * awk.h (array_vname): Declare.
+ (prev_array): Define.
+
+Sun Jun 8 11:25:36 2003 Stepan Kasal <kasal@ucw.cz>
+
+ * awkgram.y (append_right): when using savetail, remember that it
+ is not necessarily the tail of the list---it's just a pointer to
+ the last chunk appended.
+
+Thu Jun 5 12:01:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_strtonum): Make `strtonum(13)' work.
+
+Wed Jun 4 17:07:06 2003 Corinna Vinschen <vinschen@redhat.com>
+
+ * io.c (binmode): Include function for __CYGWIN__ too.
+
+Tue Jun 3 12:40:50 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (interpret): Node_K_switch. For regex case, don't
+ call `free_temp' on the result of `force_string' if it's equal to
+ switch_value. Thanks to John DuBois <spcecdt@armory.com>
+ for finding the problem.
+
+Sun Jun 1 13:08:22 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): For %c, force precision to 1.
+
+Wed May 28 11:55:48 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (isnoeffect, isassignable): Add Node_TEXTDOMAIN to
+ switches in both functions.
+
+Wed May 28 11:38:59 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * awkgram.y (switch_body): remove rule ``switch_body:/*empty/''
+ as ``switch_body:case_statements'' covers it---this disambiguation
+ fixes a reduce/reduce conflict.
+
+Sun May 25 16:23:43 2003 Corinna Vinschen <vinschen@redhat.com>
+
+ * configure.ac: Remove linking against /usr/lib/automode.o.
+ * configure: Regenerate.
+
+Sun May 25 15:19:19 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * awk.h (get_lhs): For an initialized Node_var, you may return
+ the address of var_value pointer, no matter whether reference
+ bit was set or not. We were silly slowing down most of the
+ assignements.
+
+ * (get_a_record): after grow_iop_buffer, move recm.rt_start even
+ if recm.len == 0.
+
+Mon May 19 16:55:59 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Code for C-style switch statements. Initial version contributed by
+ Michael Benzinger <Michael.Benzinger@sabre-holdings.com>.
+
+ Disabled by default, use `configure --enable-switch' to turn it on.
+
+ * configure.ac: New AC_ARG_ENABLE for switch statements.
+ * awk.h (NODETYPE): New types for switch, case, default keywords
+ and respective lists.
+ * awkgram.y: New productions for switch statement. Does checking to
+ avoid duplicate cases.
+ * eval.c (nodetypes): New entries for new NODETYPEs.
+ (interpret): New code to do switch execution.
+ * profile.c (pprint): New code to print switch statements.
+
+Mon May 19 15:05:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Renamed from configure.in.
+ * fixvers: Now looks in configure.ac.
+ * Makefile.am: Now cites configure.ac.
+
+ * Misc other: Updated to Automake 1.7.5.
+
+Sun May 18 12:03:56 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (do_delete_loop): Fix bracing of logic for
+ tests.
+
+Wed May 14 09:01:16 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ Misc patches:
+
+ * builtin.c (do_match): if third parameter to `match' is supplied,
+ store all subexpressions which are applicable, even though there
+ are some unused between them.
+
+ * awkgram.y (yylex): when returning from unterminated REGEXP
+ (which is /* kludge */), take care to fake a yylval, to
+ prevent ``internal error'' later.
+
+Sun May 11 15:51:00 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * io.c (rsnullscan, get_a_record): Boundary condition bug fixes.
+
+Sun May 11 15:15:20 IDT 2003 Scott Deifik <scottd@amgen.com>
+
+ * awk.h: Add decls for `memcpy_ulong', `memset_ulong', and
+ MSC defines.
+ * regex.c: Include <stdio.h> if MSC for size_t.
+
+Mon May 5 15:11:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Only tweak RT's value in place if the current
+ RS scanner is the same as the last one. Bug report submitted by
+ John DuBois (<spcecdt@armory.com>).
+
+Fri May 2 14:39:48 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Add logic at end to be smart about setting
+ RT. Saves considerable time, esp for default case where RS = "\n".
+
+Wed Apr 30 11:44:38 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (do_split): Add check and code for Node_gvar_ref.
+ * array.c (in_array, do_delete, asort_actual): Same.
+ * builtin.c (do_split): Same for 3rd arg array parameter.
+ * eval.c (interpret): Same for Node_K_array_for.
+ (push_args): Same for evaluating extra args.
+
+Tue Apr 29 15:54:28 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Record reading code redone/simplified considerably.
+
+ * awk.h (IOBUF): Removed total field, no longer used.
+ * io.c (at_eof, has_data, no_data_left): New macros.
+ (RECVALUE, SCANSTATE): New enumerated types.
+ (rs1get_a_record, rsnull_get_a_record, rsre_get_a_record): Removed.
+ (get_a_record): Rewritten, again. Now contains just buffer and
+ record code; searching code moved into these functions:
+ (rs1scan, rsnullscan, rsrescan): New functions to scan a buffer
+ for record contents and terminator. Fill in values in:
+ (struct recmatch): Holds found record and terminator.
+ (spec_setup): Set iop->dataend to indicate data is already in buffer.
+ (nextfile, inrec): Use new macros instead of flag and pointer tests.
+ (set_RS): Set scanning function instead of record function.
+
+ FWIW, it all passes `make test'.
+
+Sun Apr 27 21:02:39 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_close): At end, if do_posix return 0. See comment in code.
+
+Tue Apr 15 09:56:03 2003 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * configure.in: Check existence of wcrtomb, and wcscoll.
+ * configh.in: Likewise.
+ * configure: Re-generate.
+ Thanks to Kimura Koichi <kimura.koichi@canon.co.jp> for reporting.
+
+Sun Apr 13 16:02:10 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Add call to `setlocale' for LC_NUMERIC after program is
+ parsed.
+ (arg_assign): Switch back to "C" locale for LC_NUMERIC for command
+ line assignments; this is per POSIX that period is decimal point for
+ program and command line assignments and the locale's separator
+ applies for input, output, and string to number conversion.
+
+2003-03-26 Paul Eggert <eggert@twinsun.com>
+
+ * builtin.c [HAVE_INTTYPES_H]: Include <inttypes.h>.
+ [!HAVE_INTTYPES_H && HAVE_STDINT_H]: Include <stdint.h>.
+ (CHAR_BIT, INTMAX_MIN, UINTMAX_MAX): Define if the system does not.
+ (TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM): New macros, taken from
+ coreutils and many other GNU utilities.
+ (format_tree): When formatting, use widest possible integers
+ rather than settling with 'long'.
+ (do_lshift, do_rshift, do_and, do_or, do_xor, do_compl): Likewise,
+ when doing bitwise operations.
+ * configure.in (jm_AC_TYPE_LONG_LONG, jm_AC_TYPE_UNSIGNED_LONG_LONG,
+ jm_AC_TYPE_INTMAX_T, jm_AC_TYPE_UINTMAX_T): Add, since the mainline
+ code now needs this.
+ * doc/gawk.texi (Control Letters, Bitwise Functions): Document this.
+ * m4/intmax_t.m4: New file, taken from coreutils (but renamed to
+ avoid collision with our m4/inttypes.m4).
+ * m4/longlong.m4: New file, taken from coreutils.
+ * m4/uintmax_t.m4, m4/ulonglong.m4: Remove; superseded by the above
+ new m4 files.
+
+ * builtin.c (BITS_PER_BYTE): Remove; use CHAR_BIT instead, since
+ it's the standard name.
+ (do_lshift, do_rshift): Complain if the shift width is exactly equal
+ to the word size, too.
+
+Thu Mar 27 10:44:11 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (rs1_get_a_record, rsnull_get_a_record, rsre_get_a_record):
+ Enhance check for no data left in file to be only if file has
+ non-zero size. Linux files such as /proc/filesystems stat as a
+ regular file of size 0, but actually have contents. Ugh.
+ Thanks to Martin Schlemmer <azarah@gentoo.org> for the bug report.
+
+Wed Mar 26 12:19:32 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Add a lint warning at label `out_of_range'.
+
+Tue Mar 25 12:24:38 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (variable): For array subscript, if NAME is in the
+ symbol table, but not a variable, array, or parameter, generate
+ a syntax error.
+ (isarray): New function, tests if a symbol can be an array.
+
+ * custom.h: Add check for HP/UX, needed for GCC.
+
+Mon Mar 17 09:21:09 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Allow simultaneous manipulation of a global array directly
+ and when passed as a parameter.
+
+ * awk.h (Node_gvar_ref): New nodetype.
+ [orig_var]: New macro.
+ * array.c (do_delete_loop, do_delete): Add logic to handle
+ seeing Node_gvar_ref.
+ * eval.c (nodetypes): Add Node_gvar_ref.
+ (r_tree_eval, r_get_lhs): Add Node_gvar_ref case.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Wed Mar 19 14:08:11 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Production `program --> program error'. Add a return so
+ that we don't produce an infinite stream of error messages.
+ Thanks to Michael Mauch <michael.mauch@gmx.de> for pointing this out.
+
+Wed Mar 19 13:45:50 2003 Corinna Vinschen <vinschen@redhat.com>
+
+ * regex.c [RE_ENBABLE_I18N]: remove definition; the one in
+ regex_internal.h is better and makes things work with Cygwin.
+
+Tue Mar 11 11:54:20 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.h: Don't include <limits.h> after <regex.h> was
+ included in regex.c, since it could redefine RE_DUP_MAX to a lower
+ value.
+ (bitset_set, bitset_clear, bitset_contain): Use 1UL instead of 1 in
+ left shift operations.
+ * regex.c: Include <limits.h> before <regex.h>
+ * regcomp.c (re_compile_fastmap_iter, init_word_char, parse_expression):
+ Use 1UL instead of 1 in left shift operations.
+
+Mon Mar 10 15:45:37 2003 Corinna Vinschen <vinschen@redhat.com>
+
+ * configure.in: Update CYGWIN case to add /usr/lib/automode.o.
+
+Thu Mar 6 11:07:36 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Updated to automake 1.7.3.
+
+ * config.guess, config.sub: Updated from prep.
+ * Makefile.am (AUTOMAKE_OPTIONS): Add dist-bzip2 to get .bz2 files.
+
+Tue Mar 4 10:40:46 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * version.in: Added goop for K&R compilers; forgot that I have to fix
+ this file which then is used to create version.c.
+
+Mon Mar 3 17:00:44 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: New option --disable-lint.
+ * awk.h (do_lint, do_lint_old): Conditionally declare based on NO_LINT.
+ * eval.c (set_LINT): Ifdef out body if NO_LINT.
+ * main.c (do_lint, do_lint_old): Conditionally compile properly.
+ (main): Handle --lint argument code.
+
+Fri Feb 28 10:43:07 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Add LC_TIME to the things that get set with
+ setlocale().
+ * builtin.c (format_tree): Change test of `n0-- <= 0' to ==, avoids
+ VMS diagnostic.
+
+Thu Feb 27 17:48:29 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * regexec.c (proceed_next_node): Cast re_string_get_buffer to char *.
+ (get_subexp): Likewise.
+
+Tue Feb 25 12:33:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.h, regex_internal.c, regcomp.c, regexec.c:
+ Make MB_CUR_MAX into thread local variable re_mb_cur_max.
+
+ Unrelated, from Scott Deifik:
+
+ * io.c (grow_iop_buffer): Add checks for overflow of new buffer size.
+
+Mon Feb 24 13:30:59 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (gawk_mb_cur_max): Declared:
+ * main.c (gawk_mb_cur_max): Defined, init to 1.
+ (main): Initialize gawk_mb_cur_max.
+ * awkgram.y, builtin.c, eval.c, field.c, io.c, re.c (mb_cur_max):
+ Replaces all instances of MB_CUR_MAX, which is a function call (!)
+ in glibc. Big speed up, especially for -Fx case, where x is a
+ single character.
+
+ Unrelated:
+
+ * awkgram.y (rule): For non-existent action, use a Node_K_print_rec
+ node.
+
+Sun Feb 23 15:45:20 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Speed up plain `print' and `print $0':
+
+ * awk.h (Node_K_print_rec): New node type.
+ (do_print_rec): Declare function.
+ * awkgram.y (simple_stmt): Create humongous test for plain `print'
+ or `print $0', and if so, use a Node_K_print_rec for it. Modify
+ test for lint message.
+ * builtin.c (redirect_to_fp): New function for common code to get fp
+ and rp for do_print{,f,_rec} functions.
+ (do_print): Use redirect_to_fp().
+ (do_printf): Use redirect_to_fp().
+ (do_print_rec): New function to just print $0 from field_arr[0]
+ directly; will rebuild the record first if necessary.
+ * eval.c (nodetypes): Add Node_K_print_rec.
+ (interpret): Add Node_K_print_rec case.
+ * profile.c (pprint): Add Node_K_print_rec case.
+ (pp_print_stmt): If null lnode, print "$0" else print the lnode.
+
+ Unrelated:
+
+ * regex_internal.h: Add ENABLE_NLS to the condition for using
+ gettext so that --disable-nls really disables it.
+
+Sat Feb 23 22:46:00 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (rs1_get_a_record, rsnull_get_a_record, rsre_get_a_record):
+ Modify buffer-filling algorithm to always read one or more multiples
+ of the blocksize (iop->readsize).
+ (grow_iop_buffer): Make sure there's room for the current partially
+ read record and one disk block buffer.
+
+Thu Feb 20 22:02:00 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (research): Fix typo in cast of precision value to int.
+ * regex.h, regex.c, re_internal.h, re_internal.c, regcomp.c, regexec.c:
+ synced to GLIBC source, maintaining K&R portability changes, and bug
+ fixes, although losing ability to compile each file separately.
+ * Makefile.am (SOURCES): Moved placement of regex source files from here ...
+ (EXTRA_DIST): ... to here.
+
+Tue Feb 18 14:17:33 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (research): Cast precision value to int.
+ * builtin.c (format_tree): For toofew, cast field width value to int.
+ * io.c (rsre_get_a_record): Initialize restart and reend. Add a variable
+ to make sure they're set before used at end of function.
+ (iopflags2str): Removed decl at top and made not static so that GCC
+ stops complaining that it's defined but not used. Bleah.
+
+Mon Feb 17 11:02:34 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.sub: Updated from prep.
+
+Sun Feb 16 15:47:15 2003 Scott Deifik <scottd@amgen.com>
+
+ * awk.h (format_tree, make_str_node): Changed decls to match how
+ they are called.
+ * builtin.c (format_tree, sub_common): Same.
+ * node.c (make_str_node): Same.
+
+Wed Feb 5 14:18:01 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: Removed duplicate decl of set_prof_file(). Removed
+ undef of const for non-ANSI C; config.h should handle it.
+ * msg.c (set_loc): Use srcfile and srcline in regular code to shut up
+ stupid SGI compiler.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Tue Feb 4 13:40:41 2003 Martin C. Brown <mc@whoever.com>
+
+ * intl/libgnuintl.h: Preprocessor fixes for MacOS X.
+ * regex.h: Ditto.
+
+Tue Feb 4 13:39:37 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (builtin_func): New string for use in rationalizing
+ function parsing and installation code.
+
+Sun Feb 2 16:00:55 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Cache function body code pointer so that only have to find it the
+ first time a function is called. This potential for optimization
+ brought to my attention by Stepan Kasal.
+
+ * awk.h [funcbody]: New macro.
+ * awkgram.y (FUNC_CALL): Set $$->funcbody to NULL.
+ * eval.c (func_call): Changed to take top-level Node_func_call as the
+ single parameter. Do the lookup and caching.
+ (r_tree_eval): Change how func_call() is called in switch.
+ * profile.c (pp_func_call): Similar changes.
+ (tree_eval): Ditto.
+
+Sun Feb 2 15:32:42 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ ADR: More grammar rationalization/repair from Stepan.
+
+ * awkgram.y (common_exp, simp_exp): the rule from getline (without
+ pipe) has been moved from common_exp to simp_exp.
+
+ The redirection of print statements reworked. The idea comes from
+ mawk-1.3.3; much thanks to Michael Brennan!
+
+ * awkgram.y (IO_OUT, IO_IN): new tokens.
+ (APPEND_OP, TWOWAYIO): swallowed by the above ones.
+ (in_print, in_parens): new static variables, to trace whether
+ IO_OUT is expected.
+ (yylex): emit the new tokens, update in_parens on '(' and ')'.
+ (exp): the print command(s) reworked.
+ (oputput_redir): reworked.
+ (print_expression_list): new non-terminal.
+ (rexp, rexpression_list opt_rexpression_list): nuked.
+ (exp, simp_exp): ``cmd|getline'' rule changed to
+ ``cmd IO_IN getline'' and moved from exp to simp_exp.
+
+ Unrelated:
+
+ * awkgram.y (variable): Don't return Node_func, issue a fatal
+ error instead.
+ * eval.c (r_tree_eval, r_get_lhs): Omit special checks for Node_func,
+ nodes of this type cannot get into the program tree.
+ * profile.c (tree_eval, pp_lhs): Likewise.
+
+Thu Jan 30 17:42:05 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ ADR: Applied lots of patches from Stepan.
+
+ * array.c (do_delete_loop): Call after_assign for the loop index.
+ * field.c (do_split): The third argument to split(), sep, has to be
+ evaluated and the result dupnoded before assoc_clear is called,
+ similarily as src. And we needn't to evaluate the third argument
+ if it's CONSTant regex and the first parameter is null string.
+ * awk.h (dupnode): Changed to macro, function renamed to r_dupnode.
+ * node.c (dupnode, r_dupnode): Rename.
+ * awkgram.y (parms_shadow): Return bool value, ...
+ (shadow_funcs): ... which will enable us to end the program if
+ lintfunc is fatal.
+ (program): Cleanup of the rules defining the ``program'' non-terminal.
+ (start, program, rule): no value associated,
+ expression_value is now treated similarily as begin_block and end_block.
+ (pattern, rule): bison actions for non-terminal `pattern' now
+ add a new rule to the appropriate Node_rule_list, action for
+ non-terminal `rule' now only adds the associated code block
+ to the rnode of Node_rule_node.
+ (io_allowed): renamed to !begin_or_end_rule.
+ (append_pattern): New function, adds new Node_rule_node to a rule_list.
+ (mkrangenode): Deleted, this tiny function was called only once.
+ (function_body): non-terminal replaced by `action'.
+ (statements, action, statement): `statements' can now be empty;
+ both callers had to accomodate to this.
+ (statements): Don't call isnoeffect($2->type) if
+ $2 happens to be NULL.
+
+Mon Jan 27 14:12:19 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (iop_close): Based on report by Stepan Kasal and because of
+ his changes, don't call reset_record() when saving a copy of contents
+ of $0.
+ * awkgram.y: Improved function parsing error messages for case where
+ user uses a builtin name as a function name. Based on error report
+ by Stepan Kasal.
+ * ext.c (make_builtin): Set FUNC flag for new function. Based on error
+ report by Stepan Kasal.
+
+Mon Jan 27 14:06:20 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * field.c (reset_record): No longer call set_record(), the code is
+ moved to the function body. Do not set MAYBE_NUM.
+ (set_record): Call reset_record() to perform the common tasks.
+ The prototype has changed, change awk.h and all callers.
+
+Mon Jan 27 10:50:03 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (NODE): `proc' renamed to `builtin,' to fix a conflict
+ on some systems. Replaced on all spots where it was used.
+
+Sun Jan 26 11:52:01 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [NUMSUBPATS]: New macro.
+ * builtin.c (do_match): Use it in loop that fills in subpattern info.
+ * eval.c (r_tree_eval): for Node_assign, don't call free_temp(),
+ as assign_val() contains dupnode(), which would clear the TEMP
+ flag. From Stepan Kasal <kasal@math.cas.cz>.
+ * config.sub: Updated from prep.
+
+Sun Jan 19 22:34:01 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (do_asorti): Add declaration.
+ * awkgram.y (tokentab): Add asorti() function to table.
+ * array.c (ASORT_TYPE): New enumerated type for VALUE or INDEX array
+ sorting.
+ (assoc_sort_inplace): New second arg of type ASORT_TYPE. Additional code
+ to rearrange array so rest of merge-sorting works; basically values are
+ tossed and index moved into value spot.
+ (asort_actual): Renamed from do_asort(). Takes new ASORT_TYPE argument.
+ (do_asort): Calls asort_actual(tree, VALUE).
+ (do_asorti): Calls asort_actual(tree, INDEX).
+
+ * main.c (load_procinfo): Free groupset array when done with it.
+
+Thu Jan 16 18:30:50 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_match): Revised to provide start and length
+ indices in array 3rd parameter.
+ * config.guess, config.sub: Updated from prep.
+
+Thu Jan 2 11:09:12 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ Updated to bison 1.875.
+
+Tue Dec 31 17:14:45 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Updated things to automake 1.7.2 and autoconf 2.57.
+
+Tue Dec 31 16:54:44 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [IOP_CLOSED]: New flag.
+ * io.c (iop_close): Set IOP_CLOSED flag.
+ (inrec): Check for IOP_CLOSED; if set return EOF.
+ (rs1_get_a_record, rsnull_get_a_record): Check for EOF before
+ refilling buffers.
+ (rsre_get_a_record): Ditto. Also, set RT before updating pointers in IOP.
+ * Makefile.am (efence): New target to compile with Electric Fence.
+
+2002-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * awk.h (catchsig): Delete prototype.
+ * main.c (catchsig): Make static and remove excess argument.
+ (main): Delete unnecessary casts.
+ * io.c (rs1_get_a_record, rsnull_get_a_record): Mark parameter
+ with ATTRIBUTE_UNUSED.
+
+Mon Dec 23 11:54:07 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.h, regex_internal.c, regcomp.c, regexec.c, version.c:
+ Fixed to compile, once again, under K&R compilers.
+ * io.c (grow_iop_buffer): Fix calculation of new size to
+ first subtract 2, double, then add 2 back in.
+
+Fri Dec 20 11:48:42 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ get_a_record split into three routines.
+
+ * awk.h (IOBUF): Structure reworked for new code.
+ * io.c (get_a_record): Now a pointer to different functions.
+ (rs1_get_a_record, rsnull_get_a_record, rsre_get_a_record): New functions.
+ (iop_alloc, iop_close): Reworked for new structure.
+ (do_getline, inrec): Modifiend for new EOF condition.
+ (iopflags2str): New routine.
+
+Fri Dec 20 11:05:50 2002 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c, regex_internal.c, regex_internal.h: Changes to allow separate
+ compilation of the reg*c files.
+ * regcomp.c: Fix bug in using translation tables with [[:upper:]] etc.
+ * Makefile.am: Move regex files into sources from EXTRA_DIST. (ADR)
+
+Mon Dec 9 14:20:42 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * main.c (main): When processing option '-f' don't ignore spaces
+ if optarg points at the beginning of the current argument
+ (like ``gawk -f " " file'').
+
+2002-11-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * awkgram.y (stopme): Mark parameter with ATTRIBUTE_UNUSED.
+ (yyerror): Add ATTRIBUTE_PRINTF_1.
+ * builtin.c (do_systime, do_rand): Likewise.
+ * field.c (set_field, re_parse_field, def_parse_field,
+ posix_def_parse_field, null_parse_field, sc_parse_field,
+ fw_parse_field): Likewise.
+ * io.c (pidopen, useropen): Likewise.
+ * main.c (catchsig): Likewise.
+ * profile.c (init_profiling): Likewise.
+ * awk.h (err): Add ATTRIBUTE_PRINTF.
+ * msg.c (err): Delete redundant prototype. Fix format specifier.
+
+Wed Nov 27 06:04:20 2002 Pat Rankin <rankin@pactechdata.com>
+
+ * ext.c [#if !DYNAMIC] (do_ext): Cast string value for error node.
+
+Sun Nov 24 18:23:29 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ From Paul Eggert, with some edits by me.
+
+ * builtin.c (do_substr): Consistently use floating point
+ values for lint messages, so they should be printed pretty
+ much as the user saw them. Check for overflow before
+ converting floating point to integer. Do the right thing with
+ NaNs.
+
+ Check for index out-of-range before checking for length
+ out-of-range, to avoid some nasty effects if address
+ arithmetic overflows (e.g., indx + length < index).
+
+ Allow zero-length substrings when checking for lint if
+ do_lint == LINT_INVALID.
+
+Sun Nov 24 18:21:06 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (LINT_ALL, LINT_INVALID): New constants.
+ * main.c (main): Allow --lint=invalid which restricts warning to
+ things that aren't valid.
+ * eval.c (set_LINT): Update setting logic.
+
+Wed Nov 20 13:14:58 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (lintfunc): Improve ifdef for attribute to only
+ work for GCC 3.2 and later.
+ * io.c (PIPES_SIMULATED): Don't define if on AIX, which
+ does define TANDEM in one of its header files. Ugh.
+
+Tue Nov 19 15:33:55 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_substr): Use %lu in warnings instead of %d.
+
+Mon Nov 18 14:42:53 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess: Synced from ftp.gnu.org.
+ * config.sub: Ditto.
+
+Sun Nov 17 21:32:49 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Updated things to automake 1.7.1.
+
+Sun Nov 3 14:33:30 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_get_lhs): For variables, always clear UNINITIALIZED,
+ since the variable is about to be assigned to. From Stepan Kasal.
+
+Fri Nov 1 11:19:01 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (lintfunc): Can only supply attributes for a function
+ pointer if GCC >= 3. Added ifdefs. Bah, humbug.
+
+2002-10-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * array.c (array_init, concat_exp, assoc_find, do_delete):
+ Const-ify.
+ * awk.h (redirect, set_record, pp_func, pp_string_fp, format_val,
+ parse_escape, make_regexp, research, reisstring, remaybelong):
+ Likewise.
+ * awkgram.y (dumpintlstr, dumpintlstr2, func_use, dup_parms,
+ var_comp, finfo, fcompare, func_use, dumpintlstr, dumpintlstr2):
+ Likewise.
+ * builtin.c (stdfile, do_fflush, do_index, category_table):
+ Likewise.
+ * eval.c (push_forloop, push_args, PUSH_BINDING, RESTORE_BINDING,
+ cmp_nodes, op_assign, loop_info, fcall, fmt_ok, set_LINT,
+ comp_func): Likewise.
+ * ext.c (do_ext): Likewise.
+ * field.c (set_record): Likewise.
+ * io.c (gawk_popen, two_way_open, binmode, redirect, getredirect,
+ fatal): Likewise.
+ * node.c (values, format_val, make_str_node, parse_escape): Likewise.
+ * profile.c (pp_string, pp_match_op, pp_func, pp_string,
+ pp_string_fp): Likewise.
+ * re.c (make_regexp, research, reisstring, remaybelong): Likewise.
+
+2002-10-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * awk.h (__attribute__, ATTRIBUTE_UNUSED, ATTRIBUTE_NORETURN,
+ ATTRIBUTE_PRINTF, ATTRIBUTE_PRINTF_1, __extension__): Define.
+ (emalloc, erealloc): Fix format specifier warnings.
+ (do_nextfile):Mark with ATTRIBUTE_NORETURN.
+ (getredirect): Const-ify.
+ (msg, error, warning, r_fatal, lintfunc): Mark with
+ ATTRIBUTE_PRINTF_1.
+ (r_fatal): Mark with ATTRIBUTE_NORETURN.
+ * builtin.c (format_tree): Fix format specifier warning.
+ * eval.c (interpret): Likewise.
+ * main.c (usage, copyleft, catchsig, nostalgia, version): Mark
+ with ATTRIBUTE_NORETURN.
+ * profile.c (dump_and_exit): Likewise.
+
+2002-10-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * array.c (array_init): Use ISDIGIT, not isdigit.
+ * awk.h (m_tree_eval, force_number, force_string): Use
+ __extension__ in statement expressions.
+ * main.c (lintfunc): Fix !__SDTC__ case.
+ * regex_internal.c (calc_state_hash): Fix inline declaration.
+ * regexec.c (proceed_next_node): Cast assignment to correct type.
+
+2002-10-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * awk.h (exp_node, Func_ptr): Add prototype arguments.
+ * awkgram.y (yystype, token, getfname, nextc, pushback,
+ allow_newline, yylex): Likewise.
+ * io.c (wait_any): Likewise.
+ * profile.c (indent_in, indent_out): Likewise.
+ * random.h (random): Likewise.
+
+2002-10-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * array.c (grow_table): Const-ify.
+ * awk.h (RE_TRANSLATE_TYPE): Define.
+ (flagtab, casetable): Const-ify.
+ (getfname, shadow_funcs, redflags2str): Prototype.
+ (flags2str, genflags2str, nodetype2str, redflags2str, set_loc,
+ msg, error, warning, r_fatal): Const-ify.
+ * awkgram.y (tokentab, snode): Likewise.
+ * builtin.c (format_tree, do_strftime,
+ localecategory_from_argument): Likewise.
+ * eval.c (casetable, nodetypes, nodetype2str, flags2str,
+ genflags2str): Likewise.
+ * io.c (redflags2str, socketopen): Likewise.
+ * main.c (varfile, version_string, lintfunc, optab, copyleft,
+ varinit, init_vars): Likewise.
+ * msg.c (srcfile, msg, warning, error, set_loc, r_fatal):
+ Likewise.
+ * profile.c (pp_op_assign, pp_match_op, pp_redir): Likewise.
+ * random.c (sccsid): Likewise.
+ * version.c, version.in (version_string): Likewise.
+
+Tue Oct 29 10:50:52 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Update version in AC_INIT and AM_INIT_AUTOMAKE
+ * fixvers: Make grep for pattern a little smarter.
+
+Mon Oct 28 16:35:39 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (hash): Now a function pointer.
+ * array.c (gst_hash_string, scramble): New functions.
+ (awk_hash): Renamed from hash.
+ (hash): Now a function pointer.
+ (array_init): Change hash function based on environment for
+ experimentation.
+
+Mon Oct 28 13:21:20 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Applied lots of patches from Stepan Kasal, tweaked as needed
+ for current code base.
+
+ * node.c (dupnode): When n->stref overfows, flag the node as PERM.
+ Same for n->ahname_ref.
+ (unref): Remove the check for n->stref == LONG_MAX and
+ n->ahname_ref == LONG_MAX.
+ * awk.h (make_string): The third argument to make_str_node changed
+ from FALSE to 0, it's not Boolean.
+ (free_temp): Evaluate the argument only once, so that we
+ can call free_temp(tree_eval(n)) for achieving side effects.
+ (load_environ, load_procinfo): Changed return type to NODE *.
+ * main.c (load_environ): The ENVIRON_node should be created with type
+ Node_var_array and lnode set to NULL. Return pointer to the created node
+ and create an empty hash even on TANDEM.
+ (load_procinfo): Same mods for PROCINFO_node.
+ (init_args): ARGV_node should also have lnode set to NULL.
+ * eval.c (r_tree_eval): case Node_assign moved just above the other
+ assignment cases.
+ (op_assign): ++ and -- cases merged with += and -=, respectively.
+ (push_args): Evaluate all args, even in cases where more args are
+ supplied then required.
+ (interpret): In case Node_K_forarray, flag the variable
+ num_elems also as volatile, so that it survives longjmp() and
+ can be trusted when linting code.
+ (r_get_lhs): Case Node_param_list was unreachable (unless
+ something breaks really badly), remove it;
+ (r_tree_eval): case Node_var_array removed from the last switch,
+ it was caught in the first switch above.
+ * profile.c (tree_eval): Again, case Node_var_array was caught above.
+ * awkgram.y (variable): Code simplified, making use of the above
+ changes.
+ * field.c (sc_parse_field): IGNORECASE only applies to regex based
+ field-splitting, so remove code that pays attention to it.
+ (do_split): Don't use parse_field if RS_is_null.
+ (set_FS): Beware of FS == "\\" even if RS_is_null.
+
+ Code changes to make things work better:
+ * field.c (set_FS): Don't use cmp_nodes() to compare old and new
+ value of FS, that uses IGNORECASE, which is a bad idea. Improve
+ logic for choosing sc_parse_field. Ensure that when RS_is_null
+ but using a single character, that we do pay attention to
+ case when doing regex splitting.
+ * io.c (set_RS): Don't use cmp_nodes() to compare old and new
+ value of RS, that uses IGNORECASE, which is a bad idea.
+
+Mon Oct 28 09:43:14 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * recomp.c (parse_expression): Change return statement into
+ two so it'll compile for SGI cc.
+
+ * awk.h (STR, CUR): Changed to STRCUR and NUMCUR respectively,
+ to avoid conflict with STR on some System V systems. Changed
+ in all source files.
+
+Thu Oct 24 16:14:34 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (AVG_CHAIN_MAX): Now a variable, to allow easy experimentation.
+ (array_init): Pulls a new value from env var AVG_CHAIN_MAX if it
+ exists and sets the variable.
+ * awk.h: Add declaration for array_init().
+ * main.c (main): Call array_init().
+
+Tue Oct 22 11:23:56 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bisonfix.sed: Updated for current bison. Death to alloca!
+
+2002-10-21 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * builtin.c (tolower, toupper): Add casts to char* to fix some
+ compiler warnings.
+ * eval.c (cmp_nodes): Ditto.
+ * regcomp.c (peek_token_bracket): Skip the byte already read.
+
+Wed Oct 16 15:02:09 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (set_RS): Make sure to always call set_FS().
+
+2002-10-11 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regcomp.c (re_compile_fastmap_iter): Remove the handling
+ OP_CONTEXT_NODE.
+ (regfree): Likewise.
+ (create_initial_state): Likewise.
+ (analyze): Remove the substitutions which became useless.
+ (calc_first): Likewise.
+ (calc_epsdest): Use edests of OP_BACK_REF in case that it has
+ epsilon destination.
+ (duplicate_node_closure): New function.
+ (duplicate_node): Remove the handling OP_CONTEXT_NODE.
+ (calc_inveclosure): Likewise.
+ (calc_eclosure): Likewise.
+ (calc_eclosure_iter): Invoke duplicate_node_closure instead of
+ direct invocation of duplicate_node.
+ (parse): Don't use comma operator in the return to avoid compiler
+ warning.
+ (parse_reg_exp): Likewise.
+ (parse_branch): Likewise.
+ (parse_expression): Likewise.
+ (parse_sub_exp): Likewise.
+ (parse_dup_op): Likewise.
+ * regex_internal.c (re_dfa_add_node): Remove the substitutions
+ which became useless.
+ (create_ci_newstate): Remove the handling OP_CONTEXT_NODE.
+ (create_cd_newstate): Likewise.
+ * posix/regex_internal.h (re_token_type_t): Remove the obsolete type.
+ (re_token_t): Likewise.
+ (re_dfa_t): Likewise.
+ (re_node_set_remove): New macro.
+ * regexec.c (check_matching): Remove the handling
+ OP_CONTEXT_NODE.
+ (check_halt_node_context): Likewise.
+ (proceed_next_node): Likewise.
+ (pop_fail_stack): Fix the memory leak.
+ (set_regs): Likewise.
+ (free_fail_stack_return): New function.
+ (sift_states_backward): Fix the memory leak. Remove the handling
+ OP_CONTEXT_NODE.
+ (update_cur_sifted_state): Append some if clause to avoid redundant
+ call.
+ (sub_epsilon_src_nodes): Use IS_EPSILON_NODE since it might be a
+ back reference.
+ (check_dst_limits): Remove the handling OP_CONTEXT_NODE.
+ (check_subexp_limits): Likewise.
+ (search_subexp): Likewise.
+ (sift_states_bkref): Likewise.
+ (transit_state_mb): Likewise.
+ (transit_state_bkref_loop): Likewise.
+ (transit_state_bkref_loop): Likewise.
+ (group_nodes_into_DFAstates): Likewise.
+ (check_node_accept): Likewise.
+ (sift_ctx_init): Add initializing.
+
+Tue Oct 15 14:18:53 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (set_IGNORECASE): Call set_RS() instead of
+ set_FS_if_not_FIELDWIDTHS(). The former calls the latter
+ for us, and also makes IGNORECASE affect RS like it's supposed to.
+ * field.c (FS_re_yes_case, FS_re_no_case): New variables.
+ (set_FS): Smarten up routine to not recompile FS_regexp if all
+ that's changed is IGNORECASE or if switching back to FS from
+ FIELDWIDTHS. Significant speed-up for cases where IGNORECASE
+ is assigned to for every record.
+ * io.c (RS_re_yes_case, RS_re_no_case): New variables.
+ (set_RS): Similar changes as to set_FS(). In particular,
+ IGNORECASE changing now affects record splitting too.
+ * re.c (refree): Set rp->pat.tranaslate to NULL. It comes
+ from casetable and shouldn't be freed. (Strictly necessary
+ only for old regex, but a good idea anyway).
+ Also, call regfree(& rp->pat) instead of manually free()ing
+ things, since there's dynamically allocated stuff hiding in
+ the buffer. Avoids a memory leak.
+
+Mon Oct 14 12:02:39 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Major space reduction in array management. Overhead reduced
+ to two NODE's per element from three.
+
+ * awk.h (ahash): Union is gone.
+ (hash.ref): new union member.
+ (ahnext): new definition into hash union.
+ (ahvalue): new definition into hash union.
+ (ahname_str): new member, points into hash union.
+ (ahname_len): new member, points into hash union.
+ (ahname_ref): new member, points into hash union.
+ * array.c: Replaces uses of ahname member with string and
+ length. Set the reference count correctly to 1 on new nodes.
+ * eval.c (interpret): Case for Node_K_arrayfor. dupnode() the
+ array indices, and set loop variable to new value made via
+ make_string().
+ * node.c (unref, dupnode): Node_ahash nodes are now also
+ reference counted, a la strings. Similar code is used to
+ increment/decrement the counts, and/or copy nodes as
+ needed.
+
+ Unrelated:
+ * awk.h (forsub): Removed. Not used.
+
+Sun Oct 13 16:58:27 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * profile.c (pprint): #undef the temporary defines at the end
+ of the case.
+ * eval.c (interpret): Likewise.
+ (assign_val): we can unref() before doing dupnode().
+ Also, move the check for NF < 0 from here ...
+ * field.c (set_NF): ... to here.
+ * main.c (varinit): no need to call set_NF().
+ * awkgram.y (statements): don't be so generous when concatenating
+ `statements' with a `statement'.
+
+
+2002-10-13 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regcomp.c: Synced with development sources.
+ * regex_internal.c: Synced with development sources.
+ * regex_internal.h: Synced with development sources.
+ * regexec.c: Synced with development sources.
+
+Sun Oct 13 21:35:35 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (NODE): reflags is now unsigned long for:
+ (exec_count): defined to be sub.nodep.reflags. Using `number'
+ broke pgawk.
+ * profile.c (Node_K_delete_loop): print out as a for loop
+ with a comment that it's internally the same as `delete array'.
+ * eval.c (Node_K_delete_loop): Increment the exec_count. Ooops.
+ * configure.in (AM_GNU_GETTEXT_VERSION): New macro call.
+ * custom.h: Updated description of the file at the top.
+
+Thu Oct 10 16:39:51 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (vname, exec_count): Now macros into different
+ parts of the NODE structure that can be safely used for them.
+ Saves 16 bytes per NODE.
+ * eval.c: Changed use of `vname' to `varname' to avoid new
+ macro.
+ * main.c (lintfunc): Made ifdefed decls match awk.h.
+ * eval.c (comp_func): Use memcmp instead of strcmp.
+ * configure.in (AC_CONFIG_HEADER): Physically append custom.h
+ to config.h to avoid subdir compiliation problems.
+
+Sun Oct 6 17:36:15 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Updated to automake 1.7 and bison 1.50.
+
+ * INSTALL: Replaced with current version from automake 1.7.
+ * config.guess: Replaced with current version from automake 1.7.
+ * config.sub: Replaced with current version from automake 1.7.
+ * depcomp: Replaced with current version from automake 1.7.
+ * doc/texinfo.tex: Replaced with current version from automake 1.7.
+ * install-sh: Replaced with current version from automake 1.7.
+ * missing: Replaced with current version from automake 1.7.
+ * mkinstalldirs: Replaced with current version from automake 1.7.
+ * ylwrap: Replaced with current version from automake 1.7.
+
+ * configure.in (DYNAMIC): Updated AC_DEFINE(DYNAMIC) to
+ three-argument form for autoheader.
+ * acinclude.m4: Removed includes of jm-mktime.m4 and
+ largefile.m4, which are now standard parts of Autoconf.
+
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Regenerated.
+ * awkgram.c: Regenerated.
+ * awklib/Makefile.in: Regenerated.
+ * configure: Regenerated.
+ * doc/Makefile.in: Regenerated.
+ * test/Makefile.in: Regenerated.
+
+Sun Sep 29 16:47:49 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h (__WIN32__): Added from gnuwin32 project, via
+ Stepan Kasal.
+
+ * awkgram.y: For tawk compatibility, added `delete(array)'.
+ To remain undocumented, since it's WAY non-standard.
+
+Sun Sep 22 22:23:50 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (re_cnt): Removed, not needed since no dfa code.
+ * awkgram.y (regexp, a_regexp): Removed use of re_cnt.
+ * re.c (re_update): Ditto.
+
+Thu Sep 19 10:55:37 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (binmode): Create function if defined(WIN32) also.
+
+ Updated to gettext 0.11.5, autoconf 2.54 and automake 1.6.3.
+
+ * aclocal.m4: Regenerated.
+ * m4/codeset.m4: Updated.
+ * m4/gettext.m4: Updated.
+ * m4/glibc21.m4: Updated.
+ * m4/iconv.m4: Updated.
+ * m4/lcmessage.m4: Updated.
+ * m4/lib-ld.m4: Updated.
+ * m4/lib-link.m4: Updated.
+ * m4/lib-prefix.m4: Updated.
+ * m4/progtest.m4: Updated.
+ * po/Makefile.in.in: Updated.
+ * po/Rules-quot: Updated.
+ * po/boldquot.sed: Updated.
+ * po/en@boldquot.header: Updated.
+ * po/en@quot.header: Updated.
+ * po/insert-header.sin: Updated.
+ * po/quot.sed: Updated.
+ * po/remove-potcdate.sin: Updated.
+
+Tue Sep 17 23:46:01 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Moved override of INSTALL to just after
+ AC_INIT so that it takes effect. Necessary for Autoconf 2.5x.
+
+Mon Sep 16 16:40:57 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * awkgram.y (want_assign): Removed.
+ (SLASH_BEFORE_EQUAL, ASSIGN): New terminals; ``/='' is now
+ formed from these two.
+ (a_slash): New non-terminal, representing either '/' or
+ SLASH_BEFORE_EQUAL.
+ (assign_operator): New non-terminal, replaces ASSIGNOP.
+ (REGEXP): yylex now eats the terminating '/' before
+ returning REGEXP token.
+ (exp): The check for C-like comments moved from here
+ (regexp): ... to here.
+ (common_exp): New non-terminal; contains common parts of exp
+ and rexp. (a_relop, relop_or_less): New non-terminals.
+ (rexp): some rules updated to be analogous to exp.
+ (output_redir): Can contain only common_exp, not exp in general.
+
+Mon Sep 16 22:51:51 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (two_way_open): Move label use_pipes outsidef of ifdef,
+ just in case.
+
+Thu Sep 12 15:11:28 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (getfname): Return NULL if not found, remove
+ fatal error. Could be an extension function.
+ (dump_funcs): Walk symbol table counting functions before
+ mallocing table, since there could be extension functions,
+ func_count could be too small.
+ * profile.c (pp_builtin): Handle NULL return from getfname().
+ Print it as "extension_function()" if so.
+
+Tue Sep 10 17:33:48 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Minor code simplification.
+
+ * awk.h (in_array): Change return type to NODE*.
+ (assoc_exists): Remove declaration.
+ * array.c (in_array): Change return type to NODE *.
+ Return value is pointer to element value or NULL.
+ (assoc_exists): Removed function.
+ * eval.c (r_tree_eval): Case Node_in_array, change value
+ to test return of in_array() against NULL.
+ * io.c (pty_vs_pipes): Change test to make a tmp_string()
+ of the index and call in_array(). Add free_temp() of
+ subscript and free() of full_index (oops).
+
+2002-09-10 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * posix/regcomp.c: Wrap #include wchar.h and wctype.h in #if.
+ (build_range_exp): Add castings to strlen invocations.
+ (build_collating_symbol): Restore the type of characters from "char"
+ to "unsigned char", and supplement castings.
+ (build_collating_symbol): Likewise.
+ (build_equiv_class): Likewise.
+ (build_charclass): Likewise.
+ (seek_collating_symbol_entry): Likewise.
+ (parse_bracket_exp): Likewise.
+ (build_word_op): Supplement a casting.
+ * posix/regex_internal.c: Wrap #include wchar.h and wctype.h in #if.
+ (re_string_allocate): Fix castings.
+ (re_string_construct): Likewise.
+ (re_string_construct_common): Likewise.
+ (re_string_realloc_buffers): Likewise.
+ (build_wcs_buffer): Likewise.
+ (build_wcs_upper_buffer): Likewise.
+ (re_string_skip_chars): Likewise.
+ (re_string_reconstruct): Likewise.
+ * posix/regex_internal.h: Restore the type of characters in
+ re_string_t and bracket_elem_t from "char" to "unsigned char".
+ (re_string_elem_size_at): Fix castings.
+ * posix/regexec.c: Wrap #include wchar.h and wctype.h in #if.
+ (transit_state_bkref_loop): Restore the type of characters from
+ "char" to "unsigned char", and append a cast to "char*" pointer in
+ array subscript.
+ (check_node_accept_bytes): Likewise.
+ (find_collation_sequence_value): Likewise.
+
+Thu Sep 5 13:15:09 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (remaybelong): New routine.
+ (reisstring): Simplified the code a bit.
+ * awk.h (remaybelong): Declaration added.
+ * io.c (get_a_record): Change fourth grungy special case to
+ use remaybelong() instead of strchr() on last character.
+
+Wed Sep 4 13:20:26 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_input): Recode guts of main loop to be easier
+ to trace with a debugger.
+ (get_a_record): Fourth grungy special case for RE-based
+ record splitting added. See explanatory comments there
+ and test/rebuf.awk.
+
+2002-09-03 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * posix/regcomp.c (regcomp): Append "__restrict" modifier to avoid
+ warnings of some compilers.
+ (build_collating_symbol): Change the type of characters from
+ "unsigned char" to "char", and append a cast to "char*" pointer in
+ array subscript.
+ (build_collating_symbol): Likewise.
+ (build_equiv_class): Likewise.
+ (build_charclass): Likewise.
+ (re_compile_pattern): Remove incorrect cast.
+ (re_compile_fastmap_iter): Change the type of characters from
+ "unsigned char" to "char", and append a cast to "char*" pointer
+ in array subscript.
+ (parse_bracket_exp): Likewise.
+ * posix/regex_internal.c (re_string_construct_common): Likewise.
+ (re_string_allocate): Likewise.
+ (re_string_construct): Likewise.
+ (re_string_realloc_buffers): Likewise.
+ (build_wcs_buffer): Likewise.
+ (re_string_reconstruct): Likewise.
+ * posix/regex_internal.h: Change the type of characters in
+ re_string_t and bracket_elem_t from "unsigned char" to "char".
+ * posix/regexec.c (regexec): Append "__restrict" modifier to avoid
+ warnings of some compilers.
+ (transit_state_bkref_loop): Change the type of characters from
+ "unsigned char" to "char", and append a cast to "char*" pointer in
+ array subscript.
+ (check_node_accept_bytes): Likewise.
+ (find_collation_sequence_value): Likewise.
+
+Wed Aug 21 15:40:36 2002 Corinna Vinschen <vinschen@redhat.com>
+
+ * configure.in: Define --without-libintl-prefix and
+ --without-libiconv-prefix for Cygwin by default.
+ * Makefile.am: Call fixvers from $(srcdir).
+ * awk.h: Don't define O_BINARY on Cygwin.
+
+Wed Aug 21 15:31:57 2002 Andreas Buening <andreas.buening@nexgo.de>
+
+ * configure.in (AC_OBJEXT, AC_EXEEXT): Added. Removed OS/2 goo.
+ * Makefile.am (check-local): Add $(EXEEXT) suffixes, remove OS/2 goo.
+ * regcomp.c, regex_internal.c, regexec.c: Conditionalize include of
+ <wchar.h> and <wctype.h> on RE_ENABLE_I18N.
+
+Wed Aug 21 14:43:57 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gettext.h (ENABLE_NLS): Add include of locale.h so that things
+ compile even without optimization. Sheesh.
+ * io.c (two_way_open, pty_vs_pipes): Conditionalize pty code on
+ HAVE_TERMIOS_H.
+
+Thu Aug 8 22:16:10 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Force LC_NUMERIC locale to "C", esp. for
+ M$ systems. Ugh.
+
+Wed Aug 7 13:42:01 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Improve test for newlines at beginning of
+ record but with nothing following it. See test/nulrsend.
+
+Mon Aug 5 10:12:39 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add option to use ptys instead of pipes for |&.
+ Basic plumbing originally from Paolo Bonzini <bonzini@gnu.org>.
+
+ * awk.h (RED_PTY): New flag.
+ (assoc_exists): Add declaration.
+ * array.c (in_array): Use FALSE not zero for return value.
+ (assoc_exists): New routine to find and return value for an index
+ in an array.
+ * configure.in: test for termios.h and stropts.h, and grantpt function.
+ * io.c: include termios.h and stropts.h if available.
+ (redflags2str): Add RED_PTY to table.
+ (redirect): Add RED_PTY to flags turned off when searching.
+ (close_redir): close write channel for two-way pipes
+ that use ptys by sending an EOF.
+ (two_way_open): If pty_vs_pipe(), use pty's to open two-way pipes as
+ they are line-buffered by default --> alleviates deadlock problems.
+ If fails, fall back to using pipes.
+ (pty_vs_pipe): New function.
+ * main.c (arg_assign): Clean up English in some of the error messages.
+
+Sun Aug 4 00:37:38 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * re.c (make_regexp): don't pass the error message returned by
+ re_compile_pattern() to gettext(); it's already gettextized.
+ (make_regexp): minor reformat of code.
+
+Wed Jul 31 23:50:31 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Removed dfa code from gawk since not really needed with new regex.
+
+ * Makefile.am: Removed dfa.h and dfa.c.
+ * awk.h (struct Regexp): Removed `dfareg' and `dfa' members.
+ (make_regexp): Last parameter in function went away, changed decl.
+ (avoid_dfa): Removed declaration.
+ * awkgram.y: Fixed call to make_regexp().
+ * eval.c (match_op): Simplified: removed call to avoid_dfa() and
+ `kludge_need_start' variable. Instead, pass FALSE as last parameter
+ of research().
+ * field.c (set_FS): Fixed call to make_regexp().
+ * io.c (get_a_record, set_RS): Fixed calls to make_regexp().
+ * re.c (make_regexp): Removed last paramter (`dfa') from function.
+ Simplified the code.
+ (research): Simplified the code, removed calls to dfa stuff.
+ (dfaerror): Removed function.
+ (re_update): Fixed call to make_regexp().
+ (avoid_dfa): Removed function.
+
+Thu Jul 25 21:55:45 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c, regex_internal.c, regex_internal.h, regexec.c: Bug
+ fixes from Isamu Hasegawa <isamu@yamato.ibm.com> and Stepan Kasal
+ <kasal@math.cas.cz> applied.
+
+Sat Jul 6 23:28:37 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yyerror): Change text of unexpected newline message to
+ include end of string.
+
+Mon Jun 17 17:58:55 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (do_split): Per Michal Jaegermann, move free_temp(fs)
+ above label `out'.
+
+Tue Jun 11 23:26:09 2002 Paul Eggert <eggert@twinsun.com>
+
+ Update to autoconf 2.53 and automake 1.6.1.
+
+ * acconfig.h: Removed.
+ * m4/isc-posix.m4: Removed.
+ * m4/jm-mktime.m4: Removed.
+ * m4/largefile.m4: Removed.
+ * m4/ssize_t.m4: Removed.
+ * ansi2knr.c: updated.
+ * depcomp: updated.
+ * install-sh: updated.
+ * missing: updated.
+ * mkinstalldirs: updated.
+ * ylwrap: updated.
+
+ * configure.in: Improved quoting.
+ * acinclude.m4: Use `m4_sinclude', not antiquated `sinclude'.
+
+Tue Jun 11 23:08:40 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Add `getgrent' to list of functions checked
+ so that awklib/grcat is compiled correctly.
+
+Tue Jun 11 22:18:42 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ Improve argument parsing and -v assignment.
+
+ * awk.h (struct src): Add additional enum values.
+ (arg_assign): Return type and arg list changes.
+ * io.c (nextfile): Add extra arg in call to `arg_assign'.
+ * main.c (pre_assign): Nuked.
+ (allocfiles): New variable.
+ (srcfiles_add, preassigns_add): New macros.
+ (main): Logic cleaned up.
+ (add_src): New function.
+
+ Use `size_t' for optimal_bufsize function.
+
+ * awkgram.y (yylex): `len' is now size_t.
+ * pc/gawkmisc.pc (optimal_bufsize): Change return type to size_t.
+ * posix/gawkmisc.c (optimal_bufsize): Change return type to size_t.
+ * unsupported/atari/gawkmisc.atr (optimal_bufsize): Change return type
+ to size_t.
+ * unsupported/tandem/tmisc.c (optimal_bufsize): Change return type to size_t.
+ * vms/gawkmisc.vms (optimal_bufsize): Change return type to size_t.
+ * README_d/README.hpux: New file.
+
+Fri May 24 12:23:01 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (init_profiling): Remove default initialization
+ of `prof_fp' to stderr. Per Stepan Kasal <kasal@math.cas.cz>.
+
+Wed May 15 15:39:17 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Work through builtin operations to make sure that
+ anything that might have side effects gets dealt with.
+
+ * array.c (do_delete): Evaluate subscript first before
+ checking if something is or isn't an array.
+ * builtin.c (sub_common): Evaluate replacement text, and
+ free it if no match of regex in source text.
+
+Wed May 15 15:30:34 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Switch to new version of regex from IBM Japan.
+
+ * regcomp.c: New file.
+ * regex.c: Replaced with new version.
+ * regex.h: Replaced with new version.
+ * regex_internal.c: New file.
+ * regex_internal.h: New file.
+ * regexec.c: New file.
+ * Makefile.am (EXTRA_SOURCES): New files added.
+
+Tue May 14 17:04:05 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (<locale.h>): Move check and include into gettext.h.
+ * gettext.h (<locale.h>): Add check and include per patch from
+ Bruno Haible.
+
+ * field.c (do_split): When checking for split of null string,
+ evaluate seperator if it's not FS, since could have side effects.
+ At end, free_temp(fs), not free_temp(sep).
+ Both of these thanks to Stepan Kasal <kasal@math.cas.cz>.
+
+Mon May 13 00:41:31 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h (ultrix): Add define GETGROUPS_NOT_STANDARD.
+ * main.c (init_groupset): For GETGROUPS_NOT_STANDARD, use old way
+ to set `ngroups'.
+
+2002-05-10 Andreas Schwab <schwab@suse.de>
+
+ * dfa.c (parse_bracket_exp_mb): Fix warning.
+
+Thu May 9 22:28:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (sub_common): Fix logic for match of null strings to
+ get correct semantics. See test/gsubtst2.*.
+ * field.c (do_split): Minor code cleanup; the third arg to split()
+ is set to be FS by the grammar, so don't need to check it for NULL.
+ Thanks to Stepan Kasal <kasal@math.cas.cz>.
+ * awk.h (locale.h): Move include before that of "gettext.h" for systems
+ that define functions that gettext.h would use when NLS is disabled.
+ Per bug report from Ayamura Kikuchi <ayamura@ayamura.org>.
+
+Tue May 7 17:31:01 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Miscellanious patches courtesy of Stepan Kasal <kasal@math.cas.cz>.
+
+ * field.c, main.c: Tidy up some comments.
+ * field.c (set_FIELDWIDTHS): Init fw_alloc to 4 so it isn't
+ immediately realloced.
+ * main.c (load_procinfo): Check value of FS/FIELDWIDTHS for
+ value of PROCINFO["FS"].
+ * awk.h (set_FS_if_not_FIELDWIDTHS): Removed decl.
+ * field.c (set_FS_if_not_FIELDWIDTHS): Removed function.
+ * eval.c (set_IGNORECASE): Use inline code checking `using_fieldwidths()'.
+ * io.c (set_IGNORECASE): Ditto.
+
+Sun May 5 14:28:34 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix a memory leak in array for loops if the body contains a
+ `next' or `nextfile' statement. The changes maintain a stack
+ of active for loops that is pushed and popped for each loop,
+ and popped entirely for `next', `nextfile', etc.
+
+ * eval.c (forloops_active, pop_forloop, pop_all_forloops, push_forloop):
+ new functions.
+ (interpret): Case Node_K_arrayfor, call push and pop functions.
+ Case Node_rule_list: pop loops and pop fcalls after longjmp.
+ Cases Node_K_next, Node_K_nextfile, Node_K_break and
+ Node_K_continue, removed check before longjmp.
+ Case Node_K_exit: add loop check.
+ (loop_stack, nloops, nloops_active): New variables that implement
+ the stack.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Wed May 1 16:07:49 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.c: Installed latest version from glibc.
+
+Sun Apr 28 17:19:07 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fixvers: Changed patterns to allow test versions of the
+ form `gawk-3.1.1a'.
+ * patchlev.h: Patchlevel is now a string constant.
+ * main.c (version): Print patchlevel using %s, not %d.
+ * Makefile.am: Rework DEFPATH stuff and datadir stuff yet again.
+
+ * config.sub: Updated with current version from ftp.gnu.org.
+ * config.guess: Ditto.
+
+ Upgrade to gettext-0.11.2:
+
+ * ABOUT-NLS: Replaced with version from gettext 0.11.2.
+ * config.rpath: Replaced with version from gettext 0.11.2.
+ * intl/*: Replaced with version from gettext 0.11.2.
+ * po/Makefile.in.in: Replaced with version from gettext 0.11.2.
+ * po/Makevars.template: Replaced with version from gettext 0.11.2.
+ * po/Rules-quot: Replaced with version from gettext 0.11.2.
+ * po/boldquot.sed: Replaced with version from gettext 0.11.2.
+ * po/en@boldquot.header: Replaced with version from gettext 0.11.2.
+ * po/en@quot.header: Replaced with version from gettext 0.11.2.
+ * po/insert-header.sin: Replaced with version from gettext 0.11.2.
+ * po/quot.sed: Replaced with version from gettext 0.11.2.
+ * po/remove-potcdate.sin: Replaced with version from gettext 0.11.2.
+ * m4/codeset.m4: Replaced with version from gettext 0.11.2.
+ * m4/gettext.m4: Replaced with version from gettext 0.11.2.
+ * m4/glibc21.m4: Replaced with version from gettext 0.11.2.
+ * m4/iconv.m4: Replaced with version from gettext 0.11.2.
+ * m4/isc-posix.m4: Replaced with version from gettext 0.11.2.
+ * m4/lcmessage.m4: Replaced with version from gettext 0.11.2.
+ * m4/lib-ld.m4: Replaced with version from gettext 0.11.2.
+ * m4/lib-link.m4: Replaced with version from gettext 0.11.2.
+ * m4/lib-prefix.m4: Replaced with version from gettext 0.11.2.
+ * m4/progtest.m4: Replaced with version from gettext 0.11.2.
+
+Wed Apr 17 15:09:45 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.c (PREFIX): Change test for token concatenation ability
+ to `#ifdef HAVE_STRINGIZE'. If a cpp has one, it ought to have
+ the other.
+
+Tue Apr 16 12:26:06 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (tree_eval): Make unary minus case smarter,
+ use is_scalar test and if false parenthesize expression.
+ Add Node_TEXTDOMAIN case.
+ (pp_lhs, is_scalar, prec_level): Add Node_TEXTDOMAIN cases.
+
+Thu Apr 11 21:28:33 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (do_adump): Spelling fix in output message.
+ * builtin.c: Ditto, in multiple routines.
+ (do_toupper, do_tolower): Add cast to size_t in assigment to mbclen
+ for some compilers.
+ * re.c (research): Fix way returning is done to silence some
+ compiler diagnostics.
+
+Wed Apr 10 19:30:51 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (datadir): Set directly to have `/awk'.
+ (DEFPATH): Go back to using $(datadir) for path.
+
+Tue Apr 9 17:34:09 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Upgraded to gettext 0.11.1.
+
+ * Makefile.am (LDADD): Use @LIBINTL@ instead of @INTLLIBS@.
+ * ABOUT-NLS: Version from 0.11.1.
+ * config.rpath: Version from 0.11.1.
+ * aclocal.m4: Regenerated based on new files.
+ * intl/*: Replaced with version from 0.11.1.
+ * m4/ChangeLog: New file.
+ * m4/codeset.m4: New file.
+ * m4/gettext.m4: Version from 0.11.1.
+ * po/ChangeLog: New file.
+ * po/Makefile.in.in: Version from 0.11.1.
+ * po/remove-potcdate.sin: New file.
+
+Mon Apr 8 22:22:58 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (libexecdir): Set directly to have `/awk'.
+ (DEFPATH): Use $(pkgdatadir) for path.
+ (install-exec-hook): Add version link for pgawk.
+ (uninstall-links): Remove pgawk version link.
+
+Wed Mar 20 13:44:21 2002 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c (__alignof__): Definition for non-GCC compilers.
+
+Sun Mar 17 17:41:55 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_pathopen): Malloc buffers to hold constructed
+ filenames: No Arbitrary Limits! Thanks to keoki@techie.com
+ for the bug report.
+
+Sun Mar 10 16:59:06 2002 Scott Deifik <scottd@amgen.com>
+
+ * awk.h (LOCALEDIR): Provide a definition in case not using
+ i18n stuff.
+
+Wed Mar 6 18:14:44 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (usage): Add some explanatory text and examples at end.
+
+Sun Mar 3 16:42:50 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.h, getopt.c, getopt1.c: Update to current version
+ from glibc CVS.
+
+Fri Feb 22 15:53:38 2002 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * dfa.c (fetch_wc): Fix type from wchar_t to wint_t.
+ (parse_bracket_exp_mb): Likewise.
+ * regex.c (extract_number): Retrieve the sign information from
+ byte-code in case of AIX.
+
+Thu Feb 21 16:44:24 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (resetup): Moved setting re_max_failures into regex.c.
+ * regex.c (re_max_failures): Set to really big if REGEX_MALLOC
+ defined. Do this in both places that define re_max_failures.
+
+Thu Feb 21 19:02:22 2002 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * builtin.c (sub_common): Avoid index_multibyte_buffer invocation
+ in single byte character environments.
+
+Thu Feb 21 10:08:56 2002 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * dfa.c (parse_bracket_exp_mb): For ':', use wctype_t in MALLOC,
+ not wchar_t.
+
+Thu Feb 21 09:52:16 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Upgraded to automake 1.5 and gettext-0.11.
+ Also bug fix to multibyte code.
+
+ * ABOUT-NLS: upgraded.
+ * config.guess, config.sub, config.rpath, gettext.h, ylwrap: new files.
+ * Makefile.am: added above to appropriate places.
+ * awk.h: Replace libintl.h and macros with include of gettext.h.
+ (emalloc, erealloc): Add num bytes to error message, put string inside _().
+ (index_multibyte_buffer): Removed decl.
+ * awklib/Makefile.am: Use $(EXEEXT) for grcat and pwcat targets.
+ * builtin.c (index_multibyte_buffer): Made static to this file.
+ (sub_common): Add checks that replacement string is length > 0 so
+ that we don't try to malloc(0): this fails on some systems.
+ * configure.in (AM_GNU_GETTEXT): Update macro for gettext 0.11.
+ (ALL_LINGUAS): Removed.
+ * m4/codeset.m4: new file.
+ * m4/gettext.m4: updated.
+ * m4/glibc21.m4: new file.
+ * m4/iconv.m4: new file.
+ * m4/isc-posix.m4: new file.
+ * m4/lcmessage.m4: updated.
+ * m4/lib-ld.m4: new file.
+ * m4/lib-link.m4: new file.
+ * m4/lib-prefix.m4: new file.
+ * m4/progtest.m4: updated.
+ * intl/*: Replaced with version from gettext 0.11.
+ * po/*: Revised for gettext 0.11.
+
+Mon Feb 18 14:42:39 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (nondec2awknum): Change assert to runtime check
+ in case user passed in bad data.
+
+2002-02-17 Paul Eggert <eggert@twinsun.com>
+
+ * re.c (resetup): Try to avoid silly limitation of regex.c by
+ setting re_max_failures to the largest reasonable value.
+
+Sun Feb 17 14:57:43 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (research): If re_search() returns -2, the
+ match failed since regex couldn't allocate enough memory
+ for what it needed. Fail with a fatal message instead.
+ This is a workaround, not a fix, but I don't mess with
+ regex.[ch].
+
+Fri Feb 8 16:01:11 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (LEX_FOR): Fix case of array loop with body of single
+ delete statement to actually check the right things to make the
+ optimization.
+ * profile.c (tree_eval): Add case for Node_K_delete_loop.
+ (prec_level): Ditto.
+
+Mon Feb 4 10:38:00 2002 Bruno Haible <bruno@clisp.org>
+
+ * awk.h (dcngettext): New macro.
+ (do_dcngettext): New declaration.
+ * awkgram.y (tokentab): Add dcngettext.
+ (snode): Add a warning for incorrect use of dcngettext.
+ (dumpintlstr): fflush at the end, not in the middle.
+ (dumpintlstr2): New function.
+ * builtin.c (localecategory_from_argument): New function, extracted
+ from do_dcgettext.
+ (do_dcgettext): Call it.
+ (do_dcngettext): New function.
+
+Sun Feb 3 17:56:20 2002 Bruno Haible <bruno@clisp.org>
+
+ * builtin.c (do_bindtextdomain): Don't free the same variable twice.
+ * main.c (main): Call setlocale for LC_MESSAGE, to make dcgettext
+ function work on glibc systems.
+
+Wed Jan 23 15:03:36 2002 Andreas Buening <andreas.buening@nexgo.de>
+
+ * configure.in (PATH_SEPARATOR): Code added for OS/2.
+ Makefile.am (PATH_SEPARATOR): Added.
+ (DEFPATH): Make use of PATH_SEPARATOR.
+
+Wed Jan 23 14:46:04 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yylex): Add test for lasttok != '$' when looking
+ at _"...". See comments in code.
+
+Wed Aug 15 07:43:10 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c : Implements the codes for exactn_bin to work correctly
+ in multibyte environments, in case of invalid multibyte sequence.
+
+Wed Aug 15 07:36:56 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c : Implements the codes for charset/charset_not to
+ work in multibyte environments.
+
+Wed Aug 15 05:04:34 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c : Add some comments.
+
+Wed Aug 15 05:04:15 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c (count_mbs_length): New function, check the mutibyte
+ strings and count how many wchar_t the substring occupy.
+ (CHAR_T): New macro, character type depending on
+ environments(singlebyte/multibyte).
+ (UCHAR_T): New macro, unsigned character type.
+ (COMPILED_BUFFER_VAR): New macro, the buffer containing
+ the compiled buffer.
+ Adapt singlebyte/multibyte environments with CHAR_T, UCHAR_T,
+ and COMPILED_BUFFER_VAR.
+
+Mon Jun 25 09:00:41 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c : Reorganize code to build code twice. byte_* are
+ for single byte, wcs_* are for multibyte character sets.
+ Chose functions according to current locale dynamically.
+ * regex.c (convert_mbs_to_wcs): New function, convert multibyte
+ strings to wide character strings for multibyte environments.
+
+Fri Jun 22 05:43:50 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * regex.c (MBS_SUPPORT): New macro, defined if the environment
+ can handle multibyte characters.
+ (OFFSET_ADDRESS_SIZE): Offset address size in the
+ compiled buffer.
+ Rewrite offset addresses with OFFSET_ADDRESS_SIZE.
+
+Thu Apr 26 08:03:17 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * builtin.c (index_multibyte_buffer) : inspect the buffer and write
+ the index.
+ (sub_common) : in multibyte environment, skip multibyte characters
+ when we check special characters.
+ * awk.h (index_multibyte_buffer) : add prototype.
+ * eval.c (cmp_nodes) : in multibyte environment, compare per character.
+ * field.c (re_parse_field) : in multibyte environment, avoid to
+ call research() on invalid boundary.
+ (sc_parse_field) : in multibyte environment, avoid to compare on
+ invalid boundary.
+ (null_parse_field) : in multibyte environment, split per
+ character, not per byte.
+ * io.c (get_a_record) : in multibyte environment, avoid to compare
+ on invalid boundary.
+
+Wed Apr 25 08:29:47 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * awk.h (strncasecmpmbs) : add prototype.
+ * builtin.c (strncasecmpmbs) : new function like strncasecmp but for
+ multibyte strings.
+ (do_index) : in multibyte environment, compare per character.
+ * builtin.c (do_tolower) : in multibyte environment, user towlower
+ instead of TOLOWER.
+ (do_toupper) : in multibyte environment, user towupper instead
+ of TOUPPER.
+
+Tue Apr 24 10:38:06 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ In multibyte environments, handle multibyte characters as single
+ characters in bracket expressions.
+
+ * dfa.h (mb_char_classes) : new structure.
+ (mbcsets) : new variable.
+ (nmbcsets) : new variable.
+ (mbcsets_alloc) : new variable.
+ * dfa.c (prtok) : handle MBCSET.
+ (fetch_wc) : new function to fetch a wide character.
+ (parse_bracket_exp_mb) : new function to handle multibyte character
+ in lex().
+ (lex) : invoke parse_bracket_exp_mb() for multibyte bracket expression.
+ (atom) : handle MBCSET.
+ (epsclosure) : likewise.
+ (dfaanalyze) : likewise.
+ (dfastate) : likewise.
+ (match_mb_charset) : new function to judge whether a bracket match
+ with a multibyte character.
+ (check_matching_with_multibyte_ops) : handle MBCSET.
+ (dfainit) : initialize new variables.
+ (dfafree) : free new variables.
+
+Mon Apr 23 01:40:09 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ Implement the mechanism to match with multibyte characters,
+ and use it for `period' in multibyte environments.
+
+ * dfa.h (mbps) : new variable.
+ * dfa.c (prtok) : handle ANYCHAR.
+ (lex) : use ANYCHAR for `period' in multibyte environments.
+ (atom) : handle ANYCHAR.
+ (state_index) : initialize mbps in multibyte environments.
+ (epsclosure) : handle ANYCHAR.
+ (dfaanalyze) : handle ANYCHAR.
+ (dfastate) : handle ANYCHAR.
+ (realloc_trans_if_necessary) : new function.
+ (transit_state_singlebyte) : new function.
+ (match_anychar) : new function.
+ (check_matching_with_multibyte_ops) : new function.
+ (transit_state_consume_1char) : new function.
+ (transit_state) : new function.
+ (dfaexec) : invoke transit_state if expression can match with
+ a multibyte character in multibyte environments.
+ (dfamust) : handle ANYCHAR.
+
+Fri Apr 20 11:31:24 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ Avoid incorrect state transition in multibyte environments.
+
+ * dfa.h (nmultibyte_prop) : new variable.
+ (multibyte_prop) : new variable.
+ * dfa.c (addtok) : set inputwcs.
+ (dfastate) : avoid incorrect state transition in multibyte
+ environments.
+ (dfaexec) : likewise.
+ (dfainit) : init multibyte_prop.
+ (dfafree) : free multibyte_prop.
+ (inputwcs): new variable.
+ (mblen_buf) : new variable contains the amount of remain byte
+ of corresponding multibyte character in the input string.
+
+Fri Apr 20 06:28:59 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ Handle a multibyte character followed by '*', '+', and '{n,m}'
+ correctly.
+
+ * dfa.c (update_mb_len_index): new function.
+ Support for multibyte string.
+ (FETCH) : call update_mb_len_index.
+ (lex) : check cur_mb_index not to misunderstand multibyte characters.
+ (atom) : make a tree from a multibyte character.
+ (dfaparse) : initialize new variables.
+ (mbs) : new variable.
+ (cur_mb_len) : new variable.
+ (cur_mb_index) : new variable.
+
+Thu Apr 19 09:32:47 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * awkgram.y (cur_mbstate) : new varialble containing means current
+ shift state.
+ (cur_char_ring) : new varialbe reffering the buffer which contains
+ last some character from the buffer.
+ (cur_ring_idx) : new variable containing the current index on
+ cur_char_ring.
+ (nextc_is_1stbyte) : new macro, means that last nextc() return a
+ singlebyte character or 1st byte of a multibyte character.
+ (nextc) : check the buffer and update cur_ring_char in multibyte
+ environments.
+ (pushback) : adjust cur_ring_idx in multibyte environments.
+ (yylex) : add check whether nextc() returned 1st-byte in multibyte
+ environments.
+ * re.c (make_regexp) : in multibyte environment, skip multibyte
+ characters when we check special characters.
+
+Wed Apr 18 07:58:20 2001 Isamu Hasegawa <isamu@yamato.ibm.com>
+
+ * awk.h (MBS_SUPPORT) : New flag, means supporting multibyte strings.
+ * configure.in : add check for wchar.h, wctype.h, mbrtowc, and mbrlen.
+
+Wed Jan 16 16:32:40 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_strtonum): Simplified. Check first if the
+ value matches a non-decimal number, and if so convert it.
+ Otherwise do a regular force_number.
+
+Mon Jan 7 22:12:15 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (statement): moved delete, print, and expressions into
+ new non-terminal `simple_stmt'. Allow opt_simple_stmt in the
+ first and third part of a for loop, per latest POSIX, which documents
+ an otherwise undocumented historical oddity in Unix awk. This has
+ the pleasant side effect of making line numbers more accurate for
+ messages involving delete statements.
+ (opt_simple_stmt, simple_stmt): new non-terminals.
+
+ Based on bug report from drj@pobox.com.
+
+Mon Dec 24 14:04:02 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Changes for VMS with new strftime:
+ (AC_HEADER_TIME): added
+ (AC_CHECK_HEADERS): Check for sys/time.h.
+ (TIME_T_IN_SYS_TYPES_H): Add header check.
+ * acconfig.h (TIME_T_IN_SYS_TYPES_H): Added.
+
+Wed Dec 19 16:01:58 2001 Peter J. Farley III <pjfarley@dorsai.org>
+
+ * configure.in: Add MS-DOS to getpgrp special case.
+ * dfa.c, getopt.c, regex.c: Fix code to work with --disable-nls.
+
+Wed Dec 19 15:59:25 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * profile.c (init_profiling_signals) [__DJGPP__]: Use SIGINT
+ instead of SIGHUP and SIGQUIT instead of SIGUSR1.
+
+Tue Dec 18 20:56:07 2001 Andreas Buening <andreas.buening@nexgo.de>
+
+ More OS/2 stuff.
+
+ * awk.h (O_BINARY): Don't redefine for EMX.
+ * io.c (gawk_popen): Add __EMX__ in case compiling DOS executable.
+ * configure.in: Add OS/2 to case for manual GETPGRP_VOID.
+
+Tue Dec 4 17:54:30 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ New configure time option, --with-whiny-user-strftime.
+
+ * configure.in (AC_ARG_WITH): Add appropriate code for autoconf.
+ * accondig.h (USE_INCLUDED_STRFTIME): add #undef for it.
+ * custom.h (USE_INCLUDED_STRFTIME): set things up write.
+
+Tue Dec 4 16:44:07 2001 Andreas Buening <andreas.buening@nexgo.de>
+
+ Mongo patch for updated OS/2 support.
+
+ * awk.h (TOUPPER, TOLOWER): Define only if not already defined.
+ * awkgram.y (extproc feature): Add ifdef for __EMX__.
+ * gawkmisc.c (__EMX__): include pc/gawkmisc.c directly.
+ * io.c (__EMX__): Added for a number of places in addition to OS2 def.
+ (two_way_open): Added OS/2 specific code added that uses spawn.
+ (gawk_popen): ditto.
+
+Mon Dec 3 14:07:56 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix use of getgroups to use dynamic memory, solves
+ problem of systems where NGROUPS_MAX lies.
+
+ * awk.h (groupset, ngroups): New extern variables.
+ * configure.in (AC_CHECK_FUNCS): Add getgroups to list.
+ * io.c (user_open): Use global ngroups and groupset variables,
+ don't call getgroups here.
+ * main.c (init_groupset): New function to init global
+ vars using malloc. Declare it at top.
+ (main): Call init_groupset().
+ (load_procinfo): Use global ngroups and groupset variables.
+
+Sun Nov 18 11:56:01 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.c (srandomdev): ifdef-out. Lots of compile time
+ problems on multiple platforms, and gawk doesn't even
+ use the routine. The heck with fine-grained solutions.
+
+Wed Nov 14 16:12:40 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * builtin.c (bchunk_one): Use `ofre < 1' instead of `ofre <= 0'
+ to avoid compiler complaint about suspicious comparison for
+ unsigned variable. (`ofre == 0' ought to suffice...)
+
+Tue Nov 13 17:27:52 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yyerror): Fix the code to behave like it
+ used to. Keep "no arbitrary limits" by mallocing the
+ buffer and freeing it.
+
+Wed Nov 7 16:46:20 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yyerror): Remove dependency upon buf[] to
+ hold prepended space and `^' pointer. Avoids core dumps
+ for long source lines.
+
+Sat Nov 3 22:27:21 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * m4/strtod.m4: Add missing `#endif'. Oops.
+
+Mon Oct 29 14:53:57 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Add semicolons in calls to count_args().
+ Apparently bisoon adds a semicolon to each body
+ automatically and byacc doesn't.
+
+Sun Oct 28 16:53:18 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Fix off-by-one error in "ran out
+ for this one" diagnostic. Also fix lint check for too many
+ arguments vs. count in format string.
+
+Wed Oct 10 11:01:47 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fixvers: Check that files exist before doing `cmp', in
+ case they're in a source code system and aren't there.
+ Fix from Grant Erickson (gerickson@brocade.com).
+
+Thu Oct 4 18:20:36 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_tree_eval): For comparison, dupnode() results of
+ evaluation so that we can hang on to them and avoid memory
+ corruption. Change calls to free_temp() to unref().
+
+Tue Sep 25 15:19:53 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (iop_open): Only call os_close_on_exec() for
+ fd > fileno(stderr).
+
+2001-09-07 Paul Eggert <eggert@twinsun.com>
+
+ * io.c (redirect): When deciding to use the fdopen bug hack,
+ use "__sun" rather than "solaris". No compilers predefine
+ "solaris", but both GCC and Sun C predefine "__sun".
+
+Thu Aug 30 15:17:12 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (copyleft): Use a printf %d for last year of update
+ to avoid translation strings changing when the file
+ is updated from now on. Suggestion from Ulrich Drepper.
+
+Thu Aug 23 14:01:14 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (unary minus production): Add check that value
+ isn't a string. Based on bug report from drj@pobox.com.
+ * profile.c (tree_eval): For node_val, only test NUMBER
+ to see if value is numeric, not NUM|NUMBER.
+
+Thu Aug 16 12:21:28 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in (ALL_LINGUAS): Added `fr' and `tr'.
+ * po/fr.po, po/tr.fo: New files.
+
+2001-08-13 Paul Eggert <eggert@twinsun.com>
+
+ This patch fixes a bug that causes gawk to rewind standard
+ input incorrectly. It also removes all instances of fseek,
+ from the gawk source proper, which should make gawk a bit
+ more portable.
+
+ (The original patch removed off_t & lseek too, but I need
+ that for something else. ADR.)
+
+ * posix/gawkmisc.c (optimal_bufsize):
+ Don't use lseek on the input, because that might change
+ its state. Instead, just check whether it is a regular file.
+ This obviates the need to invoke isatty.
+ (Also, fix a spelling error in the first line of the source.)
+ * pc/gawkmisc.pc, unsupported/atari/gawkmisc.atr: Likewise.
+
+ * awk.h (S_ISREG): Move this macro here ...
+ * io.c (S_ISREG): from here.
+
+ * protos.h (fseek): Remove prototype; no longer used.
+
+Fri Aug 3 13:38:54 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): Change assert test on type to real test
+ to protect against FS[1] = "x" kinds of things. It'd be better
+ to do this in the grammar, but this is easier and just as
+ effective.
+
+ Undid BECAMEARRAY changes of 25 June 2001 in favor of correct code:
+ * eval.c (pop_fcall): Change test and comment for freeing n->vname.
+ (flags2str): removed BECAMEARRAY entry.
+ * awk.h (BECAMEARRAY): Removed define.
+ * array.c (assoc_lookup): Removed setting of BECAMEARRAY flag.
+
+Mon Jul 23 17:33:13 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Handle case where RS = "" and input file
+ is only newlines. See test/onlynl. Bug report by
+ Michel Jouvin <jouvin@lal.in2p3.fr>.
+
+Wed Jul 4 18:34:19 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (assign_val): Don't allow negative values for NF.
+ * field.c (set_NF): Robustify field-freeing code to make sure
+ values are always positive.
+
+Sun Jul 1 19:15:01 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_index): If second string is "", return 1.
+
+Mon Jun 25 19:34:24 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ Further rationalization of treatment of dynamic regexes,
+ so that profiling code works correctly.
+ * awk.h (NODETYPE): New type, Node_dynregex.
+ * awkgram.y (mk_rexp): Use Node_dynregex.
+ * eval.c (nodetypes): Add Node_dynregex.
+ (r_tree_eval): Add Node_dynregex to case for match_op().
+ * profile.c (tree_eval): Add Node_dynregex to case for pp_match_op().
+ (pp_match_op): Handle Node_dynregex, simplify cases for ~ and !~.
+ * re.c (re_update): Add assertion that type is Node_regex when flags
+ indicate CONST.
+
+ New lint warning.
+ * awkgram.y (yylex): Added lint warning that constant with leading
+ zero is treated as octal or hex.
+
+ Generalized code for those who are Strong In The Ways of the Source.
+ * awk.h: New boolean variable.
+ * main.c (main): set it.
+ * eval.c (interpret): For arrays, check it. Remove variable 'first',
+ not needed anymore.
+ * profile.c (pp_string_fp): Enable printing of non-ascii characters
+ verbatim if variable set.
+
+ Fix memory corruption on SCO for array vars as params changed globally.
+ * awk.h (BECAMEARRAY): new flag.
+ * array.c (assoc_lookup): set the flag as appropriate.
+ * eval.c (flags2str): Add the flag.
+ (pop_fcall): Check the flag, don't free memory if set.
+
+Wed Jun 13 18:07:06 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (fmt_index): Actually call erealloc() to grow fmt_list
+ if that's really necessary. Bug report from David Jones,
+ djones@zoonami.com.
+
+Sun Jun 10 14:24:48 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_match_op): Rationalized the code.
+
+Thu Jun 7 11:54:36 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (O_BINARY): Don't define if already defined
+ (as is true for cygwin/gcc --- oops).
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Wed Apr 25 11:44:07 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (AM_MAKEFLAGS): Add definition per advice from
+ Nelson Beebe.
+
+Tue Apr 24 14:28:00 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * io.c (devopen): Patch from Jeurgen to robustify pulling
+ out hostname, port numbers, etc, to avoid any buffer overrun
+ problems.
+
+Mon Apr 23 10:26:38 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Fix grammar so that `print ... |& ".." |& getline'
+ dies with a parse-time error message.
+
+Sun Apr 22 16:46:48 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * io.c (socketopen): Fix from Juergen in recursive call.
+
+Thu Apr 19 18:39:20 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * awk.h: Really fix logic around include of <sys/types.h>.
+
+ * awk.h (callresult): New name for `result' macro.
+ * eval.c (r_get_lhs, case Node_builtin): Use it.
+
+Thu Apr 19 16:31:09 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * io.c: Move code around to allow compilation with DEC C.
+
+Thu Apr 19 16:21:56 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.h: Move decl of random() here.
+ * random.c: Remove decl of random().
+
+Mon Apr 9 11:41:58 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (dfainit): Initialize more members in the structure,
+ based on bug report in bug.gnu.utils by aaronl@vitelus.com
+ (Aaron Lehmann).
+ * awk.h: Fix logic around include of <sys/types.h>.
+
+Thu Apr 5 20:12:05 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * dfa.c: for VMS, #include <stddef.h> instead of <sys/types.h>.
+ * missing_d/mktime.c: likewise.
+
+ * random.c: reorder include directives to get gawk config info
+ from random.h sooner.
+ [fcntl.h]: guard #include with HAVE_FCNTL_H test.
+ [unistd.h]: guard #include with HAVE_UNISTD_H test.
+
+ * random.c (srandomdev): skip /dev/urandom usage if O_RDONLY
+ is not defined.
+
+Tue Mar 20 11:07:11 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (function_body): Add opt_nls to end of production.
+
+Tue Mar 20 09:30:32 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * awk.h (BROKEN_STRNCASECMP): Add decl of strcasecmp.
+ * io.c (two_way_open): Add `return FALSE;' for fussy compilers.
+
+Sun Mar 18 15:10:56 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (gawk_pclose): Set the exit value for close correctly
+ if the pipe died with a signal.
+
+Wed Mar 7 11:28:52 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Correctly handle the case of a leading
+ single newline at the front of the file when RS = "".
+
+2001-02-26 Paul Eggert <eggert@twinsun.com>
+
+ * COPYING: Incorporate latest version from FSF, which fixes a Y2k bug.
+
+ * builtin.c (do_mktime): Allow the user to specify the
+ tm_isdst member as an optional trailing integer, and to
+ specify "out-of-range" members. Check for overflow when
+ subtracting 1 from month or 1900 from year. Allow years just
+ past INT_MAX, as they work on some hosts when INT_MAX - 1900
+ is representable as an int.
+
+ * doc/gawk.1, doc/gawk.texi: Document the above changes.
+ Also, document that the origin-zero Gregorian calendar is used.
+ Fix confusing wording about "midnight" by replacing it with 00:00
+ ("midnight" is also 24:00, the end of the day).
+ Mention the typical range for time stamps.
+ Do not assume that years are nonnegative and are less than 10,000.
+ Suggest TZ=UTC0 instead of TZ=GMT0, as that's how recent versions
+ of GNU date behave.
+ GMT is not always the time of day in Greenwich these days.
+ Fix typos: "Emporer/Era", "1980's", "1970's".
+
+ * m4/largefile.m4: Synchronized with latest version.
+
+Tue Feb 27 12:10:11 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_in_array): Change test to tree->type == Node_expression_list.
+
+Wed Feb 7 14:46:50 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (LEX_FOR): Allow newline after `;' in for loops.
+ Per bug report from Brian Kernighan, bwk@research.bell-labs.com.
+
+Tue Feb 6 18:35:27 2001 Martin C. Brown <mc@whoever.com>
+
+ * io.c (socket_open): Conditionalize various options based on
+ ifdef. Needed for BeOS port.
+
+Tue Feb 6 18:17:13 2001 Michal Jaegermann <michal@ellpspace.math.ualberta.ca>
+
+ * regex.c (re_match_2_internal): Case maybe_pop_jump, for
+ charset and not_charset: change cast from (unsigned char)
+ to (unsigned). Catches last 8 chars with high bit set
+ if backtracking. See test/rebt8b1.awk, test/rebt8b2.awk.
+
+Tue Feb 6 11:20:21 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ Have `for (iggy in foo)' save the elements and loop over them.
+ Make sorted for loops a dynamic test instead of a compile time test.
+ Still requires being Strong In The Ways Of The Source.
+
+ * awk.h: (struct search): removed.
+ (assoc_scan, assoc_next): removed declarations.
+ * array.c (assoc_scan, assoc_next): removed functions.
+ * eval.c (interpret): remove Node_K_array_sorted_for. Change code
+ at Node_K_arrayfor.
+ (nodetypes): remove Node_K_array_sorted_for.
+ * configure.in: removed array sorting test.
+ * awkgram.y: removed sorted_in keyword and associated code.
+
+Sun Feb 4 14:57:49 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (interpret): use tree->rnode->exec_count to hold count of
+ times if was true.
+ profile.c (interpret): ditto.
+ * main.c (pre_assign): gross hack. malloc fresh copy of assign so can
+ clear the '=', otherwise screws up profiling print out.
+
+Sun Jan 28 16:16:02 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ Per request from Nelson Beebe, SIGHUP to pgawk dumps profile
+ and function call stack and exits, SIGUSR1 dumps and continues
+ running.
+
+ * eval.c (dump_fcall_stack): New function, dumps awk function call
+ stack.
+ * awk.h (dump_fcall_stack): Add declaration.
+ (init_profiling_signals): Ditto.
+ * main.c (main): Call init_profiling_signals.
+ * profile.c (init_profiling_signals, dump_and_exit, just_dump): new
+ functions.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * io.c (gawk_popen): Restore the mode of stdin before running the
+ child process and switch it back if BINMODE is in effect after the
+ child returns.
+ (redirect): Restore the mode of stdin before running the child
+ process.
+ (close_redir): Switch mode of stdin back to binary if BINMODE is
+ in effect, after the child returns.
+
+ * builtin.c (do_system): Restore the mode of stdin before running
+ the child process and switch it back if BINMODE is in effect after
+ the child returns.
+
+ * awk.h (os_restore_mode): Add prototype.
+
+Thu Jan 18 14:03:06 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h, README_d/README.ultrix: Fixes for Ultrix
+ from Juergen Kahrs.
+
+Wed Jan 17 11:03:40 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * io.c (redirect) [F_GETFL && O_APPEND]: Use binmode in the call
+ to fdopen.
+
+Mon Jan 15 16:29:52 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (prec_level): Made Node_K_getline higher than <
+ but lower than others. Allows use of getline with redirection
+ inside an if.
+
+Wed Jan 10 15:35:06 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (set_BINMODE): Rationalized string assignment.
+
+Sun Jan 7 15:26:16 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.h: Removed names in prototypes for getopt_long
+ and getopt_long_only, fixes problems on MINGW32.
+
+Thu Jan 4 10:13:46 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Add check for mcheck.h
+ * main.c: Include mcheck.h if have it.
+ (main): If TIDYMEM turned on in environment, also call mtrace().
+
+Wed Jan 3 16:41:33 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fixed minor memory leaks.
+ * re.c (re_update): When IGNORECASE changed, unref(t->re_text).
+ * eval.c (pop_fcall): Fix the logic to correctly free the vname
+ when copying array args back to their underlying source.
+
+ Fixed massive memory leaks.
+ * node.c (dupnode): If PERM is set, do nothing.
+ (unref): Fix logic. Always turn off TEMP. Check just for MALLOC
+ when incrementing the stref.
+ * array.c (assoc_lookup): Turn off PERM also when saving subscript.
+ * builtin.c (sub_common): Turn off PERM also when making private copy
+ of string.
+
+ Add a minor memory cleanup facility (undocumented):
+ * awk.h (do_tidy_mem, release_all_vars): Add declarations.
+ * main.c (do_tidy_mem): Add declaration.
+ (main): if $TIDYMEM exists, do_tidy_mem is true, and call mtrace().
+ * awkgram.y (release_all_vars): New function.
+
+Sun Dec 31 10:47:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (in_end_rule): Renamed `parsing_end_rule' to avoid
+ conflict with global var of same name.
+
+Sun Dec 24 10:36:54 2000 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * awkgram.y (snode): Reword the error message about the number of
+ arguments for a builtin, so as not to use the English `s' as a
+ plural suffix.
+
+Tue Dec 12 08:38:03 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ext.c (do_ext): ifdef out use of `dummy'. Duh.
+ * regex.c (re_error_msgid): Revert to array of `char *' so that can
+ compile on K&R compilers. Fix all uses appropriately.
+ (re_error_msgid_idx): Removed.
+
+Fri Dec 8 11:47:26 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ext.c (dummy): Make gcc specific via ifdef.
+ * builtin.c (do_dcgettext): make conditional compilation smarter.
+ * msg.c (warning, error, r_fatal): Finish switching back to
+ multi-version function header.
+
+Wed Dec 6 13:28:58 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.h: include <config.h> to get ssize_t definition.
+ * awkgram.y (yyerror): Restore multi-version function header,
+ it seems that what ansi2knr produces doesn't quite do the
+ job on old compilers.
+ msg.c (msg): Ditto.
+
+Tue Dec 5 15:05:35 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in (AC_C_INLINE): Added macro call.
+ * Makefile.am (LN): Define it for install hooks.
+
+Sun Dec 3 17:28:53 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (os_setbinmode): Declare new function.
+ (setmode): Remove definition: conflicts with MacOS X.
+ * main.c (main): Change call of setmode to os_setbindmode.
+
+ * builtin.c (do_dcgettext): Improve ifdef for code, fixes MacOS X.
+ * custom.h (__APPLE__): Force definition of HAVE_MKTIME, won't
+ link otherwise. Harumph.
+
+Sun Nov 26 11:58:52 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_dcgettext, do_bindtextdomain): Add calls to
+ free_temp the various arguments. Sigh.
+ * io.c (yylex): nuked bstart variable, put all uses of mend variable
+ into TANDEM ifdef.
+ * main.c (load_environ): removed cp variable, value never used.
+ * random.c: Remvoed uses of `inline' keyword.
+ * Makefile.am (install-exec-hook, uninstall-local): new targets.
+ Adds creation of gawk-X.Y.Z and awk links, as in 3.0.x.
+ * configure.in (GAWK_AC_TYPE_SSIZE_T): Added.
+ m4/ssize_t.m4: new file.
+
+Wed Nov 22 14:47:18 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ After consultation with Brian Kernighan and Michael Brennan,
+ nuked the abort keyword.
+
+ * awk.h (Node_K_abort): removed.
+ * eval.c (aborting): removed decl.
+ (interpret): Removed Node_K_abort case.
+ * io.c (do_input): Removed checks for aborting.
+ * main.c (aborting): removed.
+ (main): Removed checks for aborting.
+ * profile.c (pprint): Removed Node_K_abort case.
+ * awk.y (LEX_ABORT): All stuff removed.
+
+Wed Nov 22 10:45:57 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ext.c (dummy): Move inside #ifdef DYNAMIC. Helps on
+ PCs and other platforms that don't do dynamic loading.
+ * awk.h (RED_TCP): New flag, means use shutdown.
+ io.c (redflags2str): Add RED_TCP.
+ (SHUT_RD, SHUT_WR, SHUT_RDWR): Add conditional defines.
+ (redirect): Add RED_TCP to tflag if appropriate. Add more
+ #ifdef HAVE_SOCKETS as needed.
+ (close_redir): If RED_TCP set, shutdown(2) on each end of the socket.
+
+Tue Nov 21 16:25:41 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y: for (iggy in foo) loops: add test that index
+ in delete statement is a simple variable.
+
+Tue Nov 14 16:11:39 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: Add appropriate conditional versions of the gettext
+ functions if we don't have <libintl.h> or if ENABLE_NLS
+ is not defined or zero.
+ * configure.in: Add check for libintl.h header.
+
+ From Scott Deifik for PCs.
+ * awk.h (lintwarn): Call set_loc unconditionally, makes
+ compilation work on PCs.
+ * builtin.c (do_dcgettext): Compile out cat_tab and code
+ if not ENABLE_NLS.
+ * ext.c: for MSC, no long long variable.
+ * random.c: use clock() instead of gettimeofday().
+ * builtin.c: Fixed prototypes for new random functions (ADR).
+
+Sun Nov 12 17:45:44 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (parse_next_arg): Fix call to >= num_args so
+ running out of args check is correct, instead of core dumping.
+ (format_tree): Save and restore `the_args' and `args_size'
+ if a nested call is in progress, see explanatory comment.
+ See also tests/addcomma.
+ * Makefile.am: Fix things so that gawk/pgawk built first,
+ even if `make check' called before make. Add some
+ commentary.
+
+Wed Nov 8 14:39:20 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: Only add -rdynamic for linux.
+ * dfa.h, dfa.c: upgraded to versions in grep 2.4.2.
+
+Tue Nov 7 18:17:17 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * All: Switched to ANSI function headers and added
+ `ansi2knr' automake option. Really cool.
+
+Tue Nov 7 16:57:49 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect): Check for O_APPEND in flags when doing
+ fdopen() of /dev/fd/N. Thanks to bug report from
+ "John H. DuBois III" <spcecdt@armory.com>.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (os_is_setuid): declare function.
+ * main.c (main): call it if do_lint and warn if true.
+ * awkgram.y (tokentab):
+ - Made sure all extensions are actually marked as such. Ouch.
+ - Changed "sort" to "asort". Potential to break too much old code.
+ * getopt.h, getopt.c, getopt1.c: replaced with current versions
+ from glibc CVS archive.
+
+Mon Nov 6 18:14:33 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * random.c: Replaced with recent version from FreeBSD.
+
+Mon Nov 6 15:37:12 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ Major simplification of automake machinery.
+
+ * configure.in:
+ - INSTALL is forced only if not provided in environment
+ - lots of Makefile.in files removed since move to automake 1.4a
+ * Makefile.am, */Makefile.am: Moved directories that don't need
+ the automake machinery into EXTRA_DIST as appropriate and
+ removed the Makefile{,.am,.in} files as needed.
+ * eval_p.c, profile_p.c: New files to make it easier with automake
+ to compile pgawk.
+
+Tue Oct 24 12:20:18 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (valinfo, var_comp, dump_vars): New functions to dump
+ the list of global variables.
+ * awk.h: Declare dump_vars.
+ * main.c (optab): new option "dump-variables".
+ (main): Code to handle it, set the output file and then call
+ dump_vars() at the end.
+ (usage): New option added to usage message.
+
+Sat Oct 21 22:59:59 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (parms_shadow): For a function, check if any
+ parameters shadow global variables and print a warning.
+ (shadow_funcs): Go through all functions and call parms_shadow().
+ (isnoeffect, isassignable): Add Node_LINT and NODE_BINMODE.
+ * main.c (main): If do_lint, call shadow_funcs().
+ * awk.h: add declaration of shadow_funcs().
+ * configure.in: added m4/Makefile and awklib/eg/network/Makefile
+ to list of generated makefiles.
+
+Tue Oct 17 10:47:35 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): Reverted change that did dupnode of
+ array indices. Creates significant problems if index is
+ numeric value and CONVFMT changes. Added fix to set
+ bucket->ahname->stfmt to -1 so that force_string never recalculates
+ the string value, and also turned off NUM and turned on STR.
+ See test/arynasty.awk.
+
+Mon Oct 16 12:21:26 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * All: Cleaned up various lint warnings for consistent phrasing.
+ * awk.y (in_end_rule): New variable for warning about unredirected
+ getline. It's ok in a BEGIN, but not in an END.
+
+Sun Oct 15 14:14:05 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (set_FS): Add lint warning for FS = "".
+ (do_split): Ditto for 3rd arg = "".
+
+Fri Oct 13 09:17:04 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (close_redir): Clear rp->fp on all closes. Remove
+ rp from list if either closing both ends or both ends
+ have been closed separately. Add exitwarn message for
+ co-process.
+ (flush_io): Add warning message if fflush of co-process
+ fails. Rationalize return value to either 0 or -1.
+ * builtin.c (do_gensub): 3rd arg of zero generates a
+ warning.
+ (do_fflush): rationalize return value: -1 for unopen or read-only
+ redirection, status of fflush otherwise.
+
+Wed Oct 11 22:11:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y (for loop): Check that there is a body as
+ part of the `is it a delete statement' check.
+
+Thu Oct 5 11:56:42 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h, awkgram.y, configure.in, eval.c: enabled
+ `for (i in_sorted array)' loops for those who
+ are Strong In The Way Of The Source. So there.
+
+Mon Oct 2 10:09:32 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_close): make close(x) for non-open x return -1
+ and update ERRNO. close(FILENAME) no longer does anything
+ magic; this is all for better consistency with other awks
+ and is more logical, anyway.
+
+Thu Sep 28 17:27:16 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (close_one): Added a lint warning if it becomes
+ necessary to start multiplexing fd's, per ancient suggestion
+ from Scott Deifik, <scottd@amgen.com>.
+
+Tue Sep 26 14:41:41 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c: Move enum for redirection placement to top
+ of file, and make the value a parameter to pp_redir.
+ Fix all the calls. This gets `|&' right everywhere.
+
+Sun Sep 24 16:38:04 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (freenode): set the flags straight to UNINITIALIZED.
+ * node.c (unref): Fix test for MALLOC|TEMP to test the
+ actual flags, not zero.
+ * builtin.c (format_tree): ala print and concat, dupnode
+ the temp nodes from tree_evaling the arguments. See
+ test/nasty2.awk.
+
+Mon Sep 18 10:16:58 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (snode): Make match 3rd arg and close 2nd arg fatal
+ errors if --tradtional.
+
+Thu Sep 14 12:22:42 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (update_ERRNO): Call gettext on result of strerror.
+ i18n rules.
+
+Wed Sep 13 14:56:11 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_tree_eval): Case for Node_concat. Dupnode the
+ strings ala do_print to get more consistent results.
+ Compare gawk 3.0.6 to nawk/mawk on test/nasty.awk.
+ Thanks to Andrew Sumner (andrewsumner@yahoo.com) for
+ pointing this one out.
+
+Wed Sep 13 10:06:47 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (two_way_close_type): New enumerated type.
+ (close_redir): New third param of type two_way_close_type.
+ Add smarts to two-way case for different close types.
+ Only remove it from the redir list if closing is for both ends.
+ (gawk_pclose): Check that rp->iop != NULL before closing,
+ all three versions.
+ * awkgram.y (tokentab): Allow 2nd argument to close.
+ (snode): Add lint warning.
+
+Sun Sep 10 14:16:10 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (set_FIELDWIDTHS): Generate a fatal error upon
+ encountering a negative width.
+
+Sun Sep 10 10:37:35 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (snode): If first argument to dcgettext is a
+ string constant and --gen-po, dump the string constant to
+ the .po file too.
+ * main.c (nostalgia): Add call to fflush(stderr).
+ * eval.c (r_tree_eval): Add entries for Node_LINT and for
+ NODE_TEXTDOMAIN.
+
+Thu Sep 7 10:46:20 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_dcgettext): Per suggestion from Ulrich Drepper,
+ make the awk interface:
+
+ str = dcgettext(string [, domain [, category]])
+
+Wed Sep 6 16:28:12 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ Bring gettext features out to the awk level!
+
+ * awk.h: Add declarations of new functions `do_dcgettext'
+ `do_bindtextdomain', `set_TEXTDOMAIN' and variables
+ `TEXTDOMAIN', `TEXTDOMAIN_node'. New NODETYPE enum
+ `Node_TEXTDOMAIN'.
+ * eval.c (nodetypes): add Node_TEXTDOMAIN at end.
+ (set_TEXTDOMAIN): new function.
+ (r_get_lhs): add case for Node_TEXTDOMAIN.
+ * main.c (varinit): add entry for TEXTDOMAIN.
+ * node.c (format_val): If INTLSTR use dcgettext of string
+ and TEXTDOMAIN.
+ * awkgram.y (tokentab): Add entries for "dcgettext" and
+ "bindtextdomain".
+ * builtin.c (do_dcgettext, do_bindtextdomain): new functions.
+
+Tue Sep 5 17:01:34 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_string_fp): Use lower case versions of
+ isascii and isprint to avoid printing high-bit-set
+ characters. Make it smarter to break strings at 70
+ chars or after embedded newline, for --gen-po.
+ Fix the calls to it everywhere for new boolean option
+ to yes/no break lines.
+ * m4/strtod.m4: new file, defines GAWK_AC_FUNC_STRTOD_C89.
+ * configure.in: GAWK_AC_FUNC_STRTOD_C89 call added
+ * acinclude.m4: include strtod.m4.
+ * acconfig.h: add entry for STRTOD_NOT_C89.
+ Remove entries for BITOPS and NON_DEC_DATA.
+ * missing/missing.c: add check for STRTOD_NOT_C89, use ours
+ if set.
+ * missing/strtod.c: make smarter for input like 0x345.
+ * awk.h: [STRTOD_NOT_C89]: define strtod gawk_strtod to get
+ our version. Avoids linker weirdness.
+
+Mon Sep 4 09:16:43 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (set_record): fix from Utz-Uwe Haus
+ <haus@saturn.Math.Uni-Magdeburg.DE> to make sure there's
+ always enough room in the record.
+ * builtin.c (nondec2awknum): Fix octal conversions to exit
+ when hitting a non-digit, and not go to decimal. Make
+ check for non-octal better. Based on bug report from
+ Morris_Lee@tvratings.com.
+
+Sun Sep 3 13:52:11 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Allow positional parameters for
+ %*.* kinds of things.
+
+ Made octal/hex constants and strtonum on by default. Made
+ --enable-non-decimal-data a runtime switch `--non-decimal-data'.
+
+ * configure.in: Removed AC_ARG_ENABLE for --enable-bitops and
+ --enable-non-decimal-data.
+ In .developing check, remove the AC_DEFINEs.
+ * awk.h: Decls for bitwise functions now there by default.
+ Add decl of `do_non_decimal_data'.
+ * main.c (do_non_decimal_data): new variable
+ (optlist): add new entry for `--non-decimal-data'.
+ (main): turn off `do_non_decimal_data' if `do_traditional'.
+ (usage): add the new option.
+ * node.c (r_force_number): make check for non-decimal data a
+ runtime check based on do_non_decimal_data.
+ * awkgram.y (yylex): make non-decimal constants a runtime check.
+ * builtin.c: remove the ifdefs around the bit functions and
+ nondec2awknum.
+
+Tue Aug 29 18:45:56 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: go back to ARRAYDEBUG if .developing set.
+ * awkgram.y: use ARRAYDEBUG for adump(), use multiple tests
+ for stopme().
+
+Mon Aug 28 17:09:06 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (do_split): Add check for first arg is null string,
+ if so, skip the work and return zero.
+
+Mon Aug 14 23:01:55 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Add %COUNT$... handling to printf.
+ awk.h (printf_count): new define in NODE structure.
+ (format_tree): added decl.
+ awkgram.y (count_args): new function to set printf_count in
+ a node.
+ [print productions]: call the function.
+ (snode): for do_sprintf, call count_args, set the count
+ in the lnode.
+ builtin.c (format_tree): new fourth arg is argument count.
+ Add smarts to handle the `$' in a format.
+ (do_sprintf): use new argument to format_tree.
+ node.c (format_val): ditto.
+
+Sun Aug 13 11:10:41 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ Changes from Alan J. Broder (ajb@woti.com):
+ - Array third arg to match puts subtexts into the array:
+ * awk.y (tokentab): "match" gets third arg, and lint warning
+ * builtin.c (do_match): if third arg there, fill it with subtexts
+ - New builtin sort function:
+ * awk.h (do_sort): declared.
+ * array.c (do_sort, dup_table, merge, merge_sort, assoc_from_list,
+ assoc_sort_inplace): new functions.
+
+ * eval.c (tree_eval): in debug code, make uninitialized var
+ a warning, not a fatal error. Breaks too many things.
+
+Wed Aug 9 10:51:41 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (func_call): Increment the exec_count on the
+ function's node; this allows printing a call count for
+ functions.
+ profile.c (pp_func): print the count for functions.
+ * ALL: Changed DEBUG to GAWKDEBUG in all gawk files, so that
+ I don't get regex/dfa debugging. In some cases, changed
+ memory-related stuff to MEMDEBUG. Still have work to do.
+ * awk.h, node.c, profile.c: removed exec_count_init variable;
+ code has been cleaned up to not need different values for
+ profiling/not profiling.
+
+Thu Jul 5 21:10:59 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (casetable): Removed the USE_PURE_ASCII stuff; it
+ was never documented. Latin 1 forever.
+ * main.c (main): only call `init_profiling' after arg parsing
+ if `do_profiling' is still false. Avoids resetting `prof_fp'
+ back to stderr.
+
+2000-02-17 Akim Demaille <akim@epita.fr>
+
+ * m4: New directory.
+ * acinclude.m4: Removed, replaced by m4/*.m4.
+ * Makefile.am: Adjusted.
+ Added ACLOCAL_AMFLAGS.
+ * configure.in Adjusted.
+ Use AC_SYS_LARGEFILE not GAWK_AC_SYS_LARGEFILE, jm_FUNC_MKTIME,
+ not GAWK_FUNC_MKTIME.
+ * acconfig.h: Removed _FILE_OFFSET_BITS, _LARGEFILE_SOURCE and
+ _LARGE_FILES now templated by m4/largefile.m4.
+
+2000-02-15 Arnold Robbins <arnold@skeeve.com>
+
+ * MOVED TO AUTOMAKE AND GETTEXT.
+ Just about every file touched. Work done by Arno Peters.
+
+Sun Jan 2 14:48:23 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ First edit of the new millenium!
+ * awk.y (yylex): if lint checking, be obnoxious about gotos.
+
+Mon Oct 25 19:12:02 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: remove C_ALLOCA ifdef.
+ * main.c (main): remove C_ALLOCA code.
+ * io.c (do_input): ditto.
+
+Mon Aug 9 17:36:24 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bisonfix.sed: unconditionally #undef YYSTACK_USE_ALLOCA.
+ * configure.in: remove all alloca and ALLOCA related stuff.
+ * Makefile.in: ditto
+
+Thu Jul 29 18:32:05 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (NODE): exec_count now in #ifndef NO_PROFILING.
+ * Makefile.in: changes to only recompile eval.c and profile.c to a
+ special version for profiling.
+ * custom.h [MSC_VER]: turn on NO_PROFILING to omit the exec_count
+ and save space.
+ * node.c (more_nodes): move setting of exec_count to
+ #ifndef NO_PROFILING.
+
+Thu Jul 1 12:12:05 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in (AC_PREREQ): update to 2.13.
+ GAWK_AC_C_STRINGIZE: convert to AC_C_STRINGIZE.
+ * aclocal.m4 (GAWK_AC_C_STRINGIZE): remove definition, now
+ part of autoconf.
+ * acconfig.h (HAVE_STRINGIZE): ditto.
+
+Wed Apr 28 11:08:05 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): fix call to free_temp(subs) to after
+ last use of subs.
+
+Sun Apr 25 16:48:06 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect): add lint warning when same file is used for
+ > and >>.
+
+Thu Apr 22 15:05:30 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): Fix call to fatal to lintwarn instead.
+ * node.c (r_force_number): Use `0 &&' to disable warnings about
+ conversions: they're overzealous, methinks.
+
+Thu Apr 8 14:27:58 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ New features for profiling:
+ * awk.h (NODE): add `exec_count' member.
+ (freenode): clear `exec_count' upon free.
+ * awk.y (func_count): new variable, counts total number of functions.
+ (func_install): increment func_count.
+ (struct finfo): information for use in sorting functions when
+ pretty printing.
+ (fcompare): compare two finfo structures.
+ (dump_funcs): print the functions in sorted order for profiling.
+ (getfname): return the name of a builtin function.
+ * eval.c (INCREMENT): new macro for counting execution of nodes.
+ (interpret): call INCREMENT() appropriately.
+ * main.c (do_profiling): new flag if doing profiling.
+ `--profiling': new option added to getopt_long machinery.
+ (main): For profiled version, set do_profile and output file.
+ Call `dump_prog' and `dump_funcs' if do_profiling at end.
+ (usage): add new argument.
+ * node.c (more_nodes, freenode): set exec_count to zero.
+ * profile.c: new file, does pretty printing and prints counts.
+ * Makefile.in: update to create two versions of gawk, regular
+ and `pgawk' which does profiling.
+
+Wed Mar 10 21:38:14 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (close_redir): use update_ERRNO() instead of manually
+ doing it.
+
+Mon Dec 21 15:58:21 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: add BeOS to list of cases where we hardwire
+ GETPGRP_VOID.
+ custom.h: remove the #define from __be_os case. Cleaner to
+ do it all in configure. Based on email from Martin C. Brown,
+ mc@whoever.com.
+
+Mon Nov 30 20:52:52 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (update_ERRNO): new function, mainly for use by
+ extension functions.
+ * awk.h: add decl.
+
+Tue Nov 24 18:13:29 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Changes based on submission from Christos Zoulas at D.E. Shaw
+ that adds the following features:
+ - checking for use of uninitialized variables
+ - checking if a string that's not a number converts to 0
+ - ability to load a dynamic library to add built-ins
+ - VERSION variable (may or may not stay)
+ Additional change:
+ - --lint=fatal makes lint errors become fatal
+ - LINT="fatal" has the same effect, any other positive
+ value makes lint errors be just warnings
+ * Makefile.in (includedir): new variable for gawk header files
+ (ext.c, ext.o): new source and object files
+ (OTHERS, extension): new directory for macro with example extension
+ (install): install header files
+ * acconfig.h (DYNAMIC): new macro, true if can do dynamic loading
+ * array.c (assoc_lookup): new parameter `reference' is true if we
+ want to do reference checking. Add appropriate reference checking
+ code.
+ * awk.h (UNITITIALIZED): new flag
+ (lintfunc): function pointer for correct function to use
+ (lintwarn): new macro to produce warnings
+ (result): new macro for func call result, used in commented out
+ code in eval.c.
+ (getnode, freenode): revised to set UNINITIALIZED.
+ (get_lhs): third arg for reference checking, change all calls
+ -- Add appropriate decls of new/changed functions
+ * awk.y (tokentab): new builtin "extension" for adding extensions
+ (node_common): set flags to UNINITIALIZED for Node_var.
+ * configure.in (dynamic linking): new check. Probably should
+ be a separate macro.
+ * eval.c (flag2str): add UNINITIALIZED to the table.
+ (r_tree_eval): add checks for UNINITIALIZED.
+ (push_args): appropriate changes for UNINITIALIZED to work.
+ (r_get_lhs): new third argument for reference checking.
+ (set_LINT): add code to handle setting `lintfunc' appropriately.
+ * ext.c: new file, for doing dynamic library extensions.
+ * extension/*: new directory with simple example code.
+ * main.c (VERSION_node, EXTENSION_node): new nodes for new vars.
+ (optab): change for "lint" to allow optional argument.
+ (lintfunc): definition.
+ (main): add case in option processing for --lint.
+ (varinit): add entries for VERSION and EXTENSION.
+ * node.c (r_force_number): checks that string really is a number.
+ (morenodes): set UNITIALIZED in the flags.
+ * re.c (all): change `result' to `res' globally to avoid conflict
+ with new macro.
+ * GLOBAL: change lint calls to warning() to lintwarn().
+ * GLOBAL: change all calls to get_lhs() to have 3rd arg.
+ * GLOBAL: change all calls to assoc_lookup() to have 3rd arg.
+
+Sun Nov 22 17:07:39 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * patchlev.h: renamed from patchlevel.h to make life
+ easier for the PC guys.
+ (main.c): changed to include patchlev.h.
+ (Makefile.in): changed to ref patchlev.h where needed.
+
+Sat Nov 7 21:29:52 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_get_lhs): case Node_field_spec. Fix the lint
+ warnings for field reference of null string or non-numeric value.
+ When turned on, $0 generated a warning! Oops.
+
+Thu Nov 5 16:58:38 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (init_fds): new function to pre-open 0, 1, and 2 on
+ /dev/null if they're not open. Robustness, more or less.
+ (main): call init_fds.
+ * io.c (str2mode): add smarts for two-letter strings
+ such as "rw", "r+", "wr", "w+" and "a+".
+
+Mon Nov 2 16:55:46 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_*): added lint checks for non-numeric
+ and/or non-string arguments, as appropriate. This should
+ have been done long ago.
+
+Tue Oct 20 21:56:06 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (LINT_node): new variable for LINT special var
+ (Node_LINT): new node type.
+ (set_LINT): declare function.
+ * main.c (varinit): add LINT variable.
+ (usage): print an emphatic pointer to the manual for bug reports.
+ * eval.c (nodetypes): new entry for Node_LINT.
+ (r_get_lhs): case added for Node_LINT.
+ (set_LINT): set do_lint from LINT variable.
+
+Mon Oct 19 22:35:46 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: for GCC, add -Wall to get warnings for development.
+ * Makefile.in (awktab.c): move sed stuff to separate script.
+ * bisonfix.sed: new script, with old fix and Solaris x86 fix.
+ * awk.h (nodetype2str): add declaration.
+ (load_procinfo): add declaration.
+
+Tue Oct 13 22:28:56 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Changes to make PROCINFO["FS"] reflect the use of FIELDWIDTHS or FS.
+ eval.c (assign_val): new function that does the mechanics of
+ assignment
+ main.c (load_procinfo): add setting of PROCINFO["FS"] to "FS".
+ field.c (update_PROCINFO): new function to update the array.
+ (set_FS): call update_PROCINFO.
+ (set_FIELDWIDTHS): ditto.
+
+Sun Sep 27 10:18:05 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (reisstring): new prototype.
+ * re.c (reisstring): new function, returns true if the re did
+ a simple string match. This is rather simplistic in its logic.
+ * io.c (get_a_record): in the case that RS is a regexp, AND
+ the re matched at the exact end of the buffer, add a call to
+ `reisstring' in case it's a simple string match. If so, we
+ don't need to read more into the buffer because we don't
+ have a regex like `x.*y' that might extend longer.
+ This should be very helpful for interactive /inet clients
+ where something like `RS = "\r\n"' happens.
+
+Thu Aug 13 22:07:40 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (socketopen): fixes from Juergen Kahrs to socket
+ opening code for "any host".
+
+Tue Jul 14 19:02:33 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * aclocal.m4 (GAWK_AC_LIB_SOCKETS): removed the caching;
+ configure gave different results the second time it was run!
+
+Fri Jul 10 09:11:06 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (interpret): minor cleanups: add variable name to
+ fatal error Node_K_array_for and other minor changes.
+
+Mon Jun 22 16:53:34 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (tags, TAGS): add $(LIBSRC).
+
+Tue Jun 2 15:23:05 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (devopen): relax previous change, don't require "any",
+ just that a port be there. The user can put 0 if they
+ don't care.
+
+Wed May 27 21:33:45 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (devopen): for /inet, require that local and remote
+ ports and the remote hostname be there, and that `any'
+ be used for a port if they don't care.
+
+Thu May 21 14:13:46 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (parse_escape): Add warning that is always on
+ for \q for any unknown q inside string or regex constant.
+ I got bit by this myself once too often. Or else I'm
+ just getting old and senile.
+
+Mon May 4 12:42:49 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (NODETYPE): Sorted the Node_xxx entries for the
+ builtin variables. Gotta look nice, don't we?
+ * eval.c (nodetypes): ditto.
+ (genflags2str): added code to check that we don't
+ overflow the static buffer. This is just a debugging
+ routine, not worth the hassle of dynamic allocation.
+
+Mon Mar 2 16:06:16 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (dist): remove any embedded copied RCS or CVS
+ directories.
+
+Mon Feb 23 00:09:52 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (genflags2str): add declaration.
+ * eval.c (genflags2str): new function.
+ (flags2str): use new general purpose function.
+ * io.c (redflags2str): same.
+
+Sun Feb 22 23:57:29 1998 Arnold D. Robbins <arnold@skeeve.com>
+
+ Significant changes to add two-way i/o and sockets!!!
+
+ * Makefile.in: add @SOCKET_LIBS@ to LIBS variable.
+ * acconfig.h: add HAVE_SOCKETS and HAVE_PORTALS defs.
+ * aclocal.m4: new macro GAWK_AC_LIB_SOCKETS.
+ * awk.h: new node type, Node_redirect_twoway, and new redirection
+ flags: RED_TWOWAY, and RED_SOCKET.
+ * awk.y (parser): add TWOWAYIO token and appropriate productions.
+ (yylex): recognize `|&' token if not traditional.
+ * builtin.c (do_print, do_printf): flush buffer if TWOWAYIO.
+ * configure.in: add header checks for networking header files,
+ add --enable-portals switch, call GAWK_AC_LIB_SOCKETS
+ * eval.c (nodetypes): add string constant for Node_redirect_twoway.
+ * io.c (redflags2str): new function.
+ (redirect): better error message in default case, add code for
+ Node_redirect_twoway.
+ (socketopen): new function.
+ (iop_open, devopen): add recognition of `/inet/...'.
+ (two_way_open): new function.
+
+Sat Dec 13 21:15:07 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (struct node): new member, `param_list' in union `x', becomes
+ `node->parmlist' in the code.
+ * awk.y (func_install): rearranged a bit, to build up a list of
+ the function parameter names and to save it in the `parmlist' field.
+ * eval.c (push_args): new parameter, `varnames', which is the list
+ of variable names. Use this to set the vname field of each
+ parameter's value as it's created. Special case arrays to include
+ where they came from, mainly for array vs. scalar diagnostics.
+ (r_tree_eval): don't set the `vname' field for parameters.
+ (pop_fcall): free the `vname' field if it's an array.
+ (func_call): pass in the `parmlist' field to call of push_args().
+ (r_get_lhs): for Node_subscript, change error message to use
+ the `vname' field.
+ (stopme): new do-nothing function for use with debugging code
+ and setting breakpoints.
+
+Thu Dec 4 15:18:17 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y: fixed several lint checks and moved some into
+ test for do_lint_old.
+ * eval.c (fmt_index): add value of bad format spec to
+ error message.
+
+Tue Nov 18 22:19:02 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (install): strip the installed binary.
+ From Anatoly A. Orehovsky (tolik@mpeks.tomsk.su).
+
+Sun Nov 16 22:12:39 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (in_array, assoc_lookup): add symbol->vname to
+ fatal calls for scalar in array context.
+
+Wed Nov 12 22:18:33 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [ISASCII]: on all IS* macros, add cast to unsigned char.
+ [TOUPPER, TOLOWER]: new macros using unsigned char.
+ * awk.y: change to use of IS* vs. is* macros.
+ * builtin.c (nondec2awknum): change to use of IS* vs. is* macros,
+ change casts for casetable[] from int to unsigned char.
+ use new TOLOWER, TOUPPER macros
+ * dfa.c [ISASCII]: on all IS* macros, add cast to unsigned char.
+ (lex): change isdigit to ISDIGIT.
+ [TOUPPER, TOLOWER]: new macros using unsigned char, now used.
+ * eval.c (fmt_ok): change to use of IS* vs. is* macros.
+ * field.c (sc_parse_field): change to use of IS* vs. is* macros,
+ change casts for casetable[] from int to unsigned char.
+ (set_FS): change to use of IS* vs. is* macros.
+ * io.c (get_a_record): change to use of IS* vs. is* macros,
+ change casts for casetable[] from int to unsigned char.
+ * main.c (main): change to use of IS* vs. is* macros.
+ * node.c (r_force_number, parse_escape): change to use of IS* vs.
+ is* macros.
+ * re.c (make_regexp): change to use of IS* vs. is* macros.
+ * regex.c [ISASCII]: on all IS* macros, add cast to unsigned char.
+
+Sun Oct 19 12:36:47 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ALL: Change email address to arnold@gnu.org in all relevant places.
+
+Wed Oct 15 03:38:12 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y (yylex): Don't allow newlines after ? or : if do_posix.
+
+Thu Oct 9 19:28:39 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h [SEQUENT]: removed; not needed any more since the
+ mmap code was ripped out.
+
+Wed Oct 8 17:22:03 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in: remove check for madvise; don't need it any more
+ after nuking use of mmap.
+
+Tue Oct 7 11:14:21 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (flags2str): made the code table driven. Shortened a lot.
+
+Tue Sep 30 20:59:17 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (r_get_lhs): case Node_field_spec. Add lint warnings
+ for field reference of null string or non-numeric value.
+ Based on patch submitted by Alan Broder, ajb@dtmr.com.
+
+Wed Sep 24 20:47:59 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h [TANDEM]: new changes. Finishes up Tandem
+ integration.
+
+Mon Sep 22 00:42:34 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h [__be_os]: remove BROKEN_TOKEN definition.
+ dfa.c, dfa.h: change `token' to `dfa_token' to avoid BeOS
+ compile problems.
+
+Thu Aug 7 22:35:17 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Changes for BeOS from mc@whoever.com
+ awk.h (strncasecmp): bracket prototype.
+ custom.h [__be_os]: new stuff.
+ dfa.h, dfa.c [BROKEN_TOK]: new ifdefs to use dfa_token, not token.
+
+Fri Aug 1 13:32:49 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Tandem changes:
+ awk.h [TANDEM]: misc additions, as needed.
+ io.c (get_a_record): changes for fixed length records; not used
+ on other systems.
+ main.c (MRL): new variable, TANDEM specific.
+ (main): update handling -mr option for TANDEM.
+ (load_environ): comment out whole routine if TANDEM.
+ missing.c [TANDEM]: new includes.
+ gawkmisc.c [TANDEM]: include `tmiscc'.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Close-on-exec changes:
+ awk.h: (os_close_on_exec, os_isdir): new functions.
+ gawkmisc.c: add include fcntl.h.
+ configure.in [AC_CHECK_HEADERS]: add fcntl.h.
+ io.c (devopen, iop_open): change to use os_isdir(), not S_IFDIR().
+ (redirect, devopen, iop_open, gawk_popen): change all calls to
+ fcntl() to os_close_on_exec().
+
+Tue Jul 29 11:09:45 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (set_BINMODE): fixed check for digits to use isdigit()
+ instead of looping over digits and using strchr(). Duh.
+
+Sat Jul 26 22:52:08 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (set_BINMODE): fix so that `-v BINMODE=w' works.
+ * node.c (r_force_number): add decl of strtod(); makes things
+ work on MIPS.
+ * Makefile.in (install-strip): new target.
+
+Fri Jul 18 13:28:05 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect, devopen, iop_open, gawk_popen): set the
+ close-on-exec flag on all files and pipes opened for I/O.
+ Keeps children run via system() or other pipes from running out
+ of file descriptors.
+
+ (Reported by Kenny McCormack, gazelle@yin.interaccess.com.)
+
+Tue Jul 8 22:18:00 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y [LEX_NEXT]: Removed support for `next file' as two words.
+
+Tue Jul 8 06:46:32 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: changes from pjr@jet.UK (Paul J Rippin) from an old
+ bug report against 2.14.0 that speed up initialization and
+ rewrite the inner loop into readable code.
+
+Thu Jul 3 11:44:50 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Atari support moved into new `unsupported' directory.
+ awk.h, Makefile.in, gawkmisc.c, and missing.c modified.
+
+Sun Jun 29 14:17:37 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y (exp): fixed warning about `x = /foo/'.
+
+Wed Jun 25 09:07:57 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * PORTS: removed from distribution.
+ * Makefile.in (MISC): removed PORTS.
+
+Sun Jun 22 11:52:57 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * BINMODE changes
+ awk.h (Node_BINMODE): added.
+ (struct redirect): added mode field to save for io.c:close_one().
+ (BINMODE, BINMODE_node, set_BINMODE): add declarations.
+ awk.y (isnoeffect): add Node_BINMODE.
+ eval.c (nodetypes): add Node_BINMODE string.
+ (r_tree_eval, r_get_lhs): add cases for Node_BINMODE.
+ (set_BINMODE): new function.
+ io.c (binmode): new function.
+ (nextfile, redirect, gawk_popen): add calls to binmode().
+ main.c (BINMODE, BINMODE_node): add decls.
+ (main): add call to setmode() if BINMODE is set.
+ (varinit): add entry for BINMODE.
+
+Wed Jun 4 21:52:25 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.in [AC_FUNC_MMAP]: removed call.
+ * awk.h [struct iobuf]: removed IOP_MMAPED flag and `getrec' member.
+ * io.c: removed all mmap related code.
+
+Sun Apr 27 16:23:56 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * aclocal.m4 [GAWK_AC_FUNC_MKTIME]: new macro.
+ * configure.in (GAWK_AC_FUNC_MKTIME): call it.
+
+Thu Apr 24 23:25:06 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (devopen): remove stat test for /dev/foo files. Finally.
+
+Fri Jul 26 09:23:15 1996 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Changes to add an abort statement, a la tawk
+ awk.h (Node_K_abort): new enum value for NODETYPE.
+ main.c (aborting): new flag variable.
+ (main): add logic to handle aborting.
+ eval.c (interpret): add case for Node_K_abort.
+ io.c (do_input): if aborting, break loop.
+ awk.y (tokentab): add entry for "abort" keyword
+ (PRODUCTIONS): add production for LEX_ABORT.
+
+Wed Jul 24 12:49:52 1996 Arnold D. Robbins <arnold@skeeve.com>
+
+ * First cut at changes for i18n.
+ awk.h (do_intl): declare new flag variable.
+ [INTLSTR]: new flag def.
+ (m_tree_eval): fix definitions for INTLSTR.
+ (force_string): fix definitions for INTLSTR.
+ awk.y (yylex): add _"..." for international strings.
+ (dumpintlstr): new function.
+ main.c (do_intl): define new flag variable.
+ (optab): add "gen-po" entry.
+ (main): if do_intl, exit, don't run the program.
+ (gawkoption): add "gen-po" entry.
+ node.c (r_force_string): call gettext if flags indicate INTLSTR.
+
+Thu Mar 14 06:29:42 1996 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (do_mktime): added declaration of new function.
+ * builtin.c (do_mktime): new function.
+ * awk.y (tokentab): added "mktime" to list of gawk extensions.
+ * missing.c [HAVE_MKTIME]: added include of mktime.c if needed.
+
+Mon Feb 26 22:32:19 1996 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (pidopen, useropen): added warnings to use PROCINFO[],
+ not special files.
+ * main.c (load_procinfo): new function.
+ * awk.y (variable): added call to load_procinfo() function.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Thu Aug 3 17:47:53 2000 Greg McGary <greg@mcgary.org>
+
+ * regex.c: patches for gcc bounded pointer handling.
+
+Thu Aug 3 13:09:09 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (in_array, do_delete): fix tests for index equality
+ when searching through the array to work correctly when
+ index is "".
+
+Fri Jul 14 21:40:17 2000 Pat Rankin <rankin@eql.caltech.edu>
+
+ * builtin.c (format_tree): Workaround a DEC C V5.7 bug by
+ splitting `strcpy() + 3' into two expressions (the builtin
+ inline strcpy evidently has erroneous return type of void *
+ instead of char *; reputedly fixed in V6.1).
+
+ * eval.c (C): New macro.
+ [casetable]: Use it to add explicit casts for the character
+ values outside the range of 0 to 127.
+ * missing/strncasecmp.c [C, charmap]: Likewise.
+
+ * io.c (redirect): Add EIO check on failed open for VMS.
+
+Fri Jul 14 11:57:23 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ Efficiency hack: turn `for (iggy in foo) delete foo[iggy]'
+ into moral equivalent of `delete foo'.
+ * array.c (do_delete_loop): new routine.
+ * awk.h [NODETYPE]: new Node_K_delete_loop value.
+ Add declaration of do_delete_loop.
+ * awk.y [LEX_FOR]: Fix code to recognize special case.
+ * eval.c (nodetypes): new entry for Node_K_delete_loop.
+ (interpret): add case for Node_K_delete_loop, add more
+ diagnostic info in default (cant_happen) case.
+
+Tue Jul 11 22:15:10 2000 Pat Rankin <rankin@eql.caltech.edu>
+
+ * awk.y (nextc): Recast unsigned char values back to int to
+ prevent VAX C from truncating EOF to 255.
+
+Tue Jul 11 14:08:23 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (do_delete): switch to string comparison, not
+ cmp_nodes.
+ (assoc_find): add call to force_string on subscript.
+ * eval.c (interpret): Case Node_K_arrayfor: check for
+ Node_array_ref and fetch original_array. Yowser.
+
+Fri Jun 30 21:57:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): Don't force the subscript
+ to be a string. Not a good idea after the change
+ to using dupnode.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 14 13:03:45 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (set_record): manage a private buffer for $0.
+ Keeps things safe in case `getline var' rearranges the
+ IOBUF's contents that $0 is still pointing into.
+
+Tue Jun 13 16:27:55 2000 Paul Eggert <eggert@twinsun.com>
+
+ Upgrade to latest and greatest version of largefile code.
+
+ * configure.in (AC_CANONICAL_HOST): Remove.
+ (GAWK_AC_SYS_LARGEFILE): Defer until after AC_MINIX,
+ to avoid autoconf warnings.
+
+ Rewrite largefile configuration so that we don't need to run
+ getconf and don't need AC_CANONICAL_HOST.
+ * config.guess, config.sub: Remove these files.
+ * Makefile.in (MISC): Remove config.guess, config.sub.
+ * m4/largefile.m4 (GAWK_AC_SYS_LARGEFILE_FLAGS,
+ GAWK_AC_SYS_LARGEFILE_SPACE_APPEND): Remove.
+ (GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES): New macro.
+ (GAWK_AC_SYS_LARGEFILE_MACRO_VALUE): Change arguments from
+ CODE-TO-SET-DEFAULT to VALUE, INCLUDES, FUNCTION-BODY.
+ All uses changed.
+ Instead of inspecting the output of getconf, try to compile the
+ test program without and with the macro definition.
+ (GAWK_AC_SYS_LARGEFILE): Do not require AC_CANONICAL_HOST or check
+ for getconf. Instead, check for the needed flags by compiling
+ test programs.
+
+ (GAWK_AC_SYS_LARGEFILE): Define _XOPEN_SOURCE to be 500 to
+ work around glibc 2.1.3 bug.
+
+ (GAWK_AC_SYS_LARGEFILE_FLAGS): Don't use -n32 on IRIX if the
+ installer said otherwise.
+
+ (GAWK_AC_SYS_LARGEFILE_FLAGS): Work around a bug in the QNX shell,
+ which doesn't propagate exit status of failed commands inside
+ shell assignments.
+
+Wed Jun 7 13:23:09 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Updated copyright dates in appropriate files.
+
+Mon May 22 17:29:43 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (clean): get `*/core' too.
+
+Sun May 7 16:33:05 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (concat_exp): Change ref to `lnode->stlen' and
+ `lnode->stptr' for SUBSEP to use `var_value->...'.
+
+Tue May 2 09:54:29 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix referencing freed memory as shown by test/arynocls.* tests.
+ * awk.h [Node_array_ref]: new node type.
+ [orig_array]: new macro element in NODE structure.
+ * field.c (do_split): handle case for Node_array_ref, fetch
+ the original array.
+ * array.c (in_array, do_delete): ditto.
+ * eval.c (nodetypes[]): add Node_array_ref string.
+ (r_tree_eval): handle case for Node_array_ref.
+ (push_args): push arrays as Node_array_ref, and pass them on.
+ (pop_fcall): don't unref lnode if it's an array when releasing
+ local arguments. Check for both Node_array and Node_array_ref.
+ (r_get_lhs): choke on Node_array_ref as for Node_array.
+ For Node_subscript, handle Node_array_ref.
+
+Tue May 2 09:52:12 2000 Bruno Haible <haible@clisp.cons.org>
+
+ * io.c (redirect): After reopening a `struct redirect', move it to
+ the head of the list.
+
+Sun Apr 2 17:51:40 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (re_update): Check if IGNORECASE has changed, and
+ if so recompute the re. See test/igncdym.awk.
+
+Mon Mar 20 16:18:34 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (set_RS): Added a lint warning about multicharacter RS,
+ per suggestion from Akim DeMaille (akim@epita.fr).
+
+Sun Feb 13 14:40:32 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (push_args): Fix from Nide Naoyuki <nide@ics.nara-wu.ac.jp>,
+ re-assign `f' in case tree_eval moved fcall_list around.
+
+Sun Feb 6 11:39:33 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (op_assign): Fix it right. For ++ and --, get the lhs
+ in the operations, do the op, and then return. For += etc,
+ get the rhs FIRST, since the lhs can move around as a result,
+ *then* get the lhs and do the operation. See test/opasnidx.awk.
+
+Tue Feb 1 18:41:40 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (op_assign): reget the rval after regetting
+ the left hand side. See test/opasnslf.awk for why.
+
+Thu Jan 27 18:06:31 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y (yylex): Made ']' not one of the characters
+ that sets `want_assign' to false. `a[i] /= 2' was
+ broken. Per bug report from Kristofer T. Karas
+ <ktk@ktk.bidmc.harvard.edu>.
+
+Wed Dec 22 15:06:37 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y: Removed declarations of functions before
+ definition of `tokentab[]'. They're redundant with
+ what's in awk.h.
+
+Thu Dec 9 17:01:07 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (parse_escape): Add lint warning for unrecognized
+ escape sequences.
+
+Mon Dec 6 15:17:34 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (usage): Changed bug reporting email addresses to
+ be a reference to `Bugs' node in the online and printed
+ doc, instead.
+
+Thu Dec 2 13:08:18 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_compl): test `d' for negative inside the do_lint
+ test, not uval. Ooops.
+
+Fri Nov 26 10:58:36 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_find): ALWAYS compare indexes as strings,
+ don't use cmp_nodes in case they are numeric. Oh my.
+ Talk about a Day 1 bug!
+
+Tue Nov 23 11:58:53 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.c (SYNTAX): cast argument to `unsigned char' instead of
+ &-ing with 0xFF. Hopefully somewhat more portable, ala 21 Nov 99
+ changes to awk.y.
+
+Sun Nov 21 22:25:27 1999 Paul Eggert <eggert@twinsun.com>
+
+ * aclocal.m4 (AC_SYS_LARGEFILE_FLAGS): Work around a
+ problem with the QNX 4.25 shell, which doesn't propagate exit
+ status of failed commands inside shell assignments.
+
+Sun Nov 21 20:33:35 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (nextc): remove declaration, don't need it here.
+ awk.y (nextc): Cast values to unsigned char so that latin-1
+ characters in strings don't turn themselves into EOF.
+ Most notably y-umlaut, which is decimal 255.
+
+Mon Nov 1 20:00:25 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.c (init_syntax_once): move below definition of
+ ISALNUM etc., then use ISALNUM to init the table, so that
+ the word ops will work if i18n'ed.
+ (SYNTAX): And subscript with 0xFF for Latin-1 characters.
+
+Mon Oct 25 18:37:13 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h, main.c, io.c: undo previous changes (22 Oct 1999).
+ * main.c (main): move call to `init_fields()' to before
+ arg parsing. This allows `-v NF=blah' to work ok.
+
+Fri Oct 22 17:43:40 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (arg_assign): Add new arg, `initing' for icky special
+ casing of -v of special variables. Use it to check for NF.
+ May need to add other cases later.
+ (pre_assign): change call arg_assign, passing initing=TRUE;
+ io.c (nextfile): change call arg_assign, passing initing=FALSE;
+ awk.h: Change prototype for arg_assign.
+
+Tue Oct 19 16:06:48 1999 Paul Eggert <eggert@twinsun.com>
+
+ * io.c (close_redir): Don't munge errno between setting it and
+ using it.
+
+Wed Oct 6 17:47:47 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (arg_assign): return NULL on bad variable. Allows
+ things like `./3x=stuff' to work as a filename.
+
+Thu Sep 23 21:35:46 1999 Paul Eggert <eggert@twinsun.com>
+
+ * aclocal.m4 (GAWK_AC_SYS_LARGEFILE_FLAGS): Work around GCC
+ 2.95.1 bug in HP-UX 10.20 or later. (Had to fix the fix. ADR. :-)
+
+Tue Sep 21 13:31:36 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): For '0', only set zero_flag if we
+ haven't seen the field width or precision yet.
+
+Mon Aug 9 13:06:01 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (assoc_lookup): Removed code that gave each array
+ a private copy of each index. Balloons memory usage for
+ no good reason that I can see. Just use dupnode in all
+ cases.
+ * configure.in: check for $srcdir/.developing adds extra
+ defines for my testing/debugging use. Yes, hack alert.
+
+Sun Aug 1 11:02:02 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (dupnode): turn off FIELD when copying nodes.
+ * array.c (do_adump, assoc_dump): new functions for array debugging.
+ * awk.y (tokentab): conditionally add "adump" function for debugging.
+ * awk.h: delcare new functions.
+
+Thu Jul 29 23:26:40 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ From wsanchez@apple.com:
+ * Makefile.in (install-strip): new target, coding stds. compatibility.
+ * config.guess, config.sub: Add MacOS X recognition.
+
+Thu Jul 29 19:09:19 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.y (func_install): make `function foo(foo)' a fatal error.
+ eval.c (r_tree_eval): diagnose use of a function name as a
+ variable inside the function.
+
+Sun Jul 4 16:53:14 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (eval_condition): add extra braces to avoid
+ gcc warning. I'm not going to bother for the library
+ code like dfa and regex.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Wed Jun 30 16:10:11 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.h: add include of <assert.h>, and comment about config.h
+ having to be included before any system headers. Otherwise,
+ with egcs-2.91.66 and later on Linux systems, and possibly
+ others, things break badly, due to the LFS macros.
+ * awk.y, builtin.c, eval.c, field.c, io.c: removed include
+ of assert.h
+
+Wed Jun 9 11:39:19 1999 Paul Eggert <eggert@twinsun.com>
+
+ Port the large-file code to AIX, HP-UX, and IRIX.
+ Add cross-compilation support for large files.
+
+ * config.guess, config.sub: New files.
+
+ * configure.in (AC_CANONICAL_HOST):
+ Add; GAWK_AC_SYS_LARGEFILE needs this.
+ (GAWK_AC_SYS_LARGEFILE): Renamed from GAWK_AC_LARGE_FILES.
+
+ * aclocal.m4 (GAWK_AC_SYS_LARGEFILE): Renamed from GAWK_AC_LARGE_FILES.
+ Add support for AIX and HP-UX.
+ (GAWK_AC_SYS_LARGEFILE_FLAGS, GAWK_AC_SYS_LARGEFILE_SPACE_APPEND,
+ GAWK_AC_SYS_LARGEFILE_MACRO_VALUE): New macros.
+
+ * acconfig.h (_FILE_OFFSET_BITS, _LARGEFILE_SOURCE, _LARGE_FILES):
+ New macros.
+
+ * Makefile.in (MISC): add config.guess and config.sub so they get
+ included in the distribution.
+
+Wed Jun 9 11:29:29 1999 Paul Eggert <eggert@twinsun.com>
+
+ * io.c (iop_alloc): Don't mmap files whose sizes don't fit in `int'.
+ [ This isn't really needed, as HAVE_MMAP is #undef'ed at the top,
+ but it's there in case people want to take their life in their hands. ]
+
+Sun Jun 6 11:28:07 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.46: Release tar file made.
+
+Wed Jun 2 14:36:24 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * PORTS: Updated with a more recent list of systems
+ that gawk compiles and tests ok on.
+
+Tue Jun 1 14:24:59 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.45: Release tar file made.
+
+Tue May 25 16:32:37 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (format_tree): more smarts for weird cases, such as
+ zero precisions and zero values used with the `#' flag.
+ Thanks to Andreas Schwab (schwab@gnu.org) for pointing these out.
+
+Wed May 19 14:02:54 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (do_close): move test for `close(FILENAME)' to after
+ loop through all open redirections. Fixes problems in obscure
+ cases with redirections in END rules.
+
+Sun May 16 14:08:39 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.y (yylex): fix group of characters including ',' to
+ set want_assign = FALSE. Fixes bizarre parsing problems in
+ function call lists, for example.
+ * io.c (get_a_record): repair logic for single-leading-newline
+ case.
+
+Tue May 11 16:48:11 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * aclocal.m4 (GAWK_AC_AIX_TWEAK): new macro.
+ * configure.in: call it
+ * Makefile.in: (awklib/all): pass CFLAGS on to sub-make so
+ that password programs will get AIX magic defines. Avoids
+ having to tweak program code for those in doc/gawk.texi.
+
+Mon May 3 16:56:23 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * array.c (do_delete): don't free_temp(subs) until after all
+ references to it are finished.
+
+Mon May 3 13:41:16 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.44: Release tar file made.
+
+Sun May 2 18:25:43 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (get_a_record): Do a really good job of stripping newlines
+ from the front of records when RS = "" and there's only one
+ newline at the front of the file, which the regex didn't catch.
+
+Wed Apr 28 12:27:49 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * configure.in: more HP stuff: fix the manual alloca code so that
+ gawk will compile and link on HP systems. See the comments.
+
+Sun Apr 25 13:39:16 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (gawk): add $(CFLAGS) to linking step.
+ * configure.in: correctly do AC_FUNC_GETPGRP on HP systems too.
+
+Tue Apr 13 20:21:00 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.43: Release tar file made.
+
+Tue Apr 13 19:02:20 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (useropen, pidopen): add casts to int on arguments to
+ silence gcc warnings.
+ * regex.c (regcomp,regexec,regfree): add ifdef for APPLE.
+
+Thu Feb 4 10:38:02 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * custom.h: hacks for BeOS. Not documented in the manual right now.
+ * configure.in: hacks for BeOS. Check for HP-UX and define C_ALLOCA
+ if not using gcc. I wish they'd just fix bison already.
+
+Sun Dec 20 16:57:38 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.42: Release tar file made.
+
+Sun Nov 15 21:05:39 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (gawk_popen): Add WIN32 to list of systems that use
+ the non-real-pipe version. From the PC gawk guys.
+
+Wed Nov 4 11:32:24 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.41: Release tar file made.
+
+Tue Nov 3 16:24:35 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * eval.c (r_get_lhs): Fix the cases for the special variables,
+ don't unref their current value if it's the same as the internal
+ copy; perhaps the current one is used in a concatenation or some
+ other expression somewhere higher up in the call chain. Ouch.
+ See test/getnr2tm.awk.
+
+Sun Nov 1 15:24:52 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (format_tree): improve handling of zero-fill
+ when a precision is present. See test/zeroflag.awk.
+
+Wed Oct 28 20:40:17 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * eval.c (r_tree_eval): Case for Node_concat. Get lengths
+ separately, in case one expression has a side effect that
+ that changes another. Ugly, but it keeps gawk from core
+ dumping. See test/nasty.awk.
+
+Sun Oct 18 21:27:24 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.y (append_right): bug fix, if `list' or `new' are NULL,
+ return `list', so that things don't break too badly.
+ * regex.c (re_compile_fastmap): remove unused variable `num_regs'.
+
+Thu Oct 8 19:36:57 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * BETA Release 3.0.40: Release tar file made.
+
+Mon Jul 27 10:14:33 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * node.c (parse_escape): Remove assignment with side effects
+ from ISXDIGIT test. Thanks to "Mihai T. LAZARESCU"
+ <mihai@ccmserv.polito.it> for pointing this out.
+
+Mon Apr 27 11:31:32 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * main.c (usage): fix the email address for the bug list.
+ (copyleft): update the copyright year.
+
+Mon Mar 23 21:22:32 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * eval.c (r_get_lhs): make sure that values of type
+ Node_param_list don't have the FUNC flag set. This means
+ we don't allow the use of a function name as a variable or
+ array from within the function.
+
+Sun Mar 22 19:12:32 1998 Paul Eggert <eggert@twinsun.com>
+
+ * aclocal.m4 (GAWK_AC_LARGE_FILES): new macro that checks for
+ large file support, and updates CPPFLAGS, LDFLAGS, LIBS as
+ needed.
+ * configure.in: call GAWK_AC_LARGE_FILES.
+ * Makefile.in (CPPFLAGS, LDFLAGS): Let autoconf configure.
+ (COMPFLAGS): Add $(CPPFLAGS).
+
+Mon Mar 16 14:06:41 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * field.c (using_FIELDWIDTHS): new macro.
+ (using_fieldwidths): use new macro.
+ (do_split): in case for FS_DFLT, also check that
+ we're not using FIELDWIDTHS. Otherwise, split() would use
+ FIELDWIDTHS, not current value of FS. Oops.
+
+Sun Nov 16 20:08:59 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (sub_common): fix for count of matches in gsub
+ from Geert.Debyser@esat.kuleuven.ac.be.
+
+Wed Oct 15 03:38:12 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * field.c (set_FS): Use `sc_parsefield' if the value of FS is not
+ alphabetic OR if not ignoring case. Bug fix if IGNORECASE
+ is true and FS happens to be '^'. Sheesh, talk about obscure.
+ (rebuild_record): Add more smarts to the code that sets up the
+ fields. Thanks to Alan J. Broder (ajb@dtmr.com).
+
+Sun Oct 5 11:56:52 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * configure.in: if ISC add -D_SYSV3 to CFLAGS, per email from
+ Mario Vanoni (vanonim@dial.eunet.ch).
+
+Fri Sep 26 00:57:49 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.y (append_right): return if either list is NULL. Prevents
+ syntax errors from causing core dumps.
+
+Wed Sep 17 15:34:15 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * field.c (rebuild_record): set things up so that all fields point
+ into the new record and release any changed fields without
+ causing memory leaks. Avoids problems when fields are extended
+ with the value of $0 or other fields and then $0 is assigned to.
+
+Mon Sep 15 16:12:55 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (do_print): when testing for NUMBER, make sure
+ it's not a string too. Thanks to Michael Brennan for
+ clarifying the semantics.
+
+Sun Sep 14 19:55:12 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * node.c (format_val): always format values ourselves: avoids
+ problems if OFMT is bizarre, like %s.
+
+Sun Sep 14 00:08:53 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (get_a_record): replace all occurrences of the test
+ `grRS == FALSE' with `RS_is_null' which makes ` RS = "\0" '
+ actually work, is clearer code, and actually makes use of
+ the `RS_is_null' variable!
+
+Sun Aug 17 07:15:12 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * field.c (set_FS): Change logic to always set parse_field, even
+ if FS hasn't changed. Thanks to Igor Sheyn for catching this.
+
+Wed Aug 6 21:04:37 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * io.c (VMS et al gawk_popen): use pclose, not fclose, if
+ iop_alloc fails.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.y [variable]: fix case for subscript if $3 == NULL.
+
+Sun Jul 27 22:47:30 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * awk.y (get_src_buf): don't close file if it's stdin.
+
+Sun Jul 27 22:47:15 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * io.c (#if VMS: vmsrtl_fileno): new routine.
+ (#if VMS: fileno): new macro substituted for stdio one.
+
+Thu Jul 17 20:05:59 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (do_print): When OFMT != CONVFMT, create a new
+ temporary node with just the numeric value valid and format it,
+ and use that for printing. Avoids memory corruption.
+
+Wed Jul 16 10:01:16 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * regex.c: When SYNTAX_TABLE is defined, but not emacs, then
+ CHAR_SET_SIZE is not defined, though used in regcomp. It should
+ be taken out of #ifdef SYNTAX_TABLE. Fix from bug group, from
+ Akim Demaille, demaille@inf.enst.fr.
+ * awk.h (isnondecimal): make test a little smarter.
+ builtin.c (nondec2awknum): add bailout for decimal numbers, e.g.
+ `00.1'. Fix from Larry Schwimmer <rosebud@cyclone.Stanford.EDU>.
+
+Thu Jun 19 19:00:40 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * eval.c (interpret): case Node_K_next, Node_K_nextfile: fatal
+ error if called from BEGIN or END.
+ (Fixed completely Mon May 3 13:31:42 1999.)
+
+Mon Jun 9 22:40:04 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * builtin.c (nondec2awknum): Allow `f' and `F' in hexadecimal numbers.
+ Gotta get more sleep...
+ * array.c (assoc_lookup): Fix from Tom Karzes (karzes@equator.com)
+ for memory leak when forcing type to Node_var_array.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Wed May 14 08:06:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (do_close): add lint warning if closing something that
+ isn't open.
+
+Tue May 13 12:14:12 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * random.c, builtin.c: remove __GLIBC__ tests, since it breaks
+ `make test'. I prefer consistency across platforms.
+ * Makefile.in (gawk): undid April 25 changes and added comment.
+ Putting COMPLAGS in breaks with -g on VMS POSIX.
+
+Sun May 11 14:48:04 1997 Darrell Hankerson <hankedr@mail.auburn.edu>
+
+ * io.c [MSC_VER]: add cases for WIN32.
+ * regex.c [MSC_VER]: add cases for WIN32.
+
+Sun May 11 07:04:01 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_print): in the loop that evaluates each expression
+ to be printed, do a dupnode to avoid bizarre output. Thanks to
+ Michal for finding this problem.
+ * awk.y (yylex): fix scanning of hexadecimal constants.
+
+Wed May 7 15:09:25 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (get_a_record): fix casetable indexing with cast to int.
+ Keeps Michal happy.
+
+Tue May 6 16:40:19 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (func_call): removed unneeded variables.
+
+Mon May 5 21:17:37 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * missing/strftime.c [case 'v', VMS_EXT]: for VMS date format, two
+ digit day of month should not be zero padded on the 1st through
+ the 9th.
+
+Mon May 5 06:33:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h, regex.c: merge with current GLIBC version.
+
+Mon May 5 06:33:47 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * io.c (nextfile): move the check for null return from iop_open
+ in the normal case and add one for the "no args" case.
+
+Fri Apr 25 16:52:33 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * array.c (grow_table): add a bunch more large primes so arrays
+ can get really big. Thanks to christos@deshaw.com.
+ * all files: remove ifdef'ed out code and update copyrights.
+ * Makefile.in (gawk): add $(COMPFLAGS) to command line.
+ * eval.c (flags2str): added case for FIELD.
+
+Thu Apr 24 22:39:23 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * COPYING: changed to current official version from FSF.
+ * regex.c: merge with GLIBC version.
+ * awk.h [_GNU_SOURCE]: bracket definition inside ifdef.
+ (NODE.source_line): move name member out of `x' union and
+ into `nodep'; avoids problems doing diagnostics.
+ (nondec2num): put decl into #if BITOPS || NONDECDATA
+ * posix/gawkmisc.c, missing/system.c, missing/strtod.c,
+ missing/strerror.c: move to generic GPL statement at top.
+ * builtin.c (nondec2num): put into #if BITOPS || NONDECDATA
+
+Wed Apr 23 22:14:14 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * dfa.c: misc changes for really pedantic SGI compilers.
+ * builtin.c: bracket defs of random() etc for GLIBC.
+ * random.c: bracket whole file for GLIBC.
+ * configure.in: extra goop for GETPGRP test for VMS POSIX.
+ * custom.h [VMS]: remove hard definition of GETPGRP_VOID.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Tue Apr 15 21:35:45 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ NEW UNDOCUMENTED FEATURE. USE THE SOURCE LUKE!
+ * acconfig.h [NONDECDATA]: new macro.
+ * awk.h: add decl of do_strtonum.
+ * awk.y (tokentab): add entry for strtonum function.
+ * builtin.c (do_strtonum): new function.
+ * configure.in (non-decimal-data): new --enable-* option.
+ * node.c (r_force_number): change to allow non-decimal data inside
+ ifdef NONDECDATA.
+
+Tue Apr 15 06:32:50 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * missing/strftime.c (malloc, realloc, getenv, strchr): only
+ declare these when STDC_HEADERS is not defined.
+ <stdlib.h, string.h>: include these when STDC_HEADERS is defined.
+ * awk.h (freenode, tree_eval, m_tree_eval): reorganize definitions.
+ * alloca.c (malloc): if malloc is already defined as a macro,
+ presumeably by config.h, don't define or declare it.
+
+Wed Apr 9 22:45:27 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in [COMPFLAGS]: per suggestion from Karl Berry, put
+ $(CFLAGS) last.
+
+Tue Apr 8 23:54:46 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (interpret): For Node_K_break and Node_K_continue, if
+ treating them like `next', also check the function call stack
+ and pop it if necessary.
+
+Mon Apr 7 18:22:37 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h: Add decls of new routines do_compl() and set_loc().
+ * awk.y (tokentab): add entry for "compl" function.
+ * builtin.c (do_compl): new function to do ones complement.
+ (do_substr): rationalized yet again, now notices negative start
+ and length parameters.
+ * eval.c (push_args): fix if call_list gets realloc'ed in the
+ middle of things. Avoids crash for deeply nested function calls.
+ * main.c (catch_sig): add call to set_loc().
+ * msg.c (set_loc, srcfile, srcline): new function and private
+ variables to help out in tracing down source of error messages.
+
+Fri Mar 28 08:42:27 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (iop_alloc, iop_close): Undo changes of Feb 11, apparently
+ other cleanups in io.c made mmap stuff start working again.
+ BAH! It's a mess, the test suite still fails. I'm leaving the
+ mmap stuff undefined for now. It'll probably get ripped out in 3.1.
+
+Thu Mar 27 08:48:57 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * custom.h [_SEQUENT_]: undef HAVE_MMAP.
+
+Wed Mar 26 09:08:16 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (iop_alloc): fix definition to make it static.
+
+Mon Mar 24 23:09:07 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (init_fields, etc..): more clean up use of Null_field
+ and the various flags.
+ * node.c (unref): if a field, free the node itself. Fixes
+ memory leak problems.
+
+Sun Mar 23 22:51:09 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h [FIELD]: new flag for node->flags field.
+ * builtin.c (sub_common): if FIELD is set, dup the string.
+ * field.c (init_fields): set up a new Null_field global var.
+ (init_fields, set_field, set_record) use the FIELD flag.
+ (getfield): use Null_field instead of private variable.
+ * io.c (wait_any): comment out calls to pclose and iop_close,
+ caused weird race conditions. See test/pipeio1.awk. Thanks
+ to Darrell Hankerson for tracing this one down.
+
+Tue Mar 18 20:57:18 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * dfa.c (inboth): free templist; plugs memory leak.
+ * field.c (init_fields, grow_fields_arr, set_field, rebuild_record,
+ set_record): remove PERM flag from entries in fields_arr[]. Fixes
+ nasty memory leak.
+
+Tue Mar 18 06:33:00 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (dup_parms): robustified against parameter errors.
+
+Sun Mar 16 21:31:40 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ NEW UNDOCUMENTED FEATURE. USE THE SOURCE LUKE!
+ * acconfig.h [BITOPS]: new macro. If set, do octal & hex and bit ops.
+ * awk.h [isnondecimal]: new macro, and decl of new functions.
+ * awk.y (yylex): add recognition of octal and hex constants.
+ * builtin.c (do_and, do_or, do_xor, do_lshift, do_rshift): new
+ functions that do bit operations.
+ (nondec2awknum): new function to convert octal or hex to double.
+ * configure.in: Add AC_ARG_ENABLE for bit operations.
+ * node.c (r_force_number): add octal and hex conversion.
+
+Sun Mar 16 21:28:56 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h [IOP_NOFREE_OBJ]: new macro.
+ * io.c (iop_open, iop_alloc): add new third parameter, which is
+ either NULL, meaning allocate a new IOP, or the address of one
+ already allocated. Have a static one in the `nextfile'
+ routine, and use the IOP_NOFREE_OBJ flag for it. All of this
+ keeps us from reading freed memory. The `swaplns' test fails
+ otherwise.
+ (iop_close): if IOP_NOFREE_OBJ is set, don't free the IOBUF.
+
+Wed Feb 26 06:21:02 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (in_function, pop_fcall_stack, pop_fcall, push_args):
+ new functions. These manage "frames" of awk function call arguments.
+ The problem is that a `next' or a `nextfile' from a function
+ leaks memory. These changes allow us to free up that memory.
+ (interpret): for Node_K_next and Node_K_nextfile, check if in
+ a function call and free all function call frames.
+
+Fri Feb 21 06:23:19 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Misc changes from Katsuyuki Okabe <HGC02147@niftyserve.or.jp>:
+ * builtin.c (do_substr): change a %d to %ld in warning message.
+ * eval.c (op_assign): fix format string for warning about %=.
+
+Wed Feb 19 23:29:02 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (main): add do_intervals to condition that causes
+ resetup() to be called again. Makes the --re-interval option
+ actually work. What a concept.
+
+Fri Feb 14 09:47:31 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c [#include "awk.h"]: undef HAVE_MMAP to just use the old code.
+ Something is causing a file descriptor leak, and this is getting to
+ be just too much hair. I reserve the right to rip out the mmap
+ code entirely at a future date.
+
+Tue Feb 11 06:28:29 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (iop_alloc): for an mmap'ed file, close the file descriptor,
+ and then touch each page to get a private copy. Fixes nasty case
+ of truncating our input file.
+ (iop_close): don't call close on mmap'ed file.
+
+Wed Feb 5 17:59:04 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (interpret): For Node_K_delete, just call do_delete; let
+ it handle the case of `delete array'.
+ * array.c (do_delete): Changed to handle case of `delete array',
+ and made smarter if the array is actually an uninitialized
+ parameter.
+
+Sun Jan 26 22:58:29 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * getopt.h, getopt.c, getopt1.c: replaced with new versions from
+ GLIBC 2.
+
+Sun Jan 19 23:37:03 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (nodetype2str): not static, for debugging.
+ (flags2str) new function: for debugging.
+ * field.c (get_field): add new var that is like Nnull_string but
+ does not have numeric attributes, so that new fields are strings.
+ (set_record): turn off PERM flag before unrefing fields and field 0.
+ * array.c (in_array): always evaluate subscript, could have
+ side effects.
+ * builtin.c (do_strftime): way increase size of buffer to make sure
+ we don't have overflow problem. Keeps Paul Eggert happy.
+ * custom.h [__amigaos__]: define fork to vfork. From Fred Fish.
+ * dfa.c: move include of config.h to top, for RSXNT. From Kai
+ Uwe Rommel.
+ (ISALPHA, etc): change from Jacob Engelbrecht (jaen@novo.dk)
+ to better handle non-ascii environments.
+ * gawkmisc.c: remove amigados case, posix should now work fine.
+ * amiga/*: nuked per previous entry.
+ * Makefile.in: removed all references to amiga
+ * io.c [HAVE_SYS_PARAM_H]: Add #undef RE_DUP_MAX to avoid
+ spurious conflict with regex.h.
+ (flush_io): remove amiga ifdefs, not needed anymore.
+ (spec_setup): set getrec field for special files. Fix from
+ Mark Gray (markgray@pdt.net).
+ * node.c (more_nodes): fix to get the last entry in the array.
+
+Wed Jan 8 17:42:37 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * io.c (mmap_get_record): Fix return value if file ends without
+ record separator.
+
+Fri Jan 3 19:57:16 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * awk.y (get_src_buf): Test for an empty source file by detecting
+ an initial read of 0 bytes rather than by relying on info from
+ stat().
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Wed Dec 25 11:17:32 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install, uninstall): use $(srcdir)/patchlevel.h.
+ Thanks to Richard Levitte, LeViMS@stacken.kth.se.
+ (install): remove chmod command; let $(INSTALL_PROGRAM) use -m.
+
+Mon Dec 23 20:36:59 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * custom.h (#if VMS_POSIX): Define GETPGRP_VOID.
+
+Fri Dec 20 08:59:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * getopt.c, getopt1.c: comment out the `#if defined (_LIBC) ||
+ !defined (__GNU_LIBRARY__)' and `#endif' to force use of this
+ getopt, even on systems like linux. This will be handled
+ better in 3.1 / glibc 2.
+
+Thu Dec 19 22:52:39 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (yylex): In several places, after yyerror(), add call to
+ exit(). Otherwise, infinite messages. This should probably
+ be handled better.
+
+Wed Dec 18 22:42:10 1996 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * getopt.c (_getopt_internal): if 'W' and ';', if optind == argc,
+ return c, don't fall through.
+
+Wed Dec 18 10:09:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in [AC_PREREQ]: Update to 2.12 in order to switch to
+ autoconf 2.12. Lots of other files will be rebuilt automatically.
+ [AM_SANITY_CHECK_CC]: Removed, autoconf does it now.
+ * aclocal.m4 [AM_SANITY_CHECK_CC]: Removed, autoconf does it now.
+
+Tue Dec 17 22:23:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_strftime): fix case if format string is "".
+ Also fix it if format is not "" but result of strftime is "".
+ See comments in code.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Tue Dec 10 22:39:41 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dist): add dependency on `info'. Remove line that
+ does makeinfo.
+ (install): use $(LN) not $(LN_S) to link gawk gawk-version.
+
+Sun Dec 8 07:53:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gawk): took COMPFLAGS out of link line for help
+ on VMS posix. Shouldn't (I hope) affect anything else.
+
+Thu Nov 28 11:52:24 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in (AC_PROG_INSTALL): Set INSTALL to install-sh.
+
+Tue Nov 26 22:42:00 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * PORTS: Updated list of systems.
+ * Makefile.in (install): Fix some typos and add some improvements
+ for Ultrix.
+
+Sun Nov 24 22:16:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_printf): if no args, fatal error. Return silently
+ if --traditional.
+
+Thu Nov 7 20:54:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (inrec): make sure EOF hasn't already happened before
+ trying to read; prevents accessing freed buffer. Thanks to
+ Michal Jaegermann.
+ * Makefile.in [AWKSRC]: add random.h.
+ random.h: new file, redefines names of the `random' functions.
+ random.c, builtin.c: add include of random.h.
+
+Thu Nov 7 09:06:21 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (snode): undo 4 Oct change, put do_split code back.
+ field.c (do_split): restore old code; add test for CONST, so
+ that re_parse_field is used if third arg to split is a regexp
+ constant.
+
+Mon Nov 4 12:57:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (main): Research -m[fr] options don't need literal '='
+ characters. Brian's documentation was confusing. Fixed, not
+ that anyone actually uses these options with gawk.
+
+Sun Nov 3 11:23:21 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (def_parse_field): add \n to list of acceptable white space.
+ (posix_def_parse_field): new routine, just like def_parse_field(),
+ but only allows space and tab as separators.
+ (do_split, set_FS): make appropriate choice between the two
+ *def_parse_field() routines.
+
+Fri Oct 25 10:13:06 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: remove test for random.
+ * Makefile.in: add random.c to list of files always compiled.
+ * missing.c: remove HAVE_RANDOM test.
+ * builtin.c: remove ifdef's for HAVE_RANDOM.
+ [GAWK_RAND_MAX]: use constant we know works with our random().
+ * random.c: new file - moved from missing/ directory.
+
+Wed Oct 23 19:46:01 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * builtin.c (do_tolower, do_toupper): Add `unsigned char *' casts.
+
+Tue Oct 22 21:27:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c [GAWK_RANDOM_MAX]: Try to make definition a bit
+ smarter; don't use RAND_MAX if it's equal to SHRT_MAX, blows
+ things up.
+
+Tue Oct 22 08:49:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (copyleft): update copyright date to 1996.
+ too many files to list: update copyright date to 1996.
+
+Sun Oct 20 12:21:09 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y, dfa.c, eval.c, io.c, re.c: added various FIXME comments.
+
+Sat Oct 19 22:06:42 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (nodetype2str): make static, add prototype.
+ * field.c (sc_parse_field): cast array subscripts to int to
+ shut up gcc warnings.
+ * gawkmisc.c: add prototype for xmalloc.
+ * awk.h: add prototype for getredirect.
+ * builtin.c (do_fflush): remove extern decl of getredirect.
+ * io.c (get_a_record, mmap_get_record): change decl of rs to int,
+ to shut up gcc warnings.
+ * awk.y (isassignable): add a default to switch to quiet gcc.
+ * getopt.c (_getopt_internal): give default value to `indfound'.
+
+Fri Oct 18 09:00:49 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_SYNTAX_AWK]: add RE_CONTEXT_INDEP_ANCHORS.
+
+Thu Oct 17 22:32:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * aclocal.m4 [AM_SANITY_CHECK_CC]: added.
+ * configure.in: use it.
+
+Thu Oct 17 21:43:25 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: add checks for locale.h and setlocale().
+ awk.h: include locale.h and define out setlocale() if not available.
+ main.c (main): call setlocale().
+ builtin.c (do_tolower, do_toupper): use unsigned char pointers,
+ to get other charsets right in different locales.
+
+Wed Oct 16 21:32:53 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): Change initial buffer size to 512
+ and use a constant. Allows large values of %f per bug report
+ from sheyn@cs.bu.edu.
+
+Wed Oct 16 21:22:08 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in [MISC]: removed TAGS and tags
+ (local-distclean): added TAGS and tags
+ (maintainer-clean): removed TAGS and tags
+
+Wed Oct 16 12:28:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (version): Add call to copyleft(), per new standards.
+ version.c: Fix text of version string to match new standards.
+
+Sun Oct 6 22:19:45 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.c: updated to Emacs 19.34b base.
+
+Sun Oct 6 21:57:34 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * re.c (make_regexp): fixed to handle \8 and \9 in the middle
+ of a regexp.
+
+Fri Oct 4 10:26:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (snode): remove case for do_split; always making the
+ third arg a Node_regex is wrong.
+ field.c (do_split): rationalized to distinguish `/ /' from `" "'.
+ Generally fixed up.
+ * node.c (parse_escape): Allow single digit \x escapes.
+
+1996-10-02 Paul Eggert <eggert@twinsun.com>
+
+ * builtin.c (format_tree):
+ Fix bug in %d and %i format: NaNs, and values
+ in the range LONG_MAX+1 .. ULONG_MAX, were mishandled.
+ Don't assume that double values <= -1 are converted to unsigned
+ long in the expected way; the C Standard doesn't guarantee this.
+
+1996-10-02 Paul Eggert <eggert@twinsun.com>
+
+ * awk.h (INT_MAX): Remove unused symbol.
+
+Mon Sep 30 22:19:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * getopt.c (_getopt_internal): If 'W' is in the optstring followed
+ by a ';' then search through the long opts table. This makes
+ `-W foo=bar' same as `--foo=bar'.
+ * main.c (main): 'W' now prints an error message.
+ (gawk_option): deleted the routine.
+
+Sun Sep 29 23:04:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): fix several bugs with gsub when
+ matching null strings. See test/gsubtest.awk.
+
+Fri Sep 20 17:35:54 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * alloca.c (NULL): don't define if <config.h> has already done so.
+
+Fri Sep 20 11:54:31 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_print): evaluate all the expressions first and
+ then print them. Avoids surprising behavior. See test/prtoeval.awk
+ for an example.
+
+Tue Sep 10 06:21:40 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h [FUNC]: new flag, marks a Node_parameter_list as really
+ being the function name; allows more checking in awk.y.
+ * awk.y (isassignable): now takes a NODE * instead of a type, to
+ check if a function parameter is marked FUNC, then it's the function
+ name, which is not assignable. Fix call from snode().
+ (function_prologue): mark function name as FUNC.
+ (yyerror): don't call exit() anymore; gawk will now report
+ all syntax errors.
+
+Sun Sep 1 19:36:30 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (rebuild_record): after building new field 0, go through
+ all old fields, and if they used to point into the old one,
+ have them point into the new one. Then turn off PERM flag before
+ unref-ing field 0.
+
+Wed Aug 28 19:13:34 1996 Arnold D. Robbins <arnold@math.utah.edu>
+
+ * eval.c (set_IGNORECASE): Correctly parenthesize bit operations
+ in test and fix logic for string value.
+
+Wed Aug 28 22:06:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (usage): add email addresses for bug reporting, per
+ change in GNU Coding Standards from RMS.
+
+Sun Aug 11 23:13:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): correct use of $(INSTALL_PROGRAM).
+
+Thu Aug 8 23:29:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * parse.y (isassignable): new function, checks in type can
+ be assigned to.
+ (snode): changed checking for 3rd arg of gsub to be more
+ general, supersedes earlier change.
+
+Thu Aug 8 13:58:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * parse.y (snode): If third arg to sub or gsub is builtin
+ function, complain, since can't substitute into result.
+ * eval.c (r_get_lhs): diagnose Node_builtin as an error, instead
+ of falling through into default case and using cant_happen().
+
+Thu Aug 1 07:13:14 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_DEBUG]: new macro.
+ [RE_SYNTAX_GNU_AWK]: add RE_DEBUG.
+ [RE_SYNTAX_POSIX_AWK]: add RE_INTERVALS.
+ * regex.c (re_set_syntax): add #ifdef DEBUG code to turn on `debug'
+ flag if RE_DEBUG set, and turn off debug if not set and debug
+ was on.
+ * main.c (main): remove `do_intervals = TRUE' from `if (do_posix)',
+ it's now handled in the definition of RE_SYNTAX_POSIX_AWK.
+
+Mon Jul 29 17:49:07 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * io.c (O_ACCMODE): define it if <fcntl.h> doesn't.
+
+Mon Jul 29 12:02:48 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (set_IGNORECASE): made somewhat smarter. gawk -v IGNORECASE=0
+ was acting the same as -v IGNORECASE=1. Thanks to Darrell Hankerson
+ for the bug report.
+
+Fri Jul 26 12:04:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h (format_val): add declaration of new routine.
+ * node.c (format_val): new routine, abstracts old guts of
+ r_forcestring; accepts format string and index as additional params.
+ (r_force_string): changed to call format_val.
+ * builtin.c (do_print): don't tree_eval the tree twice in case
+ OFMTidx != CONVFMTidx; doing so could cause side effects
+ (from bug report by Tobias Rettstadt, xassp@ipds.uni-kiel.de).
+ Instead, call format_val.
+
+Mon Jul 22 21:59:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (iop_close): change check for "is $0 in the input buffer"
+ to use `< (iop->buf + iop->secsiz + iop->size)' instead of
+ `< iop->end'. The latter is bogus if EOF has been hit on the
+ file. Fix from Darrel Hankerson based on bug report by
+ Charles Howes (howes@grid.direct.ca). See test/eofsplit.awk.
+
+Thu Jul 18 19:43:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): backed out change of Feb 14 in favor of:
+ (do_gensub): Changed to use make_string and then to |= TEMP
+ flag, based on bug report and patch from Katsuyuki Okabe,
+ hgc02147@niftyserve.or.jp.
+
+Thu Jul 18 19:23:53 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * custom.h: added ifdef for QNX, based on bug report from
+ Michael Hunter, mphunter@qnx.com.
+
+Mon Jul 15 09:31:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (redirect): When finding the rp pointer, if it's not
+ NULL, set str = rp->value. This gets the '\0' terminated
+ version. Motivated by bug report from John Hawkinson
+ (jhawk@bbnplanet.com).
+
+Sun Jul 14 18:40:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: added call to AC_CHECK_LIB(m, fmod), since
+ apparently some systems have fmod in the math library.
+ Portability: the Holy Grail. Sigh.
+
+Sun Jul 14 18:08:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h: add Jim Meyerings ISASCII etc hacks for ctype macros.
+ * builtin.c (do_toupper, do_tolower, sub_common): changed to use
+ upper-case versions of ctype macros.
+ * main.c (main): ditto.
+ * node.c (r_force_number, parse_escape): ditto.
+
+Sun Jul 14 06:34:18 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (set_record): made it always do the PERM flag.
+ Fixes cases where $0 is assigned to, e.g. by gsub, keeps
+ the fields valid.
+ (get_field): removed the call to reset_record in
+ case where ! field0_valid. We want to leave the fields alone
+ if they've been changed.
+
+Thu Jul 11 23:04:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (devopen): change tests of (flag & O_fooONLY) to
+ (flag & O_ACCMODE) == O_fooONLY. Per (long standing) bug
+ report from Chapman Flack.
+ (close_redir): change final conditional to just (status != 0)
+ so that ERRNO always set; the warning had its own `if (do_lint)'
+ anyway.
+ * eval.c (do_split): force type of array to be Node_var_array
+ instead of Node_var. Per (long standing) bug report from
+ Chapman Flack.
+
+Thu Jul 11 22:17:14 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): added symlink of gawk to awk if
+ no awk in $(bindir).
+ (LN_S): new variable for symlinking.
+ (uninstall): remove awk if it's the same gawk.
+ * Configure.in: Added call to AC_PROG_LN_S for Makefile.in.
+
+Sun Jul 7 15:47:13 1996 Arnold D. Robbins <arnold@infographix.com>
+
+ * main.c (main): made `--posix' turn on interval expressions.
+ Gawk now matches its documentation. (What a concept!)
+
+Wed Jul 3 15:02:48 1996 Arnold D. Robbins <arnold@infographix.com>
+
+ * regex.h, regex.c: upgraded to changes from Emacs 19.31.
+
+Fri May 17 08:46:07 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (get_a_record): added `continued' flag. Fix from
+ Darrell Hankerson for when RS = "\n|something".
+
+Wed May 15 02:34:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (awklib/all): now depends on gawk, fixes problem
+ with parallel make.
+
+Tue May 14 15:02:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): fix handling of '*' to deal with
+ negative value for fieldwidth -- make positive and turn on
+ left justify. Per bug report from Michael Brennan.
+
+Sun May 12 20:42:06 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (r_get_lhs): case Node_subscript. Check if array name
+ is actually a function, fatal error if so.
+
+Sun May 5 10:11:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (redirect): call flush_io() before creating a new output pipe,
+ per bug report from Brian Kernighan (bwk@research.bell-labs.com).
+
+Fri Mar 15 06:38:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): use $(INSTALL_PROGRAM), not $(INSTALL).
+ (local-distclean): add `*~' to list of files to be removed.
+ (CFLAGS): now contains just @CFLAGS@.
+ (COMPFLAGS): replaces use of CFLAGS, has CFLAGS plus all the
+ other stuff.
+
+Wed Mar 13 14:19:38 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (mmap_get_record): fixed to not place sentinel at end
+ of mmap'ed object. Won't work if file is exact multiple of
+ disk block size. See comments in code for more info.
+ Thanks to Rick Adams (rick@uunet.uu.net) for help in testing.
+
+Sun Mar 10 22:50:23 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (do_close): notice if we were called as `close(FILENAME)'
+ and arrange to close the current input file. This turns out
+ to be easy to do, just call `nextfile(TRUE)'. Based on bug report
+ from Pascal A. Dupuis, <dupuis@lei.ucl.ac.be>.
+
+Thu Mar 7 08:08:51 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (init_fields, grow_fields, set_field, rebuild_record):
+ Nuke the `nodes' array everywhere. Anytime a field is unref'ed,
+ allocate a new node that is a copy of Nnull_string. This avoids
+ subtle memory management problems when doing a lot of assignment
+ to fields, and tweaking of NF. Make sure that fields_arr[0] always
+ has a type of Node_val!
+ * field.c (set_NF): If NF is decremented, clear fields between
+ NF and parse_high_water, otherwise if NF incremented, clear
+ fields between parse_high_water and NF.
+ * eval.c (nodetype2str): new function, used for diagnostics.
+ eval.c (interpret): use nodetype2str when finding invalid node.
+
+Mon Mar 4 09:02:28 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_toupper, do_tolower): use isascii along with
+ isupper/islower before changing case, in case characters have
+ the high bit set. This is a hack.
+
+Mon Feb 26 22:24:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): if no match, and called from gensub,
+ don't free the temporary string, since the tmp_number then
+ writes over it.
+
+Sun Feb 25 23:13:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): fixed %c to treat user input as
+ numeric also by adding test for MAYBE_NUM.
+
+Tue Feb 20 12:25:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: Added AC_FUNC_MMAP call and add madvise to
+ list of functions to look for.
+ * awk.h [IOP_ISMAPPED]: new flag value for mmap support and new
+ `getrec' structure member in struct iobuf.
+ * io.c (iop_alloc, iop_close): changed to map/unmap input file
+ into memory if possible.
+ (mmap_get_record): new function to actually retrieve the
+ record from mmaped file.
+
+Thu Feb 1 08:56:46 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): fixed lint message to use indx+1 when
+ start position is past end of string.
+
+Sun Jan 28 07:00:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): rationalized handling of missing length
+ argument, as well as various accompanying lint warnings. Previous
+ code was slightly bogus. Talk about your Day 1 bugs.
+
+Thu Jan 25 14:09:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): if length exceeds length of actual
+ string, do computation of needed substring length *after*
+ the lint warning.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gawk): Add $(CFLAGS) to link line.
+ (Makefile): target depends on the Makefile.in files.
+ (OTHERS): Added TAGS and tags to the distribution.
+ (local-distclean): New rule.
+ (distclean): Use it.
+ (maintainer-clean): Don't `make distclean' before running submakes,
+ since that removes makefiles needed for the submakes.
+ * builtin.c (do_strftime): Remove hard coded limit on length of result.
+ Based on code from Paul Eggert (eggert@twinsun.com).
+
+Mon Jan 22 13:16:37 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (usage): takes new fp parameter which is either
+ stdout for `--help' (per the GNU Coding Standards) or stderr
+ if an error occurs. Fix all calls.
+ (version): prints to stdout per the coding stds.
+ (copyleft): prints to stdout now, not stderr, and exits.
+
+Fri Jan 19 08:10:29 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_GNU_AWK]: added RE_CONTEXT_INDEP_OPS to set of
+ bits we turn off for regular operation. Breaks things like
+ /^+[0-9]+/ to match a literal `+' at the beginning of, say,
+ a phone number.
+
+Wed Jan 10 23:19:36 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * 3.0.0 polished up and release tar file made.
+
+Wed Dec 27 11:46:16 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * 2.94.0 released to porting group (no, I haven't been good
+ about this file; I'll do better once 3.0 is released).
+
+Mon Aug 28 23:04:30 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h updated for NeXT - bracket TRUE/FALSE
+ * io.c (get_a_record): removed shadowing of 'start' in
+ * Makefile.in and doc/Makefile.in: fixed to use gawk.1 and gawk.texi,
+ instead of gawk.1.in and gawk.texi.in.
+
+Mon Aug 25 11:04:30 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * 2.90.0 released to porting group.
+
+Fri Aug 18 12:43:31 1995 Arnold D. Robbins <arnold@puny.ssc.com>
+
+ * ChangeLog created.
--- /dev/null
+This file lists future projects and enhancements for gawk. Items are listed
+in roughly the order they will be done for a given release. This file is
+mainly for use by the developers to help keep themselves on track, please
+don't bug us too much about schedules or what all this really means.
+
+With the 3.0 release, we are acknowledging that awk is not PERL, nor should
+it become PERL. (To paraphrase Dennis Ritchie, "If you want PERL, you
+know where to get it.")
+
+The focus on the future is thus narrowed to performance and functional
+enhancements, with only minor plans for significant new features.
+
+(OK, so 3.1 had a bad case of feature-itis. I think I'm mostly over it
+now, though. :-)
+
+In 3.1
+======
+ DONE: A PROCINFO array to replace /dev/pid, /dev/user, et al.
+
+ DONE: Provide awk profiling.
+
+ DONE: Integrate GNU NLS support.
+
+ DONE: Bring out hooks for NLS support into gawk itself.
+
+ DONE: Do a reference card.
+
+ DONE: Switch to full ANSI C and use ansi2kr.
+
+ Additional manual features:
+ DONE: Document NLS support
+
+ DONE: Add %'d for putting in commas in formatting.
+
+ DONE: Multibyte support for index, length, substr, match.
+
+For 3.2
+=======
+ Enable \s, \S in regexes (regcomp.c and dfa.c) and document them.
+
+ Make POSIX 2001 behavior the default for sub/gsub.
+
+ Simplify awk.h.
+
+ Consider moving var_value info into Node_var itself
+ to reduce memory usage.
+
+ Add IPv6 support.
+
+ Look at ISO C 99 printf features.
+
+ Consider integrating Fred Fish's DBUG library into gawk.
+
+ Move the loadable modules interface to libtool.
+
+ Redo the loadable modules interface from the awk level.
+
+ Rework management of array index storage. (Partially DONE.)
+
+ A RECLEN variable for fixed-length record input. PROCINFO["RS"]
+ would be "RS" or "RECLEN" depending upon what's in use.
+
+ Use a new or improved dfa and/or regex library.
+
+ DBM storage of awk arrays. Try to allow multiple dbm packages.
+
+ Consider removing use of and/or need for the protos.h file.
+
+ Additional manual features:
+ ? Add exercises
+ Document use of dbm arrays
+ ? Add an error messages section to the manual
+
+For 3.3
+=======
+ ? Have strftime() pay attention to the value of ENVIRON["TZ"]
+
+ Add a lint check if the return value of a function is used but
+ the function did not supply a value.
+
+ Additional manual features:
+ ? A section on where gawk is bounded
+ regex
+ i/o
+ sun fp conversions
+
+For 3.4
+=======
+ Do an optimization pass over parse tree?
+
+ Make awk '/foo/' files... run at egrep speeds (how?)
+
+For 4.x:
+========
+
+Provide awk debugging.
--- /dev/null
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PREFIX', the package will
+use PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
--- /dev/null
+This file describes limits of gawk on a Unix system (although it
+is variable even then). Non-Unix systems may have other limits.
+
+# of fields in a record: MAX_LONG
+Length of input record: MAX_INT
+Length of output record: unlimited
+Size of a field: MAX_INT
+Size of a printf string: MAX_INT
+Size of a literal string: MAX_INT
+Characters in a character class: 2^(# of bits per byte)
+# of file redirections: unlimited
+# of pipe redirections: min(# of processes per user, # of open files)
+double-precision floating point
+Length of source line: unlimited
+Number of input records in one file: MAX_LONG
+Number of input records total: MAX_LONG
--- /dev/null
+#
+# Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2000-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+## process this file with automake to produce Makefile.in
+
+# Automatic de-ANSI-fication if needed, make .bz2 files also.
+AUTOMAKE_OPTIONS = ansi2knr dist-bzip2
+
+# This undocumented variable insures that aclocal runs
+# correctly after changing configure.ac
+ACLOCAL_AMFLAGS = -I m4
+
+# This insures that make flags get passed down to child makes.
+AM_MAKEFLAGS = 'CFLAGS=$(CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
+
+# Stuff to include in the dist that doesn't need it's own
+# Makefile.am files
+EXTRA_DIST = \
+ COPYING \
+ FUTURES \
+ INSTALL \
+ LIMITATIONS \
+ NEWS \
+ POSIX.STD \
+ PROBLEMS \
+ README_d \
+ bisonfix.awk \
+ config.guess \
+ config.rpath \
+ config.sub \
+ depcomp \
+ extension \
+ m4 \
+ missing \
+ missing_d \
+ pc \
+ posix \
+ regcomp.c \
+ regex_internal.c \
+ regex_internal.h \
+ regexec.c \
+ unsupported \
+ version.in \
+ vms \
+ ylwrap
+
+# The order to do things in.
+# Build explicitly in "." in order to build gawk first, so
+# that `make check' without a prior `make' works.
+SUBDIRS = \
+ . \
+ awklib \
+ doc \
+ po \
+ test
+
+# what to make and install
+bin_PROGRAMS = gawk pgawk
+
+# sources for both gawk and pgawk
+base_sources = \
+ array.c \
+ awk.h \
+ awkgram.y \
+ builtin.c \
+ custom.h \
+ dfa.c \
+ dfa.h \
+ ext.c \
+ field.c \
+ gawkmisc.c \
+ getopt.c \
+ getopt.h \
+ getopt1.c \
+ getopt_int.h \
+ gettext.h \
+ hard-locale.h \
+ io.c \
+ mbsupport.h \
+ main.c \
+ msg.c \
+ node.c \
+ protos.h \
+ random.c \
+ random.h \
+ re.c \
+ regex.c \
+ regex.h \
+ replace.c \
+ version.c
+
+gawk_SOURCES = $(base_sources) eval.c profile.c
+pgawk_SOURCES = $(base_sources) eval_p.c profile_p.c
+
+# Get extra libs as needed, Automake will supply LIBINTL and SOCKET_LIBS.
+LDADD = $(LIBINTL) $(SOCKET_LIBS)
+
+# Directory for gawk's data files. Automake supplies datadir.
+pkgdatadir = $(datadir)/awk
+
+# stuff for compiling gawk/pgawk
+DEFPATH="\".$(PATH_SEPARATOR)$(pkgdatadir)\""
+
+DEFS= -DDEFPATH=$(DEFPATH) -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR="\"$(datadir)/locale\""
+
+AM_CPPFLAGS =
+
+# Get rid of core files when cleaning
+CLEANFILES = core core.*
+
+MAINTAINERCLEANFILES = version.c awkgram.c
+
+# We want hard links for install-exec-hook, below
+LN= ln
+
+SUFFIXES = .i
+.c.i:
+ $(COMPILE) -E $< > $@
+
+# First, add a link from gawk to gawk-X.Y.Z.
+# Same for pgawk.
+#
+# For GNU systems where gawk is awk, add a link to awk.
+# (This is done universally, which may not always be right, but
+# there's no easy way to distinguish GNU from non-GNU systems.)
+install-exec-hook:
+ (cd $(DESTDIR)$(bindir); \
+ $(LN) gawk$(EXEEXT) gawk-$(VERSION)$(EXEEXT) 2>/dev/null ; \
+ $(LN) pgawk$(EXEEXT) pgawk-$(VERSION)$(EXEEXT) 2>/dev/null ; \
+ if [ ! -f awk$(EXEEXT) ]; \
+ then $(LN_S) gawk$(EXEEXT) awk$(EXEEXT); \
+ fi; exit 0)
+
+# Undo the above when uninstalling
+uninstall-links:
+ (cd $(DESTDIR)$(bindir); \
+ if [ -f awk$(EXEEXT) ] && cmp awk$(EXEEXT) gawk$(EXEEXT) > /dev/null; then rm -f awk$(EXEEXT); fi ; \
+ rm -f gawk-$(VERSION)$(EXEEXT) pgawk-$(VERSION)$(EXEEXT); exit 0)
+
+uninstall-recursive: uninstall-links
+
+# force there to be a gawk executable before running tests
+check-local: gawk$(EXEEXT) pgawk$(EXEEXT)
+
+# A little extra clean up when making distributions.
+# FIXME: most of this rule should go away upon switching to libtool.
+dist-hook:
+ cd $(distdir)/extension ; rm -f *.o *.so
+
+# Special rules for individual files
+awkgram.c: awkgram.y
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $<
+ awk -f $(srcdir)/bisonfix.awk y.tab.c > $*.c && rm y.tab.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+
+# This is for my development & testing.
+efence: gawk
+ $(CC) $(LDFLAGS) -o gawk $$(ls *.o | grep -v '_p.o$$') $(LIBS) -lefence
+
+diffout:
+ @$(MAKE) -C test $@
--- /dev/null
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2000-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+SOURCES = $(gawk_SOURCES) $(pgawk_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ANSI2KNR = @ANSI2KNR@
+bin_PROGRAMS = gawk$(EXEEXT) pgawk$(EXEEXT)
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/configh.in \
+ $(srcdir)/version.in $(top_srcdir)/configure ABOUT-NLS AUTHORS \
+ COPYING ChangeLog INSTALL NEWS ansi2knr.1 ansi2knr.c awkgram.c \
+ config.guess config.rpath config.sub depcomp install-sh \
+ missing mkinstalldirs ylwrap
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/socket.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/strtod.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = version.c
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am__objects_1 = array$U.$(OBJEXT) awkgram$U.$(OBJEXT) \
+ builtin$U.$(OBJEXT) dfa$U.$(OBJEXT) ext$U.$(OBJEXT) \
+ field$U.$(OBJEXT) gawkmisc$U.$(OBJEXT) getopt$U.$(OBJEXT) \
+ getopt1$U.$(OBJEXT) io$U.$(OBJEXT) main$U.$(OBJEXT) \
+ msg$U.$(OBJEXT) node$U.$(OBJEXT) random$U.$(OBJEXT) \
+ re$U.$(OBJEXT) regex$U.$(OBJEXT) replace$U.$(OBJEXT) \
+ version$U.$(OBJEXT)
+am_gawk_OBJECTS = $(am__objects_1) eval$U.$(OBJEXT) \
+ profile$U.$(OBJEXT)
+gawk_OBJECTS = $(am_gawk_OBJECTS)
+gawk_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+gawk_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_pgawk_OBJECTS = $(am__objects_1) eval_p$U.$(OBJEXT) \
+ profile_p$U.$(OBJEXT)
+pgawk_OBJECTS = $(am_pgawk_OBJECTS)
+pgawk_LDADD = $(LDADD)
+pgawk_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+YLWRAP = $(top_srcdir)/ylwrap
+SOURCES = $(gawk_SOURCES) $(pgawk_SOURCES)
+DIST_SOURCES = $(gawk_SOURCES) $(pgawk_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+
+# Directory for gawk's data files. Automake supplies datadir.
+pkgdatadir = $(datadir)/awk
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = -DDEFPATH=$(DEFPATH) -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR="\"$(datadir)/locale\""
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMSGFMT = @GMSGFMT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+STRIP = @STRIP@
+U = @U@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+# Automatic de-ANSI-fication if needed, make .bz2 files also.
+AUTOMAKE_OPTIONS = ansi2knr dist-bzip2
+
+# This undocumented variable insures that aclocal runs
+# correctly after changing configure.ac
+ACLOCAL_AMFLAGS = -I m4
+
+# This insures that make flags get passed down to child makes.
+AM_MAKEFLAGS = 'CFLAGS=$(CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
+
+# Stuff to include in the dist that doesn't need it's own
+# Makefile.am files
+EXTRA_DIST = \
+ COPYING \
+ FUTURES \
+ INSTALL \
+ LIMITATIONS \
+ NEWS \
+ POSIX.STD \
+ PROBLEMS \
+ README_d \
+ bisonfix.awk \
+ config.guess \
+ config.rpath \
+ config.sub \
+ depcomp \
+ extension \
+ m4 \
+ missing \
+ missing_d \
+ pc \
+ posix \
+ regcomp.c \
+ regex_internal.c \
+ regex_internal.h \
+ regexec.c \
+ unsupported \
+ version.in \
+ vms \
+ ylwrap
+
+
+# The order to do things in.
+# Build explicitly in "." in order to build gawk first, so
+# that `make check' without a prior `make' works.
+SUBDIRS = \
+ . \
+ awklib \
+ doc \
+ po \
+ test
+
+
+# sources for both gawk and pgawk
+base_sources = \
+ array.c \
+ awk.h \
+ awkgram.y \
+ builtin.c \
+ custom.h \
+ dfa.c \
+ dfa.h \
+ ext.c \
+ field.c \
+ gawkmisc.c \
+ getopt.c \
+ getopt.h \
+ getopt1.c \
+ getopt_int.h \
+ gettext.h \
+ hard-locale.h \
+ io.c \
+ mbsupport.h \
+ main.c \
+ msg.c \
+ node.c \
+ protos.h \
+ random.c \
+ random.h \
+ re.c \
+ regex.c \
+ regex.h \
+ replace.c \
+ version.c
+
+gawk_SOURCES = $(base_sources) eval.c profile.c
+pgawk_SOURCES = $(base_sources) eval_p.c profile_p.c
+
+# Get extra libs as needed, Automake will supply LIBINTL and SOCKET_LIBS.
+LDADD = $(LIBINTL) $(SOCKET_LIBS)
+
+# stuff for compiling gawk/pgawk
+DEFPATH = "\".$(PATH_SEPARATOR)$(pkgdatadir)\""
+AM_CPPFLAGS =
+
+# Get rid of core files when cleaning
+CLEANFILES = core core.*
+MAINTAINERCLEANFILES = version.c awkgram.c
+
+# We want hard links for install-exec-hook, below
+LN = ln
+SUFFIXES = .i
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .i .c .o .obj .y
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+ cd $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/configh.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/configh.in: $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+version.c: $(top_builddir)/config.status $(srcdir)/version.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+gawk$(EXEEXT): $(gawk_OBJECTS) $(gawk_DEPENDENCIES)
+ @rm -f gawk$(EXEEXT)
+ $(LINK) $(gawk_LDFLAGS) $(gawk_OBJECTS) $(gawk_LDADD) $(LIBS)
+pgawk$(EXEEXT): $(pgawk_OBJECTS) $(pgawk_DEPENDENCIES)
+ @rm -f pgawk$(EXEEXT)
+ $(LINK) $(pgawk_LDFLAGS) $(pgawk_OBJECTS) $(pgawk_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+ansi2knr: ansi2knr.$(OBJEXT)
+ $(LINK) ansi2knr.$(OBJEXT) $(LIBS)
+ansi2knr.$(OBJEXT): $(CONFIG_HEADER)
+
+clean-krextra:
+ -rm -f ansi2knr
+
+mostlyclean-kr:
+ -test "$U" = "" || rm -f *_.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awkgram$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfa$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_p$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/field$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gawkmisc$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile_p$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/re$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replace$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version$U.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+array_.c: array.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/array.c; then echo $(srcdir)/array.c; else echo array.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+awkgram_.c: awkgram.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/awkgram.c; then echo $(srcdir)/awkgram.c; else echo awkgram.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+builtin_.c: builtin.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/builtin.c; then echo $(srcdir)/builtin.c; else echo builtin.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+dfa_.c: dfa.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/dfa.c; then echo $(srcdir)/dfa.c; else echo dfa.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+eval_.c: eval.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/eval.c; then echo $(srcdir)/eval.c; else echo eval.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+eval_p_.c: eval_p.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/eval_p.c; then echo $(srcdir)/eval_p.c; else echo eval_p.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+ext_.c: ext.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ext.c; then echo $(srcdir)/ext.c; else echo ext.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+field_.c: field.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/field.c; then echo $(srcdir)/field.c; else echo field.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+gawkmisc_.c: gawkmisc.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/gawkmisc.c; then echo $(srcdir)/gawkmisc.c; else echo gawkmisc.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+getopt_.c: getopt.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/getopt.c; then echo $(srcdir)/getopt.c; else echo getopt.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+getopt1_.c: getopt1.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/getopt1.c; then echo $(srcdir)/getopt1.c; else echo getopt1.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+io_.c: io.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/io.c; then echo $(srcdir)/io.c; else echo io.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+main_.c: main.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/main.c; then echo $(srcdir)/main.c; else echo main.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+msg_.c: msg.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/msg.c; then echo $(srcdir)/msg.c; else echo msg.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+node_.c: node.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/node.c; then echo $(srcdir)/node.c; else echo node.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+profile_.c: profile.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/profile.c; then echo $(srcdir)/profile.c; else echo profile.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+profile_p_.c: profile_p.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/profile_p.c; then echo $(srcdir)/profile_p.c; else echo profile_p.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+random_.c: random.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/random.c; then echo $(srcdir)/random.c; else echo random.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+re_.c: re.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/re.c; then echo $(srcdir)/re.c; else echo re.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+regex_.c: regex.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/regex.c; then echo $(srcdir)/regex.c; else echo regex.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+replace_.c: replace.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/replace.c; then echo $(srcdir)/replace.c; else echo replace.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+version_.c: version.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/version.c; then echo $(srcdir)/version.c; else echo version.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+array_.$(OBJEXT) awkgram_.$(OBJEXT) builtin_.$(OBJEXT) dfa_.$(OBJEXT) \
+eval_.$(OBJEXT) eval_p_.$(OBJEXT) ext_.$(OBJEXT) field_.$(OBJEXT) \
+gawkmisc_.$(OBJEXT) getopt_.$(OBJEXT) getopt1_.$(OBJEXT) io_.$(OBJEXT) \
+main_.$(OBJEXT) msg_.$(OBJEXT) node_.$(OBJEXT) profile_.$(OBJEXT) \
+profile_p_.$(OBJEXT) random_.$(OBJEXT) re_.$(OBJEXT) regex_.$(OBJEXT) \
+replace_.$(OBJEXT) version_.$(OBJEXT) : $(ANSI2KNR)
+
+.y.c:
+ $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) configh.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) configh.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ mkdir $(distdir)
+ $(mkdir_p) $(distdir)/. $(distdir)/m4 $(distdir)/po
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+all-am: Makefile $(ANSI2KNR) $(PROGRAMS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f awkgram.c
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-krextra mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic mostlyclean-kr
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+ check-am check-local clean clean-binPROGRAMS clean-generic \
+ clean-krextra clean-recursive ctags ctags-recursive dist \
+ dist-all dist-bzip2 dist-gzip dist-hook dist-shar dist-tarZ \
+ dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-recursive \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-exec \
+ install-exec-am install-exec-hook install-info install-info-am \
+ install-man install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-kr mostlyclean-recursive pdf pdf-am ps ps-am tags \
+ tags-recursive uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-info-am
+
+.c.i:
+ $(COMPILE) -E $< > $@
+
+# First, add a link from gawk to gawk-X.Y.Z.
+# Same for pgawk.
+#
+# For GNU systems where gawk is awk, add a link to awk.
+# (This is done universally, which may not always be right, but
+# there's no easy way to distinguish GNU from non-GNU systems.)
+install-exec-hook:
+ (cd $(DESTDIR)$(bindir); \
+ $(LN) gawk$(EXEEXT) gawk-$(VERSION)$(EXEEXT) 2>/dev/null ; \
+ $(LN) pgawk$(EXEEXT) pgawk-$(VERSION)$(EXEEXT) 2>/dev/null ; \
+ if [ ! -f awk$(EXEEXT) ]; \
+ then $(LN_S) gawk$(EXEEXT) awk$(EXEEXT); \
+ fi; exit 0)
+
+# Undo the above when uninstalling
+uninstall-links:
+ (cd $(DESTDIR)$(bindir); \
+ if [ -f awk$(EXEEXT) ] && cmp awk$(EXEEXT) gawk$(EXEEXT) > /dev/null; then rm -f awk$(EXEEXT); fi ; \
+ rm -f gawk-$(VERSION)$(EXEEXT) pgawk-$(VERSION)$(EXEEXT); exit 0)
+
+uninstall-recursive: uninstall-links
+
+# force there to be a gawk executable before running tests
+check-local: gawk$(EXEEXT) pgawk$(EXEEXT)
+
+# A little extra clean up when making distributions.
+# FIXME: most of this rule should go away upon switching to libtool.
+dist-hook:
+ cd $(distdir)/extension ; rm -f *.o *.so
+
+# Special rules for individual files
+awkgram.c: awkgram.y
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $<
+ awk -f $(srcdir)/bisonfix.awk y.tab.c > $*.c && rm y.tab.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+
+# This is for my development & testing.
+efence: gawk
+ $(CC) $(LDFLAGS) -o gawk $$(ls *.o | grep -v '_p.o$$') $(LIBS) -lefence
+
+diffout:
+ @$(MAKE) -C test $@
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Changes from 3.1.4 to 3.1.5
+---------------------------
+
+1. The random() suite has been updated to a current FreeBSD version, which
+ works on systems with > 32-bit ints.
+
+2. A new option, `--exec' has been added. It's like -f but ends option
+ processing. It also disables `x=y' variable assignments, but not -v.
+ It's needed mainly for CGI scripts, so that source code can't be
+ passed in as part of the URL.
+
+3. dfa.[ch] have been synced with GNU grep development. This also fixes
+ multiple regex matching problems in multibyte locales.
+
+4. Updated to Automake 1.9.5.
+
+5. Updated to Bison 2.0.
+
+6. The getopt* and regex* files were synchronized with current GLIBC CVS.
+ See the ChangeLog for the versions and minor edits made.
+
+7. `configure --disable-nls' now disables just gawk's own translations.
+ Gawk continues to work with the locale's numeric formatting. This
+ includes a bug fix in handling the printf ' flag (e.g., %'d).
+
+8. Gawk is now multibyte aware. This means that index(), length(),
+ substr() and match() all work in terms of characters, not bytes.
+
+9. Gawk is now smarter about parsing numeric constants in corner cases.
+
+11. Not closing open redirections no longer causes gawk to exit non-zero.
+
+10. The VMS port has been updated.
+
+11. Changes from Andrew Schorr at the xmlgawk project to provide for
+ open hooks from extensions are now included. This will let the
+ xmlgawk extension work in the standard gawk.
+
+12. Updated to gettext 0.14.4. Gawk no longer includes its own copy
+ of the gettext `intl' library, following current GNU practice to
+ rely on there being an external version thereof.
+
+13. A regexp of the form `//' will now generate a warning that it
+ is not a C++ comment from --lint (awk.y).
+
+14. The ^ and ^= operators with an integer exponent now use Exponentiation
+ by Squaring. This simultaneously fixes a problem with ^= and a negative
+ integer exponent.
+
+15. length(array) now returns the number of elements in the array. This is
+ is a non-standard extension that will fail in POSIX mode.
+
+16. Carriage return characters are now ignored in program source code.
+
+17. Four new translations added.
+
+18. Various minor bugs fixed. See the ChangeLog for the details.
+
+Changes from 3.1.3 to 3.1.4
+---------------------------
+
+1. Gawk now supports the POSIX %F format, falling back to %f if the local
+ system printf doesn't handle it.
+
+2. Gawk now supports the ' flag in printf. E.g., %'d in a locale with thousands
+ separators includes the thousands separator in the value, e.g. 12,345.
+
+ This has one problem; the ' flag is next to impossible to use on the
+ command line, without major quoting games. Oh well, TANSTAAFL.
+
+3. The dfa code has been reinstated; the performance degradation was
+ just too awful. Sigh. (For fun, use `export GAWK_NO_DFA=1' to
+ see the difference.)
+
+4. The special case `x = x y' is now recognized in the grammar, and gawk
+ now uses `realloc' to append the new value to the end of the existing
+ one. This can speed up the common case of appending onto a string.
+
+5. The dfa code was upgraded with most of the fixes from grep 2.5.1, and
+ the regex code was upgraded with GLIBC as mid-January 2004. The regex
+ code is faster than it was, but still not as fast as the dfa code, so
+ the dfa code stays in. The getopt code was also synced to current GLIBC.
+
+6. Support code upgraded to Automake 1.8.5, Autoconf 2.59, and gettext 0.14.1.
+
+7. When --posix is in effect, sub/gsub now follow the 2001 POSIX behavior.
+ Yippee. This is even documented in the manual.
+
+8. Gawk will now recover children that have died (input pipelines, two-way
+ pipes), upon detecting EOF from them, thus avoiding filling
+ up the process table. Open file descriptors are not recovered
+ (unfortunately), since that could break awk semantics. See the
+ ChangeLog and the source code for the details.
+
+9. Handling of numbers like `0,1' in non-American locales ought to
+ work correctly now.
+
+10. IGNORECASE is now locale-aware for characters with values above 128.
+ The dfa matcher is now used for IGNORECASE matches too.
+
+11. Dynamic function loading is better. The documentation has been improved
+ and some new APIs for use by dynamic functions have been added.
+
+12. Gawk now has a fighting chance of working on older systems,
+ a la SunOS 4.1.x.
+
+13. Issues with multibyte support on HP-UX are now resolved. `configure' now
+ disables such support there, since it's not up to what gawk needs.
+
+14. There are now even more tests in the test suite.
+
+15. Various bugs fixed; see ChangeLog for the details.
+
+Changes from 3.1.2 to 3.1.3
+---------------------------
+
+1. Gawk now follows POSIX in handling of local numeric formats for
+ input, output and number/string conversions.
+
+2. Multibyte detection improved. See README_d/README.multibyte for more
+ info about multibyte locales.
+
+3. Handling of `close' made more POSIX-compliant for POSIXLY_CORRECT,
+ see the documentation.
+
+4. The record reading code was redone, again. This time it's much
+ better. Really!
+
+5. For RS = "\n" and RS = "", gawk now only sets RT when it has changed.
+ This provides considerable performance improvement.
+
+6. `match' now sets all the subscripts in the third argument array
+ correctly, even if not all subexpressions matched.
+
+7. Updated to Automake 1.7.5. configure.in renamed configure.ac.
+
+8. C-style switch statements are available, but must be enabled at
+ compile time via `configure --enable-switch'. For 3.2 they'll be
+ enabled by default. Thanks to Michael Benzinger for the initial
+ code.
+
+9. %c now always prints no more than one character, whatever
+ precision is provided.
+
+10. strtonum(<number>) now works again.
+
+11. Gawk is now much better about scalar/array typing of global
+ uninitiailzed variables passed as parameters. Once the parameter
+ is then used one way or the other, the global var's type is
+ adjusted accordingly. Thanks to Stepan Kasal for the original
+ (considerable) changes.
+
+12. Dynamic function loading under Windows32 should now be possible. See
+ README_d/README.pcdynamic. Thanks to Patrick T.J. McPhee for the changes.
+
+13. Updated to gettext 0.12.1.
+
+14. Gawk now follows historical practice and POSIX for the return
+ value of `rand': It's now 0 <= N < 1.
+
+Changes from 3.1.1 to 3.1.2
+---------------------------
+
+1. Loops of the form:
+
+ for (iggy in foo)
+ next
+
+ no longer leak memory.
+
+2. gawk -v FIELDWIDTHS="..." now sets PROCINFO["FS"] correctly.
+
+3. All builtin operations and functions should now fully evaluate their
+ arguments so that side effects take place correctly.
+
+4. Fixed a logic bug in gsub/gensub for matches to null strings that occurred
+ later in the string after a nonnull match.
+
+5. getgroups code now works on Ultrix again.
+
+6. Completely new version of the full GNU regex engine now in place.
+
+7. Argument parsing and variable assignment has been cleaned up.
+
+8. An I/O bug on HP-UX has been documented and worked around. See
+ README_d/README.hpux.
+
+9. awklib/grcat should now compile correctly.
+
+10. Updated to automake 1.7.3, autoconf 2.57 and gettext 0.11.5 ; thanks to
+ Paul Eggert for the initial automake and autoconf work.
+
+11. As a result of #6, removed the use of the dfa code from GNU grep.
+
+12. It is now possible to use ptys for |& two-way pipes instead of
+ pipes. The basic plumbing for this was provided by Paolo Bonzini.
+ To make this happen:
+
+ command = "unix command etc"
+ PROCINFO[command, "pty"] = 1
+
+ print ... |& command
+ command |& getline stuff
+
+ In other words, set the element in PROCINFO *before* opening the
+ two-way pipe, and then gawk will use ptys instead of pipes.
+
+ On systems without ptys or where all the ptys are in use, gawk
+ will fall back to using plain pipes.
+
+13. Fixed a regex matching across buffer boundaries bug, with a
+ heuristic. See io.c:rsre_get_a_record.
+
+14. Profiling no longer dumps core if there are extension functions in place.
+
+15. Grammar and scanner cleaned up, courtesy of Stepen Kasal, to hopefully
+ once and for all fix the `/=' operator vs. `/=.../' regex ambiguity.
+ Lots of other grammar simplifications applied, as well.
+
+16. BINMODE should work now on more Windows ports.
+
+17. Updated to bison 1.875. Includes fix to bisonfix.sed script.
+
+18. The NODE structure is now 20% (8 bytes) smaller (on x86, anyway), which
+ should help conserve memory.
+
+19. Builds not in the source directory should work again.
+
+20. Arrays now use 2 NODE's per element instead of three. Combined with
+ #18, (on the x86) this reduces the overhead from 120 bytes per element
+ to just 64 bytes: almost a 50% improvement.
+
+21. Programs that make heavy use of changing IGNORECASE should now be
+ much faster, particularly if using a regular expression for FS or RS.
+ IGNORECASE now correctly affects RS regex record splitting, as well.
+
+22. IGNORECASE no longer affects single-character field splitting (FS = "c"),
+ or single-character record splitting (RS = "c").
+
+ This cleans up some weird behavior, and makes gawk better match the
+ documentation, which says it only affects regex-based field splitting
+ and record splitting.
+
+ The documentation on this was improved, too.
+
+23. The framework in test/ has been simplified, making it much easier to
+ add new tests while keeping the size of Makefile.am reasonable. Thanks
+ for this to Stepan Kasal.
+
+24. --lint=invalid causes lint warnings only about stuff that's actually
+ invalid. This needs additional work.
+
+25. More translations.
+
+26. The `get_a_record' routine has been revamped (currently by splitting it
+ into three variants). This should improve long-term maintainability.
+
+27. `match' now adds more entries to 3rd array arg:
+ match("the big dog", /([a-z]+) ([a-z]+) ([a-z]+)/, data)
+ fills in variables:
+ data[1, "start"], data[1, "length"], and so on.
+
+28. New `asorti' function with same interface as `asort', but sorts indices
+ instead of values.
+
+29. Documentation updated to FDL 1.2.
+
+30. New `configure' option --disable-lint at compile time disables lint
+ checking. With GCC dead-code-elimination, cuts almost 200K off the
+ executable size on GNU/Linux x86. Presumably speeds up runtime.
+
+ Using this will cause some of the tests in the test suite to fail.
+ This option may be removed at a later date.
+
+31. Various minor cleanups, see the ChangeLog for details.
+
+Changes from 3.1.0 to 3.1.1
+---------------------------
+
+1. Six new translations.
+
+2. Having more than 4 different values for OFMT and/or CONVFMT now works.
+
+3. The handling of dynamic regexes is now more more sane, esp. w.r.t.
+ the profiling code. The profiling code has been fixed in several
+ places.
+
+4. The return value of index("", "") is now 1.
+
+5. Gawk should no longer close fd 0 in child processes.
+
+6. Fixed test for strtod semantics and regenerated configure.
+
+7. Gawk can now be built with byacc; an accidental bison dependency was
+ removed.
+
+8. `yyerror' will no longer dump core on long source lines.
+
+9. Gawk now correctly queries getgroups(2) to figure out how many groups
+ the process has.
+
+10. New configure option to force use of included strftime, e.g. on
+ Solaris systems. See `./configure --help' for the details. Replaced
+ the included strftime.c with the one from textutils.
+
+11. OS/2 port has been updated.
+
+12. Multi-byte character support has been added, courtesy of IBM Japan.
+
+13. The `for (iggy in foo) delete foo[iggy]' -> `delete foo' optimisation
+ now works.
+
+14. Upgraded to gettext 0.11.2 and automake 1.5.
+
+15. Full gettext compatibility (new dcngettext function).
+
+16. The O'Reilly copyedits and indexing changes for the documentation have
+ been folded into the texinfo version of the manuals.
+
+17. A humongously long value for the AWKPATH environment variable will no
+ longer dump core.
+
+18. Configuration / Installation issues have been straightened out in
+ Makefile.am.
+
+Changes from 3.0.6 to 3.1.0
+---------------------------
+
+1. A new PROCINFO array provides info about the process. The non-I/O /dev/xxx
+ files are now obsolete, and their use always generates a warning.
+
+2. A new `mktime' builtin function was added for creating time stamps. The
+ `mktime' function written in awk was removed from the user's guide.
+
+3. New `--gen-po' option creates GNU gettext .po files for strings marked
+ with a leading underscore.
+
+4. Gawk now completely interprets special file names internally, ignoring the
+ existence of real /dev/stdin, /dev/stdout files, etc.
+
+5. The mmap code was removed. It was a worthwhile experiment that just
+ didn't work out.
+
+6. The BINMODE variable is new; on non-UNIX systems it affects how gawk
+ opens files for text vs. binary.
+
+7. The atari port is now unsupported.
+
+8. Gawk no longer supports `next file' as two words.
+
+9. On systems that support it, gawk now sets the `close on exec' flag on all
+ files and pipes it opens. This makes sure that child processes run via
+ `system' or pipes have plenty of file descriptors available.
+
+10. New ports: Tandem and BeOS. The Tandem port is unsupported.
+
+11. If `--posix' is in effect, newlines are not allowed after ?:.
+
+12. Weird OFMT/CONVFMT formats no longer cause fatal errors.
+
+13. Diagnostics about array parameters now include the parameter's name,
+ not just its number.
+
+14. configure should now automatically add -D_SYSV3 for ISC Unix.
+ (This seems to have made it into the gawk 3.0.x line long ago.)
+
+15. It is now possible to open a two-way pipe via the `|&' operator.
+ See the discussion in the manual about putting `sort' into such a pipeline,
+ though. (NOTE! This is borrowed from ksh: it is not the same as
+ the same operator in csh!)
+
+16. The `close' function now takes an optional second string argument
+ that allows closing one or the other end of the two-way pipe to
+ a co-process. This is needed to use `sort' in a co-process, see
+ the doc.
+
+17. If TCP/IP is available, special file names beginning with `/inet'
+ can be used with `|&' for IPC. Thanks to Juergen Kahrs for the initial
+ code.
+
+18. With `--enable-portals' on the configure command line, gawk will also
+ treat file names that start with `/p/' as a 4.4 BSD type portal file,
+ i.e., a two-way pipe for `|&'.
+
+19. Unrecognized escapes, such as "\q" now always generate a warning.
+
+20. The LINT variable is new; it provides dynamic control over the --lint
+ option.
+
+21. Lint warnings can be made fatal by using --lint=fatal or `LINT = "fatal"'.
+ Use this if you're really serious about portable code.
+
+22. Due to an enhanced sed script, there is no longer any need to worry
+ about finding or using alloca. alloca.c is thus now gone.
+
+23. A number of lint warnings have been added. Most notably, gawk will
+ detect if a variable is used before assigned to. Warnings for
+ when a string that isn't a number gets converted to a number are
+ in the code but disabled; they seem to be too picky in practice.
+
+ Also, gawk will now warn about function parameter names that shadow
+ global variable names.
+
+24. It is now possible to dynamically add builtin functions on systems
+ that support dlopen. This facility is not (yet) as portable or well
+ integrated as it might be. *** WARNING *** THIS FEATURE WILL EVOLVE!
+
+25. There are *many* new tests in the test suite.
+
+26. Profiling has been added! A separate version of gawk, named pgawk, is
+ built and generates a run-time execution profile. The --profile option
+ can be used to change the default output file. In regular gawk, this
+ option pretty-prints the parse tree.
+
+27. Gawk has been internationalized, using GNU gettext. Translations for
+ future distributions are most welcome. Simultaneously, gawk was switched
+ over to using automake. You need Automake 1.4a (from the CVS archive)
+ if you want to muck with the Makefile.am files.
+
+28. New `asort' function for sorting arrays. See the doc for details.
+
+29. The match function takes an optional array third argument to hold
+ the text matched by parenthesized sub-expressions.
+
+30. The bit op functions and octal and hex source code constants are on by
+ default, no longer a configure-time option. Recognition of non-decimal
+ data is now enabled at runtime with --non-decimal-data command line option.
+
+31. Internationalization features available at the awk level: new TEXTDOMAIN
+ variable and `bindtextdomain' and `dcgettext' functions. printf formats
+ may contain the "%2$3.5d" kind of notation for use in translations. See
+ the texinfo manual for details.
+
+32. The return value from `close' has been rationalized. Most notably,
+ closing something that wasn't open returns -1 but remains non-fatal.
+
+33. The array effeciency change from 3.0.5 was reverted; the semantics were
+ not right. Additionally, index values of previously stored elements
+ can no longer change dynamically.
+
+34. The new option --dump-variables dumps a list of all global variables and
+ their final types and values to a file you give, or to `awkvars.out'.
+
+35. Gawk now uses a recent version of random.c courtesy of the FreeBSD
+ project.
+
+36. The gawk source code now uses ANSI C function definitions (new style),
+ with ansi2knr to translate code for old compilers.
+
+37. `for (iggy in foo)' loops should be more robust now in the face of
+ adding/deleting elements in the middle; they loop over just the elements
+ that are present in the array when the loop starts.
+
+Changes from 3.0.5 to 3.0.6
+---------------------------
+
+This is a bug fix release only, pending further development on 3.1.0.
+
+Bugs fixed and changes made:
+
+1. Subscripting an array with a variable that is just a number no
+ longer magically converts the variable into a string.
+
+2. Similarly, running a `for (iggy in foo)' loop where `foo' is a
+ function parameter now works correctly.
+
+3. Similarly, `i = ""; v[i] = a; if (i in v) ...' now works again.
+
+4. Gawk now special cases `for (iggy in foo) delete foo[iggy]' and
+ treats it as the moral equivalent of `delete foo'. This should be
+ a major efficiency win when portably deleting large arrays.
+
+5. VMS port brought up to date.
+
+Changes from 3.0.4 to 3.0.5
+---------------------------
+
+This is a bug fix release only, pending further development on 3.1.0.
+
+Bugs Fixed:
+
+ 1. `function foo(foo)' is now a fatal error.
+
+ 2. Array indexing is now much more efficient: where possible, only one
+ copy of an index string is kept, even if used in multiple arrays.
+
+ 3. Support was added for MacOS X and an `install-strip' target.
+
+ 4. [s]printf formatting for `0' flag and floating point formats now
+ works correctly.
+
+ 5. HP-UX large file support with GCC 2.95.1 now works.
+
+ 6. Arguments that contain `=' but that aren't syntactically valid are
+ now treated as filenames, instead of as fatal errors.
+
+ 7. `-v NF=foo' now works.
+
+ 8. Non-ascii alphanumeric characters are now treated as such in the
+ right locales by regex.c. Similarly, a Latin-1 y-umlaut (decimal
+ value 255) in the program text no longer acts like EOF.
+
+ 9. Array indexes are always compared as strings; fixes an obscure bug
+ when user input gets used for the `x in array' test.
+
+10. The usage message now points users to the documentation for how
+ to report bugs.
+
+11. `/=' now works after an array.
+
+12. `b += b += 1' now works correctly.
+
+13. IGNORECASE changing with calls `match' now works better. (Fix for
+ semi-obscure bug.)
+
+14. Multicharacter values for RS now generate a lint warning.
+
+15. The gawk open file caching is now much more efficient.
+
+16. Global arrays passed to functions are now managed better. In particular,
+ test/arynocls.awk won't crash referencing freed memory.
+
+17. In obscure cases, `getline var' can no longer clobber $0.
+
+Changes from 3.0.3 to 3.0.4
+---------------------------
+
+This is a bug fix release only, pending further development on 3.1.0.
+
+Bugs Fixed:
+
+ 1. A memory leak when turning a function parameter into an array was
+ fixed.
+
+ 2. The non-decimal data option now works correctly.
+
+ 3. Using an empty pair of brackets as an array subscript no longer causes
+ a core dump during parsing. In general, syntax errors should not
+ cause core dumps any more.
+
+ 4. Standard input is no longer closed if it provides program source,
+ avoiding strange I/O problems.
+
+ 5. Memory corruption during printing with `print' has been fixed.
+
+ 6. The gsub function now correctly counts the number of matches.
+
+ 7. A typo in doc/Makefile.in has been fixed, making installation work.
+
+ 8. Calling `next' or `nextfile' from a BEGIN or END rule is now fatal.
+
+ 9. Subtle problems in rebuilding $0 when fields were changed have been
+ fixed.
+
+10. `FS = FS' now correctly turns off the use of FIELDWIDTHS.
+
+11. Gawk now parses fields correctly when FS is a single character.
+
+12. It is now possible for RS to be the NUL character ("\0").
+
+13. Weird problems with number conversions on MIPS and other systems
+ have been fixed.
+
+14. When parsing using FIELDWIDTHS is in effect, `split' with no third
+ argument will still use the value of FS.
+
+15. Large File Support for Solaris, HP-UX, AIX, and IRIX is now enabled at
+ compile time, thanks to Paul Eggert.
+
+16. Attempting to use the name of a function as a variable or array
+ from within the function is now caught as a fatal error, instead
+ of as a core dump.
+
+17. A bug in parsing hex escapes was fixed.
+
+18. A weird bug with concatenation where one expression has side effects
+ that changes another was fixed.
+
+19. printf/sprintf now behave much better for uses of the '0' and '#' flags
+ and with precisions and field widths.
+
+20. Further strangenesses with concatenation and multiple accesses of some
+ of the special variables was fixed.
+
+21. The Atari port is marked as no longer supported.
+
+22. Build problems on HP-UX have been fixed.
+
+23. Minor fixes and additional explanations added to the documentation.
+
+24. For RS = "", even a single leading newline is now correctly stripped.
+
+25. Obscure parsing problems for regex constants like /=.../ fixed, so
+ that a regex constant is recognized, and not the /= operator.
+
+26. Fixed a bug when closing a redirection that matched the current
+ or last FILENAME.
+
+27. Build problems on AIX fixed.
+
+Changes from 3.0.2 to 3.0.3
+---------------------------
+
+The horrendous per-record memory leak introduced in 3.0.1 is gone, finally.
+
+The `amiga' directory is now gone; Amiga support is now entirely handled
+by the POSIX support.
+
+Windows32 support has been added in the `pc' directory. See `README_d/README.pc'
+for more info.
+
+The mmap changes are disabled in io.c, and will be removed entirely
+in the next big release. They were an interesting experiment that just
+really didn't work in practice.
+
+A minor memory leak that occurred when using `next' from within a
+function has also been fixed.
+
+Problems with I/O from sub-processes via a pipe are now gone.
+
+Using "/dev/pid" and the other special /dev files no longer causes a core dump.
+
+The files regex.h, regex.c, getopt.h, getopt.c, and getopt1.c have been
+merged with the versions in GNU libc. Thanks to Ulrich Drepper for his help.
+
+Some new undocumented features have been added. Use the source, Luke!
+It is not clear yet whether these will ever be fully supported.
+
+Array performance should be much better for very very large arrays. "Virtual
+memory required, real memory helpful."
+
+builtin.c:do_substr rationalized, again.
+
+The --re-interval option now works as advertised.
+
+The license text on some of the missing/* files is now generic.
+
+Lots more new test cases.
+
+Lots of other small bugs fixed, see the ChangeLog files for details.
+
+Changes from 3.0.1 to 3.0.2
+---------------------------
+
+Gawk now uses autoconf 2.12.
+
+strftime now behaves correctly if passed an empty format string or if
+the string formats to an empty result string.
+
+Several minor compilation and installation problems have been fixed.
+
+Minor page break issues in the user's guide have been fixed.
+
+Lexical errors no longer repeat ad infinitum.
+
+Changes from 3.0.0 to 3.0.1
+---------------------------
+
+Troff source for a handy-dandy five color reference card is now provided.
+Thanks to SSC for their macros.
+
+Gawk now behaves like Unix awk and mawk, in that newline acts as white
+space for separating fields and for `split', by default. In posix mode,
+only space and tab separate fields. The documentation has been updated to
+reflect this.
+
+Tons and tons of small bugs fixed and new tests added, see the ChangeLogs.
+
+Lots fewer compile time warnings from gcc -Wall. Remaining ones aren't
+worth fixing.
+
+Gawk now pays some attention to the locale settings.
+
+Fixes to gsub to catch several corner cases.
+
+The `print' statement now evaluates all expressions first, and then
+prints them. This leads to less suprising behaviour if any expression has
+output side effects.
+
+Miscellanious improvements in regex.h and regex.c.
+
+Gawk will now install itself as gawk-M.N.P in $(bindir), and link
+`gawk' to it. This makes it easy to have multiple versions of gawk
+simultaneously. It will also now install itself as `awk' in $(bindir)
+if there is no `awk' there. This is in addition to installing itself as
+`gawk'. This change benefits the Hurd, and possibly other systems. One
+day, gawk will drop the `g', but not yet.
+
+`--posix' turns on interval expressions. Gawk now matches its documentation.
+
+`close(FILENAME)' now does something meaningful.
+
+Field management code in field.c majorly overhauled, several times.
+
+The gensub code has been fixed, several bugs are now gone.
+
+Gawk will use mmap for data file input if it is available.
+
+The printf/sprintf code has been improved.
+
+Minor issues in Makefile setup worked on and improved.
+
+builtin.c:do_substr rationalized.
+
+Regex matching fixed so that /+[0-9]/ now matches the leading +.
+
+For building on vms, the default compiler is now DEC C rather than VAX C.
+
+Changes from 2.15.6 to 3.0.0
+----------------------------
+
+Fixed spelling of `Programming' in the copyright notice in all the files.
+
+New --re-interval option to turn on interval expressions. They're off
+by default, except for --posix, to avoid breaking old programs.
+
+Passing regexp constants as parameters to user defined functions now
+generates a lint warning.
+
+Several obscure regexp bugs fixed; alas, a small number remain.
+
+The manual has been thoroughly revised. It's now almost 50% bigger than
+it used to be.
+
+The `+' modifier in printf is now reset correctly for each item.
+
+The do_unix variable is now named do_traditional.
+
+Handling of \ in sub and gsub rationalized (somewhat, see the manual for
+the gory [and I do mean gory] details).
+
+IGNORECASE now uses ISO 8859-1 Latin-1 instead of straight ASCII. See the
+source for how to revert to pure ASCII.
+
+--lint will now warn if an assignment occurs in a conditional context.
+This may become obnoxious enough to need turning off in the future, but
+"it seemed like a good idea at the time."
+
+%hf and %Lf are now diagnosed as invalid in printf, just like %lf.
+
+Gawk no longer incorrectly closes stdin in child processes used in
+input pipelines.
+
+For integer formats, gawk now correctly treats the precision as the
+number of digits to print, not the number of characters.
+
+gawk is now much better at catching the use of scalar values when
+arrays are needed, both in function calls and the `x in y' constructs.
+
+New gensub function added. See the manual.
+
+If do_tradtional is true, octal and hex escapes in regexp constants are
+treated literally. This matches historical behavior.
+
+yylex/nextc fixed so that even null characters can be included
+in the source code.
+
+do_format now handles cases where a format specifier doesn't end in
+a control letter. --lint reports an error.
+
+strftime() now uses a default time format equivalent to that of the
+Unix date command, thus it can be called with no arguments.
+
+Gawk now catches functions that are used but not defined at parse time
+instead of at run time. (This is a lint error, making it fatal could break
+old code.)
+
+Arrays that max out are now handled correctly.
+
+Integer formats outside the range of an unsigned long are now detected
+correctly using the SunOS 4.x cc compiler.
+
+--traditional option added as new preferred name for --compat, in keeping
+with GCC.
+
+--lint-old option added, so that warnings about things not in old awk
+are only given if explicitly asked for.
+
+`next file' has changed to one word, `nextfile'. `next file' is still
+accepted but generates a lint warning. `next file' will go away eventually.
+
+Gawk with --lint will now notice empty source files and empty data files.
+
+Amiga support using the Unix emulation added. Thanks to fnf@ninemoons.com.
+
+test/Makefile is now "parallel-make safe".
+
+Gawk now uses POSIX regexps + GNU regex ops by default. --posix goes to
+pure posix regexps, and --compat goes to traditional Unix regexps. However,
+interval expressions, even though specified by POSIX, are turned off by
+default, to avoid breaking old code.
+
+IGNORECASE now applies to string comparison as well as regexp operations.
+
+The AT&T Bell Labs Research awk fflush builtin function is now supported.
+fflush is extended to flush stdout if no arg and everything if given
+the null string as an argument.
+
+If RS is more than one character, it is treated as a regular expression
+and records are delimited accordingly. The variable RT is set to the record
+terminator string. This is disabled in compatibility mode.
+
+If FS is set to the null string (or the third arg. of split() is the null
+string), splitting is done at every single character. This is disabled in
+compatibility mode.
+
+Gawk now uses the Autoconf generated configure script, doing away with all
+the config/* files and the machinery that went with them. The Makefile.in
+has also changed accordingly, complete with all the standard GNU Makefile
+targets. (Non-unix systems may still have their own config.h and Makefile;
+see the appropriate README_d/README.* and/or subdirectory.)
+
+The source code has been cleaned up somewhat and the formatting improved.
+
+Changes from 2.15.5 to 2.15.6
+-----------------------------
+
+Copyrights updated on all changed files.
+
+test directory enhanced with four new tests.
+
+Gawk now generates a warning for \x without following hexadecimal digits.
+In this case, it returns 'x', not \0.
+
+Several fixes in main.c related to variable initialization:
+ CONVFMT has a default value
+ resetup is called before initializing variables
+ the varinit table fixed up a bit (see the comments)
+
+gawk.1 updated with new BUG REPORTS section.
+
+A plain `print' inside a BEGIN or END now generates a lint warning (awk.y).
+
+Small fix in iop.c:get_a_record to avoid reading uninitialized memory.
+
+awk.y:yylex now does a better job of handling things if the source file
+does not end in a newline. Probably there is more work to be done.
+
+Memory leaks fixed in awk.y, particularly in cases of duplicate function
+parameters. Also, calling a function doesn't leak memory during parsing.
+
+Empty function bodies are now allowed (awk.y).
+
+Gawk now detects duplicate parameter names in functions (awk.y).
+
+New function `error' in msg.c added for use from awk.y.
+
+eval.c:r_get_lhs now checks if its argument is a parameter on the stack,
+and pulls down the real variable. This catches more 'using an array as
+a scalar' kinds of errors.
+
+main.c recovers C alloca space after parsing, this is important for
+bison-based parsers. re.c recovers C alloca space after doing an research.
+[Changes from Pat Rankin]
+
+builtin.c now declares the random() related functions based on
+RANDOM_MISSING from config.h. [Suggested by Pat Rankin]
+
+awk.h now handles alloca correctly for HP-UX. [Kaveh Ghazi]
+
+regex.h and config/cray60 updated for Unicos 8.0. [Hal Peterson]
+
+Fixed re.c and dfa.c so that gawk no longer leaks memory when using
+lots of dynamic regexps.
+
+Removed dependency on signed chars from `idx' variable in awk.h. Gawk
+now passes its test suite if compiled with `gcc -fno-signed-char'.
+
+Fixed warning on close in io.c to go under lint control. Too many people
+have complained about the spurious message, particularly when closing a
+child pipeline early.
+
+Gawk now correctly handles RS = "" when input is from a terminal
+(iop.c:get_a_record).
+
+Config file added for GNU.
+
+gawk 'BEGIN { exit 1 } ; END { exit }' now exits 1, as it should
+(eval.c:interpret).
+
+sub and gsub now follow posix, \ escapes both & and \. Each \ must
+be doubled initially in the program to get it into the string.
+Thanks to Mike Brennan for pointing this out (builtin.c:sub_common).
+
+If FS is "", gawk behaves like mawk and nawk, making the whole record be $1.
+Yet Another Dark Corner. Sigh (field.c:def_parse_field).
+
+Gawk now correctly recomputes string values for numbers if CONVFMT has
+changed (awk.h:force_string, node.c:r_force_string).
+
+A regexp of the form `/* this looks like a comment but is not */' will
+now generate a warning from --lint (awk.y).
+
+Gawk will no longer core dump if given an empty input file (awk.y:get_src_buf,
+iop.c:optimal_bufsize).
+
+A printf format of the form %lf is handled correctly. The `l' generates
+a lint warning (builtin.c:format_tree) [Thanks to Mark Moraes].
+
+Lynxos config file added.
+
+`continue' outside a loop treated as `next' only in compatibility mode,
+instead of by default; recent att nawk chokes on this now. `break'
+outside a loop now treated as `next' in compatibility mode (eval.c).
+
+Bug fix in string concatenation, an arbitrary number of expressions
+are allowed (eval.c).
+
+$1 += $2 now works correctly (eval.c).
+
+Changing IGNORECASE no longer resets field-splitting to FS if it was
+using FIELDWIDTHS (eval.c, field.c).
+
+Major enhancement: $0 and NF for last record read are now preserved
+into the END rule (io.c).
+
+Regexp fixes:
+ /./ now matches a newline (regex.h)
+ ^ and $ match beginning and end of string only, not any embedded
+ newlines (re.c)
+ regex.c should compile and work ok on 64-bit mips/sgi machines
+
+Changes from 2.15.4 to 2.15.5
+-----------------------------
+
+FUTURES file updated and re-arranged some with more rational schedule.
+
+Many prototypes handled better for ANSI C in protos.h.
+
+getopt.c updated somewhat.
+
+test/Makefile now removes junk directory, `bardargtest' renamed `badargs.'
+
+Bug fix in iop.c for RS = "". Eat trailing newlines off of record separator.
+
+Bug fix in Makefile.bsd44, use leading tab in actions.
+
+Fix in field.c:set_FS for FS == "\\" and IGNORECASE != 0.
+
+Config files updated or added:
+ cray60, DEC OSF/1 2.0, Utek, sgi405, next21, next30, atari/config.h,
+ sco.
+
+Fix in io.c for ENFILE as well as EMFILE, update decl of groupset to
+include OSF/1.
+
+Rationalized printing as integers if numbers are outside the range of a long.
+Changes to node.c:force_string and builtin.c.
+
+Made internal NF, NR, and FNR variables longs instead of ints.
+
+Add LIMITS_H_MISSING stuff to config.in and awk.h, and default defs for
+INT_MAX and LONG_MAX, if no limits.h file. Add a standard decl of
+the time() function for __STDC__. From ghazi@noc.rutgers.edu.
+
+Fix tree_eval in awk.h and r_tree_eval in eval.c to deal better with
+function parameters, particularly ones that are arrays.
+
+Fix eval.c to print out array names of arrays used in scalar contexts.
+
+Fix eval.c in interpret to zero out source and sourceline initially. This
+does a better job of providing source file and line number information.
+
+Fix to re_parse_field in field.c to not use isspace when RS = "", but rather
+to explicitly look for blank and tab.
+
+Fix to sc_parse_field in field.c to catch the case of the FS character at the
+end of a record.
+
+Lots of miscellanious bug fixes for memory leaks, courtesy Mark Moraes,
+also fixes for arrays.
+
+io.c fixed to warn about lack of explicit closes if --lint.
+
+Updated missing/strftime.c to match posted strftime 6.2.
+
+Bug fix in builtin.c, in case of non-match in sub_common.
+
+Updated constant used for division in builtin.c:do_rand for DEC Alpha
+and CRAY Y-MP.
+
+POSIXLY_CORRECT in the environment turns on --posix (fixed in main.c).
+
+Updated srandom prototype and calls in builtin.c.
+
+Fix awk.y to enforce posix semantics of unary +: result is numeric.
+
+Fix array.c to not rearrange the hash chain upon finding an index in
+the array. This messed things up in cases like:
+ for (index1 in array) {
+ blah
+ if (index2 in array) # blew away the for
+ stuff
+ }
+
+Fixed spelling errors in the man page.
+
+Fixes in awk.y so that
+ gawk '' /path/to/file
+will work without core dumping or finding parse errors.
+
+Fix main.c so that --lint will fuss about an empty program.
+Yet another fix for argument parsing in the case of unrecognized options.
+
+Bug fix in dfa.c to not attempt to free null pointers.
+
+Bug fix in builtin.c to only use DEFAULT_G_PRECISION for %g or %G.
+
+Bug fix in field.c to achieve call by value semantics for split.
+
+Changes from 2.15.3 to 2.15.4
+-----------------------------
+
+Lots of lint fixes, and do_sprintf made mostly ANSI C compatible.
+
+Man page updated and edited.
+
+Copyrights updated.
+
+Arrays now grow dynamically, initially scaling up by an order of magnitude
+ and then doubling, up to ~ 64K. This should keep gawk's performance
+ graceful under heavy load.
+
+New `delete array' feature added. Only documented in the man page.
+
+Switched to dfa and regex suites from grep-2.0. These offer the ability to
+ move to POSIX regexps in the next release.
+
+Disabled GNU regex ops.
+
+Research awk -m option now recognized. It does nothing in gawk, since gawk
+ has no static limits. Only documented in the man page.
+
+New bionic (faster, better, stronger than before) hashing function.
+
+Bug fix in argument handling. `gawk -X' now notices there was no program.
+ Additional bug fixes to make --compat and --lint work again.
+
+Many changes for systems where sizeof(int) != sizeof(void *).
+
+Add explicit alloca(0) in io.c to recover space from C alloca.
+
+Fixed file descriptor leak in io.c.
+
+The --version option now follows the GNU coding standards and exits.
+
+Fixed several prototypes in protos.h.
+
+Several tests updated. On Solaris, warn that the out? tests will fail.
+
+Configuration files for SunOS with cc and Solaris 2.x added.
+
+Improved error messages in awk.y on gawk extensions if do_unix or do_compat.
+
+INSTALL file added.
+
+Fixed Atari Makefile and several VMS specific changes.
+
+Better conversion of numbers to strings on systems with broken sprintfs.
+
+Changes from 2.15.2 to 2.15.3
+-----------------------------
+
+Increased HASHSIZE to a decent number, 127 was way too small.
+
+FILENAME is now the null string in a BEGIN rule.
+
+Argument processing fixed for invalid options and missing arguments.
+
+This version will build on VMS. This included a fix to close all files
+ and pipes opened with redirections before closing stdout and stderr.
+
+More getpgrp() defines.
+
+Changes for BSD44: <sys/param.h> in io.c and Makefile.bsd44.
+
+All directories in the distribution are now writable.
+
+Separated LDFLAGS and CFLAGS in Makefile. CFLAGS can now be overridden by
+ user.
+
+Make dist now builds compressed archives ending in .gz and runs doschk.
+
+Amiga port.
+
+New getopt.c fixes Alpha OSF/1 problem.
+
+Make clean now removes possible test output.
+
+Improved algorithm for multiple adjacent string concatenations leads to
+ performance improvements.
+
+Fix nasty bug whereby command-line assignments, both with -v and at run time,
+ could create variables with syntactically illegal names.
+
+Fix obscure bug in printf with %0 flag and filling.
+
+Add a lint check for substr if provided length exceeds remaining characters
+ in string.
+
+Update atari support.
+
+PC support enhanced to include support for both DOS and OS/2. (Lots more
+ #ifdefs. Sigh.)
+
+Config files for Hitachi Unix and OSF/1, courtesy of Yoko Morishita
+ (morisita@sra.co.jp)
+
+Changes from 2.15.1 to 2.15.2
+-----------------------------
+
+Additions to the FUTURES file.
+
+Document undefined order of output when using both standard output
+ and /dev/stdout or any of the /dev output files that gawk emulates in
+ the absence of OS support.
+
+Clean up the distribution generation in Makefile.in: the info files are
+ now included, the distributed files are marked read-only and patched
+ distributions are now unpacked in a directory named with the patch level.
+
+Changes from 2.15 to 2.15.1
+---------------------------
+
+Close stdout and stderr before all redirections on program exit. This allows
+ detection of write errors and also fixes the messages test on Solaris 2.x.
+
+Removed YYMAXDEPTH define in awk.y which was limiting the parser stack depth.
+
+Changes to config/bsd44, Makefile.bsd44 and configure to bring it into line
+ with the BSD4.4 release.
+
+Changed Makefile to use prefix, exec_prefix, bindir etc.
+
+make install now installs info files.
+
+make install now sets permissions on installed files.
+
+Make targets added: uninstall, distclean, mostlyclean and realclean.
+
+Added config.h to cleaner and clobber make targets.
+
+Changes to config/{hpux8x,sysv3,sysv4,ultrix41} to deal with alloca().
+
+Change to getopt.h for portability.
+
+Added more special cases to the getpgrp() call.
+
+Added README.ibmrt-aos and config/ibmrt-aos.
+
+Changes from 2.14 to 2.15
+---------------------------
+
+Command-line source can now be mixed with library functions.
+
+ARGIND variable tracks index in ARGV of FILENAME.
+
+GNU style long options in addition to short options.
+
+Plan 9 style special files interpreted by gawk:
+ /dev/pid
+ /dev/ppid
+ /dev/pgrpid
+ /dev/user
+ $1 = getuid
+ $2 = geteuid
+ $3 = getgid
+ $4 = getegid
+ $5 ... $NF = getgroups if supported
+
+ERRNO variable contains error string if getline or close fails.
+
+Very old options -a and -e have gone away.
+
+Inftest has been removed from the default target in test/Makefile -- the
+ results were too machine specific and resulted in too many false alarms.
+
+A README.amiga has been added.
+
+The "too many arguments supplied for format string" warning message is only
+ in effect under the lint option.
+
+Code improvements in dfa.c.
+
+Fixed all reported bugs:
+
+ Writes are checked for failure (such as full filesystem).
+
+ Stopped (at least some) runaway error messages.
+
+ gsub(/^/, "x") does the right thing for $0 of 0, 1, or more length.
+
+ close() on a command being piped to a getline now works properly.
+
+ The input record will no longer be freed upon an explicit close()
+ of the input file.
+
+ A NUL character in FS now works.
+
+ In a substitute, \\& now means a literal backslash followed by what
+ was matched.
+
+ Integer overflow of substring length in substr() is caught.
+
+ An input record without a newline termination is handled properly.
+
+ In io.c, check is against only EMFILE so that system file table
+ is not filled.
+
+ Renamed all files with names longer than 14 characters.
+
+ Escaped characters in regular expressions were being lost when
+ IGNORECASE was used.
+
+ Long source lines were not being handled properly.
+
+ Sourcefiles that ended in a tab but no newline were bombing.
+
+ Patterns that could match zero characters in split() were not working
+ properly.
+
+ The parsedebug option was not working.
+
+ The grammar was being a bit too lenient, allowing some very dubious
+ programs to pass.
+
+ Compilation with DEBUG defined now works.
+
+ A variable read in with getline was not being treated as a potential
+ number.
+
+ Array subscripts were not always of string type.
+
+
+Changes from 2.13.2 to 2.14
+---------------------------
+
+Updated manual!
+
+Added "next file" to skip efficiently to the next input file.
+
+Fixed potential of overflowing buffer in do_sprintf().
+
+Plugged small memory leak in sub_common().
+
+EOF on a redirect is now "sticky" -- it can only be cleared by close()ing
+ the pipe or file.
+
+Now works if used via a #! /bin/gawk line at the top of an executable file
+ when that line ends with whitespace.
+
+Added some checks to the grammar to catch redefinition of builtin functions.
+ This could eventually be the basis for an extension to allow redefining
+ functions, but in the mean time it's a good error catching facility.
+
+Negative integer exponents now work.
+
+Modified do_system() to make sure it had a non-null string to be passed
+ to system(3). Thus, system("") will flush any pending output but not go
+ through the overhead of forking an un-needed shell.
+
+A fix to floating point comparisons so that NaNs compare right on IEEE systems.
+
+Added code to make sure we're not opening directories for reading and such.
+
+Added code to do better diagnoses of weird or null file names.
+
+Allow continue outside of a loop, unless in strict posix mode. Lint option
+ will issue warning.
+
+New missing/strftime.c. There has been one change that affects gawk. Posix
+ now defines a %V conversion so the vms conversion has been changed to %v.
+ If this version is used with gawk -Wlint and they use %V in a call to
+ strftime, they'll get a warning.
+
+Error messages now conform to GNU standard (I hope).
+
+Changed comparisons to conform to the description found in the file POSIX.
+ This is inconsistent with the current POSIX draft, but that is broken.
+ Hopefully the final POSIX standard will conform to this version.
+ (Alas, this will have to wait for 1003.2b, which will be a revision to
+ the 1003.2 standard. That standard has been frozen with the broken
+ comparison rules.)
+
+The length of a string was a short and now is a size_t.
+
+Updated VMS help.
+
+Added quite a few new tests to the test suite and deleted many due to lack of
+ written releases. Test output is only removed if it is identical to the
+ "good" output.
+
+Fixed a couple of bugs for reference to $0 when $0 is "" -- particularly in
+ a BEGIN block.
+
+Fixed premature freeing in construct "$0 = $0".
+
+Removed the call to wait_any() in gawk_popen(), since on at least some systems,
+ if gawk's input was from a pipe, the predecessor process in the pipe was a
+ child of gawk and this caused a deadlock.
+
+Regexp can (once again) match a newline, if given explicitly.
+
+nextopen() makes sure file name is null terminated.
+
+Fixed VMS pipe simulation. Improved VMS I/O performance.
+
+Catch . used in variable names.
+
+Fixed bug in getline without redirect from a file -- it was quitting after the
+ first EOF, rather than trying the next file.
+
+Fixed bug in treatment of backslash at the end of a string -- it was bombing
+ rather than doing something sensible. It is not clear what this should mean,
+ but for now I issue a warning and take it as a literal backslash.
+
+Moved setting of regexp syntax to before the option parsing in main(), to
+ handle things like -v FS='[.,;]'
+
+Fixed bug when NF is set by user -- fields_arr must be expanded if necessary
+ and "new" fields must be initialized.
+
+Fixed several bugs in [g]sub() for no match found or the match is 0-length.
+
+Fixed bug where in gsub() a pattern anchored at the beginning would still
+ substitute throughout the string.
+
+make test does not assume that . is in PATH.
+
+Fixed bug when a field beyond the end of the record was requested after
+ $0 was altered (directly or indirectly).
+
+Fixed bug for assignment to field beyond end of record -- the assigned value
+ was not found on subsequent reference to that field.
+
+Fixed bug for FS a regexp and it matches at the end of a record.
+
+Fixed memory leak for an array local to a function.
+
+Fixed hanging of pipe redirection to getline
+
+Fixed coredump on access to $0 inside BEGIN block.
+
+Fixed treatment of RS = "". It now parses the fields correctly and strips
+ leading whitespace from a record if FS is a space.
+
+Fixed faking of /dev/stdin.
+
+Fixed problem with x += x
+
+Use of scalar as array and vice versa is now detected.
+
+IGNORECASE now obeyed for FS (even if FS is a single alphabetic character).
+
+Switch to GPL version 2.
+
+Renamed awk.tab.c to awktab.c for MSDOS and VMS tar programs.
+
+Renamed this file (CHANGES) to NEWS.
+
+Use fmod() instead of modf() and provide FMOD_MISSING #define to undo
+ this change.
+
+Correct the volatile declarations in eval.c.
+
+Avoid errant closing of the file descriptors for stdin, stdout and stderr.
+
+Be more flexible about where semi-colons can occur in programs.
+
+Check for write errors on all output, not just on close().
+
+Eliminate the need for missing/{strtol.c,vprintf.c}.
+
+Use GNU getopt and eliminate missing/getopt.c.
+
+More "lint" checking.
+
+
+Changes from 2.13.1 to 2.13.2
+-----------------------------
+
+Toward conformity with GNU standards, configure is a link to mkconf, the latter
+ to disappear in the next major release.
+
+Update to config/bsd43.
+
+Added config/apollo, config/msc60, config/cray2-50, config/interactive2.2
+
+sgi33.cc added for compilation using cc rather than gcc.
+
+Ultrix41 now propagates to config.h properly -- as part of a general
+ mechanism in configure for kludges -- #define anything from a config file
+ just gets tacked onto the end of config.h -- to be used sparingly.
+
+Got rid of an unnecessary and troublesome declaration of vprintf().
+
+Small improvement in locality of error messages.
+
+Try to diagnose use of array as scalar and vice versa -- to be improved in
+ the future.
+
+Fix for last bug fix for Cray division code--sigh.
+
+More changes to test suite to explicitly use sh. Also get rid of
+ a few generated files.
+
+Fixed off-by-one bug in string concatenation code.
+
+Fix for use of array that is passed in from a previous function parameter.
+ Addition to test suite for above.
+
+A number of changes associated with changing NF and access to fields
+ beyond the end of the current record.
+
+Change to missing/memcmp.c to avoid seg. fault on zero length input.
+
+Updates to test suite (including some inadvertently left out of the last patch)
+ to invoke sh explicitly (rather than rely on #!/bin/sh) and remove some
+ junk files. test/chem/good updated to correspond to bug fixes.
+
+Changes from 2.13.0 to 2.13.1
+-----------------------------
+
+More configs and PORTS.
+
+Fixed bug wherein a simple division produced an erroneous FPE, caused by
+ the Cray division workaround -- that code is now #ifdef'd only for
+ Cray *and* fixed.
+
+Fixed bug in modulus implementation -- it was very close to the above
+ code, so I noticed it.
+
+Fixed portability problem with limits.h in missing.c
+
+Fixed portability problem with tzname and daylight -- define TZNAME_MISSING
+ if strftime() is missing and tzname is also.
+
+Better support for Latin-1 character set.
+
+Fixed portability problem in test Makefile.
+
+Updated PROBLEMS file.
+
+=============================== gawk-2.13 released =========================
+Changes from 2.12.42 to 2.12.43
+-------------------------------
+
+Typo in awk.y
+
+Fixed up strftime.3 and added doc. for %V.
+
+Changes from 2.12.41 to 2.12.42
+-------------------------------
+
+Fixed bug in devopen() -- if you had write permission in /dev,
+ it would just create /dev/stdout etc.!!
+
+Final (?) VMS update.
+
+Make NeXT use GFMT_WORKAROUND
+
+Fixed bug in sub_common() for substitute on zero-length match. Improved the
+ code a bit while I was at it.
+
+Fixed grammar so that $i++ parses as ($i)++
+
+Put support/* back in the distribution (didn't I already do this?!)
+
+Changes from 2.12.40 to 2.12.41
+-------------------------------
+
+VMS workaround for broken %g format.
+
+Changes from 2.12.39 to 2.12.40
+-------------------------------
+
+Minor man page update.
+
+Fixed latent bug in redirect().
+
+Changes from 2.12.38 to 2.12.39
+-------------------------------
+
+Updates to test suite -- remove dependence on changing gawk.1 man page.
+
+Changes from 2.12.37 to 2.12.38
+-------------------------------
+
+Fixed bug in use of *= without whitespace following.
+
+VMS update.
+
+Updates to man page.
+
+Option handling updates in main.c
+
+test/manyfiles redone and added to bigtest.
+
+Fixed latent (on Sun) bug in handling of save_fs.
+
+Changes from 2.12.36 to 2.12.37
+-------------------------------
+
+Update REL in Makefile-dist. Incorporate test suite into main distribution.
+
+Minor fix in regtest.
+
+Changes from 2.12.35 to 2.12.36
+-------------------------------
+
+Release takes on dual personality -- 2.12.36 and 2.13.0 -- any further
+ patches before public release won't count for 2.13, although they will for
+ 2.12 -- be careful to avoid confusion! patchlevel.h will be the last thing
+ to change.
+
+Cray updates to deal with arithmetic problems.
+
+Minor test suite updates.
+
+Fixed latent bug in parser (freeing memory).
+
+Changes from 2.12.34 to 2.12.35
+-------------------------------
+
+VMS updates.
+
+Flush stdout at top of err() and stderr at bottom.
+
+Fixed bug in eval_condition() -- it wasn't testing for MAYBE_NUM and
+ doing the force_number().
+
+Included the missing manyfiles.awk and a new test to catch the above bug which
+ I am amazed wasn't already caught by the test suite -- it's pretty basic.
+
+Changes from 2.12.33 to 2.12.34
+-------------------------------
+
+Atari updates -- including bug fix.
+
+More VMS updates -- also nuke vms/version.com.
+
+Fixed bug in handling of large numbers of redirections -- it was probably never
+ tested before (blush!).
+
+Minor rearrangement of code in r_force_number().
+
+Made chem and regtest tests a bit more portable (Ultrix again).
+
+Added another test -- manyfiles -- not invoked under any other test -- very Unix
+ specific.
+
+Rough beginning of LIMITATIONS file -- need my AWK book to complete it.
+
+Changes from 2.12.32 to 2.12.33
+-------------------------------
+
+Expunge debug.? from various files.
+
+Remove vestiges of Floor and Ceil kludge.
+
+Special case integer division -- mainly for Cray, but maybe someone else
+ will benefit.
+
+Workaround for iop_close closing an output pipe descriptor on Cray --
+ not conditional since I think it may fix a bug on SGI as well and I don't
+ think it can hurt elsewhere.
+
+Fixed memory leak in assoc_lookup().
+
+Small cleanup in test suite.
+
+Changes from 2.12.31 to 2.12.32
+-------------------------------
+
+Nuked debug.c and debugging flag -- there are better ways.
+
+Nuked version.sh and version.c in subdirectories.
+
+Fixed bug in handling of IGNORECASE.
+
+Fixed bug when FIELDWIDTHS was set via -v option.
+
+Fixed (obscure) bug when $0 is assigned a numerical value.
+
+Fixed so that escape sequences in command-line assignments work (as it already
+ said in the comment).
+
+Added a few cases to test suite.
+
+Moved support/* back into distribution.
+
+VMS updates.
+
+Changes from 2.12.30 to 2.12.31
+-------------------------------
+
+Cosmetic manual page changes.
+
+Updated sunos3 config.
+
+Small changes in test suite including renaming files over 14 chars. in length.
+
+Changes from 2.12.29 to 2.12.30
+-------------------------------
+
+Bug fix for many string concatenations in a row.
+
+Changes from 2.12.28 to 2.12.29
+-------------------------------
+
+Minor cleanup in awk.y
+
+Minor VMS update.
+
+Minor atari update.
+
+Changes from 2.12.27 to 2.12.28
+-------------------------------
+
+Got rid of the debugging goop in eval.c -- there are better ways.
+
+Sequent port.
+
+VMS changes left out of the last patch -- sigh! config/vms.h renamed
+ to config/vms-conf.h.
+
+Fixed missing/tzset.c
+
+Removed use of gcvt() and GCVT_MISSING -- turns out it was no faster than
+ sprintf("%g") and caused all sorts of portability headaches.
+
+Tuned get_field() -- it was unnecessarily parsing the whole record on reference
+ to $0.
+
+Tuned interpret() a bit in the rule_node loop.
+
+In r_force_number(), worked around bug in Uglix strtod() and got rid of
+ ugly do{}while(0) at Michal's urging.
+
+Replaced do_deref() and deref with unref(node) -- much cleaner and a bit faster.
+
+Got rid of assign_number() -- contrary to comment, it was no faster than
+ just making a new node and freeing the old one.
+
+Replaced make_number() and tmp_number() with macros that call mk_number().
+
+Changed freenode() and newnode() into macros -- the latter is getnode()
+ which calls more_nodes() as necessary.
+
+Changes from 2.12.26 to 2.12.27
+-------------------------------
+
+Completion of Cray 2 port (includes a kludge for floor() and ceil()
+ that may go or be changed -- I think that it may just be working around
+ a bug in chem that is being tweaked on the Cray).
+
+More VMS updates.
+
+Moved kludge over yacc's insertion of malloc and realloc declarations
+ from protos.h to the Makefile.
+
+Added a lisp interpreter in awk to the test suite. (Invoked under
+ bigtest.)
+
+Cleanup in r_force_number() -- I had never gotten around to a thorough
+ profile of the cache code and it turns out to be not worth it.
+
+Performance boost -- do lazy force_number()'ing for fields etc. i.e.
+ flag them (MAYBE_NUM) and call force_number only as necessary.
+
+Changes from 2.12.25 to 2.12.26
+-------------------------------
+
+Rework of regexp stuff so that dynamic regexps have reasonable
+ performance -- string used for compiled regexp is stored and
+ compared to new string -- if same, no recompilation is necessary.
+ Also, very dynamic regexps cause dfa-based searching to be turned
+ off.
+
+Code in dev_open() is back to returning fileno(std*) rather than
+ dup()ing it. This will be documented. Sorry for the run-around
+ on this.
+
+Minor atari updates.
+
+Minor vms update.
+
+Missing file from MSDOS port.
+
+Added warning (under lint) if third arg. of [g]sub is a constant and
+ handle it properly in the code (i.e. return how many matches).
+
+Changes from 2.12.24 to 2.12.25
+-------------------------------
+
+MSDOS port.
+
+Non-consequential changes to regexp variables in preparation for
+ a more serious change to fix a serious performance problem.
+
+Changes from 2.12.23 to 2.12.24
+-------------------------------
+
+Fixed bug in output flushing introduced a few patches back. This caused
+ serious performance losses.
+
+Changes from 2.12.22 to 2.12.23
+-------------------------------
+
+Accidentally left config/cray2-60 out of last patch.
+
+Added some missing dependencies to Makefile.
+
+Cleaned up mkconf a bit; made yacc the default parser (no alloca needed,
+ right?); added rs6000 hook for signed characters.
+
+Made regex.c with NO_ALLOCA undefined work.
+
+Fixed bug in dfa.c for systems where free(NULL) bombs.
+
+Deleted a few cant_happen()'s that *really* can't hapen.
+
+Changes from 2.12.21 to 2.12.22
+-------------------------------
+
+Added to config stuff the ability to choose YACC rather than bison.
+
+Fixed CHAR_UNSIGNED in config.h-dist.
+
+Second arg. of strtod() is char ** rather than const char **.
+
+stackb is now initially malloc()'ed since it may be realloc()'ed.
+
+VMS updates.
+
+Added SIZE_T_MISSING to config stuff and a default typedef to awk.h.
+ (Maybe it is not needed on any current systems??)
+
+re_compile_pattern()'s size is now size_t unconditionally.
+
+Changes from 2.12.20 to 2.12.21
+-------------------------------
+
+Corrected missing/gcvt.c.
+
+Got rid of use of dup2() and thus DUP_MISSING.
+
+Updated config/sgi33.
+
+Turned on (and fixed) in cmp_nodes() the behaviour that I *hope* will be in
+ POSIX 1003.2 for relational comparisons.
+
+Small updates to test suite.
+
+Changes from 2.12.19 to 2.12.20
+-------------------------------
+
+Sloppy, sloppy, sloppy!! I didn't even try to compile the last two
+ patches. This one fixes goofs in regex.c.
+
+Changes from 2.12.18 to 2.12.19
+-------------------------------
+
+Cleanup of last patch.
+
+Changes from 2.12.17 to 2.12.18
+-------------------------------
+
+Makefile renamed to Makefile-dist.
+
+Added alloca() configuration to mkconf. (A bit kludgey.) Just
+ add a single line containing ALLOCA_PW, ALLOCA_S or ALLOCA_C
+ to the appropriate config file to have Makefile-dist edited
+ accordingly.
+
+Reorganized output flushing to correspond with new semantics of
+ devopen() on "/dev/std*" etc.
+
+Fixed rest of last goof!!
+
+Save and restore errno in do_pathopen().
+
+Miscellaneous atari updates.
+
+Get rid of the trailing comma in the NODETYPE definition (Cray
+ compiler won't take it).
+
+Try to make the use of `const' consistent since Cray compiler is
+ fussy about that. See the changes to `basename' and `myname'.
+
+It turns out that, according to section 3.8.3 (Macro Replacement)
+ of the ANSI Standard: ``If there are sequences of preprocessing
+ tokens within the list of arguments that would otherwise act as
+ preprocessing directives, the behavior is undefined.'' That means
+ that you cannot count on the behavior of the declaration of
+ re_compile_pattern in awk.h, and indeed the Cray compiler chokes on it.
+
+Replaced alloca with malloc/realloc/free in regex.c. It was much simpler
+ than expected. (Inside NO_ALLOCA for now -- by default no alloca.)
+
+Added a configuration file, config/cray60, for Unicos-6.0.
+
+Changes from 2.12.16 to 2.12.17
+-------------------------------
+
+Ooops. Goofed signal use in last patch.
+
+Changes from 2.12.15 to 2.12.16
+-------------------------------
+
+RENAMED *_dir to just * (e.g. missing_dir).
+
+Numerous VMS changes.
+
+Proper inclusion of atari and vms files.
+
+Added experimental (ifdef'd out) RELAXED_CONTINUATION and DEFAULT_FILETYPE
+ -- please comment on these!
+
+Moved pathopen() to io.c (sigh).
+
+Put local directory ahead in default AWKPATH.
+
+Added facility in mkconf to echo comments on stdout: lines beginning
+ with "#echo " will have the remainder of the line echoed when mkconf is run.
+ Any lines starting with "#" will otherwise be treated as comments. The
+ intent is to be able to say:
+ "#echo Make sure you uncomment alloca.c in the Makefile"
+ or the like.
+
+Prototype fix for V.4
+
+Fixed version_string to not print leading @(#).
+
+Fixed FIELDWIDTHS to work with strict (turned out to be easy).
+
+Fixed conf for V.2.
+
+Changed semantics of /dev/fd/n to be like on real /dev/fd.
+
+Several configuration and updates in the makefile.
+
+Updated manpage.
+
+Include tzset.c and system.c from missing_dir that were accidently left out of
+ the last patch.
+
+Fixed bug in cmdline variable assignment -- arg was getting freed(!) in
+ call to variable.
+
+Backed out of parse-time constant folding for now, until I can figure out
+ how to do it right.
+
+Fixed devopen() so that getline <"-" works.
+
+Changes from 2.12.14 to 2.12.15
+-------------------------------
+
+Changed config/* to a condensed form that can be used with mkconf to generate
+ a config.h from config.h-dist -- much easier to maintain. Please check
+ carefully against what you had before for a particular system and report
+ any problems. vms.h remains separate since the stuff at the bottom
+ didn't quite fit the mkconf model -- hopefully cleared up later.
+
+Fixed bug in grammar -- didn't allow function definition to be separated from
+ other rules by a semi-colon.
+
+VMS fix to #includes in missing.c -- should we just be including awk.h?
+
+Updated README for texinfo.tex version.
+
+Updating of copyright in all .[chy] files.
+
+Added but commented out Michal's fix to strftime.
+
+Added tzset() emulation based on Rick Adams' code. Added TZSET_MISSING to
+ config.h-dist.
+
+Added strftime.3 man page for missing_dir
+
+More posix: func, **, **= don't work in -W posix
+
+More lint: ^, ^= not in old awk
+
+gawk.1: removed ref to -DNO_DEV_FD, other minor updating.
+
+Style change: pushbak becomes pushback() in yylex().
+
+Changes from 2.12.13 to 2.12.14
+-------------------------------
+
+Better (?) organization of awk.h -- attempt to keep all system dependencies
+ near the top and move some of the non-general things out of the config.h
+ files.
+
+Change to handling of SYSTEM_MISSING.
+
+Small change to ultrix config.
+
+Do "/dev/fd/*" etc. checking at runtime.
+
+First pass at VMS port.
+
+Improvements to error handling (when lexeme spans buffers).
+
+Fixed backslash handling -- why didn't I notice this sooner?
+
+Added programs from book to test suite and new target "bigtest" to Makefile.
+
+Changes from 2.12.12 to 2.12.13
+-------------------------------
+
+Recognize OFS and ORS specially so that OFS = 9 works without efficiency hit.
+ Took advantage of opportunity to tune do_print*() for about 10% win on a
+ print with 5 args (i.e. small but significant).
+
+Somewhat pervasive changes to reconcile CONVFMT vs. OFMT.
+
+Better initialization of builtin vars.
+
+Make config/* consistent wrt STRTOL_MISSING.
+
+Small portability improvement to alloca.s
+
+Improvements to lint code in awk.y
+
+Replaced strtol() with a better one by Chris Torek.
+
+Changes from 2.12.11 to 2.12.12
+-------------------------------
+
+Added PORTS file to record successful ports.
+
+Added #define const to nothing if not STDC and added const to strtod() header.
+
+Added * to printf capabilities and partially implemented ' ' and '+' (has an
+ effect for %d only, silently ignored for other formats). I'm afraid that's
+ as far as I want to go before I look at a complete replacement for
+ do_sprintf().
+
+Added warning for /regexp/ on LHS of MATCHOP.
+
+Changes from 2.12.10 to 2.12.11
+-------------------------------
+
+Small Makefile improvements.
+
+Some remaining nits from the NeXT port.
+
+Got rid of bcopy() define in awk.h -- not needed anymore (??)
+
+Changed private in builtin.c -- it is special on Sequent.
+
+Added subset implementation of strtol() and STRTOL_MISSING.
+
+A little bit of cleanup in debug.c, dfa.c.
+
+Changes from 2.12.9 to 2.12.10
+------------------------------
+
+Redid compatability checking and checking for # of args.
+
+Removed all references to variables[] from outside awk.y, in preparation
+ for a more abstract interface to the symbol table.
+
+Got rid of a remaining use of bcopy() in regex.c.
+
+Changes from 2.12.8 to 2.12.9
+-----------------------------
+
+Portability improvements for atari, next and decstation.
+
+Bug fix in substr() -- wasn't handling 3rd arg. of -1 properly.
+
+Manpage updates.
+
+Moved support from src release to doc release.
+
+Updated FUTURES file.
+
+Added some "lint" warnings.
+
+Changes from 2.12.7 to 2.12.8
+-----------------------------
+
+Changed time() to systime().
+
+Changed warning() in snode() to fatal().
+
+strftime() now defaults second arg. to current time.
+
+Changes from 2.12.6 to 2.12.7
+-----------------------------
+
+Fixed bug in sub_common() involving inadequate allocation of a buffer.
+
+Added some missing files to the Makefile.
+
+Changes from 2.12.5 to 2.12.6
+-----------------------------
+
+Fixed bug wherein non-redirected getline could call iop_close() just
+ prior to a call from do_input().
+
+Fixed bug in handling of /dev/stdout and /dev/stderr.
+
+Changes from 2.12.4 to 2.12.5
+-----------------------------
+
+Updated README and support directory.
+
+Changes from 2.12.3 to 2.12.4
+-----------------------------
+
+Updated CHANGES and TODO (should have been done in previous 2 patches).
+
+Changes from 2.12.2 to 2.12.3
+-----------------------------
+
+Brought regex.c and alloca.s into line with current FSF versions.
+
+Changes from 2.12.1 to 2.12.2
+-----------------------------
+
+Portability improvements; mostly moving system prototypes out of awk.h
+
+Introduction of strftime.
+
+Use of CONVFMT.
+
+Changes from 2.12 to 2.12.1
+-----------------------------
+
+Consolidated treatment of command-line assignments (thus correcting the
+-v treatment).
+
+Rationalized builtin-variable handling into a table-driven process, thus
+simplifying variable() and eliminating spc_var().
+
+Fixed bug in handling of command-line source that ended in a newline.
+
+Simplified install() and lookup().
+
+Did away with double-mallocing of identifiers and now free second and later
+instances of a name, after the first gets installed into the symbol table.
+
+Treat IGNORECASE specially, simplifying a lot of code, and allowing
+checking against strict conformance only on setting it, rather than on each
+pattern match.
+
+Fixed regexp matching when IGNORECASE is non-zero (broken when dfa.c was
+added).
+
+Fixed bug where $0 was not being marked as valid, even after it was rebuilt.
+This caused mangling of $0.
+
+
+Changes from 2.11.1 to 2.12
+-----------------------------
+
+Makefile:
+
+Portability improvements in Makefile.
+Move configuration stuff into config.h
+
+FSF files:
+
+Synchronized alloca.[cs] and regex.[ch] with FSF.
+
+array.c:
+
+Rationalized hash routines into one with a different algorithm.
+delete() now works if the array is a local variable.
+Changed interface of assoc_next() and avoided dereferencing past the end of the
+ array.
+
+awk.h:
+
+Merged non-prototype and prototype declarations in awk.h.
+Expanded tree_eval #define to short-circuit more calls of r_tree_eval().
+
+awk.y:
+
+Delinted some of the code in the grammar.
+Fixed and improved some of the error message printing.
+Changed to accomodate unlimited length source lines.
+Line continuation now works as advertised.
+Source lines can be arbitrarily long.
+Refined grammar hacks so that /= assignment works. Regular expressions
+ starting with /= are recognized at the beginning of a line, after && or ||
+ and after ~ or !~. More contexts can be added if necessary.
+Fixed IGNORECASE (multiple scans for backslash).
+Condensed expression_lists in array references.
+Detect and warn for correct # args in builtin functions -- call most of them
+ with a fixed number (i.e. fill in defaults at parse-time rather than at
+ run-time).
+Load ENVIRON only if it is referenced (detected at parse-time).
+Treat NF, FS, RS, NR, FNR specially at parse time, to improve run time.
+Fold constant expressions at parse time.
+Do make_regexp() on third arg. of split() at parse tiem if it is a constant.
+
+builtin.c:
+
+srand() returns 0 the first time called.
+Replaced alloca() with malloc() in do_sprintf().
+Fixed setting of RSTART and RLENGTH in do_match().
+Got rid of get_{one,two,three} and allowance for variable # of args. at
+ run-time -- this is now done at parse-time.
+Fixed latent bug in [g]sub whereby changes to $0 would never get made.
+Rewrote much of sub_common() for simplicity and performance.
+Added ctime() and time() builtin functions (unless -DSTRICT). ctime() returns
+ a time string like the C function, given the number of seconds since the epoch
+ and time() returns the current time in seconds.
+do_sprintf() now checks for mismatch between format string and number of
+ arguments supplied.
+
+dfa.c
+
+This is borrowed (almost unmodified) from GNU grep to provide faster searches.
+
+eval.c
+
+Node_var, Node_var_array and Node_param_list handled from macro rather
+ than in r_tree_eval().
+Changed cmp_nodes() to not do a force_number() -- this, combined with a
+ force_number() on ARGV[] and ENVIRON[] brings it into line with other awks
+Greatly simplified cmp_nodes().
+Separated out Node_NF, Node_FS, Node_RS, Node_NR and Node_FNR in get_lhs().
+All adjacent string concatenations now done at once.
+
+field.c
+
+Added support for FIELDWIDTHS.
+Fixed bug in get_field() whereby changes to a field were not always
+ properly reflected in $0.
+Reordered tests in parse_field() so that reference off the end of the buffer
+ doesn't happen.
+set_FS() now sets *parse_field i.e. routine to call depending on type of FS.
+It also does make_regexp() for FS if needed. get_field() passes FS_regexp
+ to re_parse_field(), as does do_split().
+Changes to set_field() and set_record() to avoid malloc'ing and free'ing the
+ field nodes repeatedly. The fields now just point into $0 unless they are
+ assigned to another variable or changed. force_number() on the field is
+ *only* done when the field is needed.
+
+gawk.1
+
+Fixed troff formatting problem on .TP lines.
+
+io.c
+
+Moved some code out into iop.c.
+Output from pipes and system() calls is properly synchronized.
+Status from pipe close properly returned.
+Bug in getline with no redirect fixed.
+
+iop.c
+
+This file contains a totally revamped get_a_record and associated code.
+
+main.c
+
+Command line programs no longer use a temporary file.
+Therefore, tmpnam() no longer required.
+Deprecated -a and -e options -- they will go away in the next release,
+ but for now they cause a warning.
+Moved -C, -V, -c options to -W ala posix.
+Added -W posix option: throw out \x
+Added -W lint option.
+
+
+node.c
+
+force_number() now allows pure numerics to have leading whitespace.
+Added make_string facility to optimize case of adding an already malloc'd
+ string.
+Cleaned up and simplified do_deref().
+Fixed bug in handling of stref==255 in do_deref().
+
+re.c
+
+contains the interface to regexp code
+
+Changes from 2.11.1 to FSF version of same
+------------------------------------------
+Thu Jan 4 14:19:30 1990 Jim Kingdon (kingdon at albert)
+
+ * Makefile (YACC): Add -y to bison part.
+
+ * missing.c: Add #include <stdio.h>.
+
+Sun Dec 24 16:16:05 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
+
+ * Makefile: Add (commented out) default defines for Sony News.
+
+ * awk.h: Move declaration of vprintf so it will compile when
+ -DVPRINTF_MISSING is defined.
+
+Mon Nov 13 18:54:08 1989 Robert J. Chassell (bob at apple-gunkies.ai.mit.edu)
+
+ * gawk.texinfo: changed @-commands that are not part of the
+ standard, currently released texinfmt.el to those that are.
+ Otherwise, only people with the as-yet unreleased makeinfo.c can
+ format this file.
+
+Changes from 2.11beta to 2.11.1 (production)
+--------------------------------------------
+
+Went from "beta" to production status!!!
+
+Now flushes stdout before closing pipes or redirected files to
+synchronize output.
+
+MS-DOS changes added in.
+
+Signal handler return type parameterized in Makefile and awk.h and
+some lint removed. debug.c cleaned up.
+
+Fixed FS splitting to never match null strings, per book.
+
+Correction to the manual's description of FS.
+
+Some compilers break on char *foo = "string" + 4 so fixed version.sh and
+main.c.
+
+Changes from 2.10beta to 2.11beta
+---------------------------------
+
+This release fixes all reported bugs that we could reproduce. Probably
+some of the changes are not documented here.
+
+The next release will probably not be a beta release!
+
+The most important change is the addition of the -nostalgia option. :-)
+
+The documentation has been improved and brought up-to-date.
+
+There has been a lot of general cleaning up of the code that is not otherwise
+documented here. There has been a movement toward using standard-conforming
+library routines and providing them (in missing.d) for systems lacking them.
+Improved (hopefully) configuration through Makfile modifications and missing.c.
+In particular, straightened out confusion over vprintf #defines, declarations
+etc.
+
+Deleted RCS log comments from source, to reduce source size by about one third.
+Most of them were horribly out-of-date, anyway.
+
+Renamed source files to reflect (for the most part) their contents.
+
+More and improved error messages. Cleanup and fixes to yyerror().
+String constants are not altered in input buffer, so error messages come out
+better. Fixed usage message. Make use of ANSI C strerror() function
+(provided).
+
+Plugged many more memory leaks. The memory consumption is now quite
+reasonable over a wide range of programs.
+
+Uses volatile declaration if STDC > 0 to avoid problems due to longjmp.
+
+New -a and -e options to use awk or egrep style regexps, respectively,
+since POSIX says awk should use egrep regexps. Default is -a.
+
+Added -v option for setting variables before the first file is encountered.
+Version information now uses -V and copyleft uses -C.
+
+Added a patchlevel.h file and its use for -V and -C.
+
+Append_right() optimized for major improvement to programs with a *lot*
+of statements.
+
+Operator precedence has been corrected to match draft Posix.
+
+Tightened up grammar for builtin functions so that only length
+may be called without arguments or parentheses.
+
+/regex/ is now a normal expression that can appear in any expression
+context.
+
+Allow /= to begin a regexp. Allow ..[../..].. in a regexp.
+
+Allow empty compound statements ({}).
+
+Made return and next illegal outside a function and in BEGIN/END respectively.
+
+Division by zero is now illegal and causes a fatal error.
+
+Fixed exponentiation so that x ^ 0 and x ^= 0 both return 1.
+
+Fixed do_sqrt, do_log, and do_exp to do argument/return checking and
+print an error message, per the manual.
+
+Fixed main to catch SIGSEGV to get source and data file line numbers.
+
+Fixed yyerror to print the ^ at the beginning of the bad token, not the end.
+
+Fix to substr() builtin: it was failing if the arguments
+weren't already strings.
+
+Added new node value flag NUMERIC to indicate that a variable is
+purely a number as opposed to type NUM which indicates that
+the node's numeric value is valid. This is set in make_number(),
+tmp_number and r_force_number() when appropriate and used in
+cmp_nodes(). This fixed a bug in comparison of variables that had
+numeric prefixes. The new code uses strtod() and eliminates is_a_number().
+A simple strtod() is provided for systems lacking one. It does no
+overflow checking, so could be improved.
+
+Simplification and efficiency improvement in force_string.
+
+Added performance tweak in r_force_number().
+
+Fixed a bug with nested loops and break/continue in functions.
+
+Fixed inconsistency in handling of empty fields when $0 has to be rebuilt.
+Happens to simplify rebuild_record().
+
+Cleaned up the code associated with opening a pipe for reading. Gawk
+now has its own popen routine (gawk_popen) that allocates an IOBUF
+and keeps track of the pid of the child process. gawk_pclose
+marks the appropriate child as defunct in the right struct redirect.
+
+Cleaned up and fixed close_redir().
+
+Fixed an obscure bug to do with redirection. Intermingled ">" and ">>"
+redirects did not output in a predictable order.
+
+Improved handling of output buffering: now all print[f]s redirected to a tty
+or pipe are flushed immediately and non-redirected output to a tty is flushed
+before the next input record is read.
+
+Fixed a bug in get_a_record() where bcopy() could have copied over
+a random pointer.
+
+Fixed a bug when RS="" and records separated by multiple blank lines.
+
+Got rid of SLOWIO code which was out-of-date anyway.
+
+Fix in get_field() for case where $0 is changed and then $(n) are
+changed and then $0 is used.
+
+Fixed infinite loop on failure to open file for reading from getline.
+Now handles redirect file open failures properly.
+
+Filenames such as /dev/stdin now allowed on the command line as well as
+in redirects.
+
+Fixed so that gawk '$1' where $1 is a zero tests false.
+
+Fixed parsing so that `RLENGTH -1' parses the same as `RLENGTH - 1',
+for example.
+
+The return from a user-defined function now defaults to the Null node.
+This fixes a core-dump-causing bug when the return value of a function
+is used and that function returns no value.
+
+Now catches floating point exceptions to avoid core dumps.
+
+Bug fix for deleting elements of an array -- under some conditions, it was
+deleting more than one element at a time.
+
+Fix in AWKPATH code for running off the end of the string.
+
+Fixed handling of precision in *printf calls. %0.2d now works properly,
+as does %c. [s]printf now recognizes %i and %X.
+
+Fixed a bug in printing of very large (>240) strings.
+
+Cleaned up erroneous behaviour for RS == "".
+
+Added IGNORECASE support to index().
+
+Simplified and fixed newnode/freenode.
+
+Fixed reference to $(anything) in a BEGIN block.
+
+Eliminated use of USG rand48().
+
+Bug fix in force_string for machines with 16-bit ints.
+
+Replaced use of mktemp() with tmpnam() and provided a partial implementation of
+the latter for systems that don't have it.
+
+Added a portability check for includes in io.c.
+
+Minor portability fix in alloc.c plus addition of xmalloc().
+
+Portability fix: on UMAX4.2, st_blksize is zero for a pipe, thus breaking
+iop_alloc() -- fixed.
+
+Workaround for compiler bug on Sun386i in do_sprintf.
+
+More and improved prototypes in awk.h.
+
+Consolidated C escape parsing code into one place.
+
+strict flag is now turned on only when invoked with compatability option.
+It now applies to fewer things.
+
+Changed cast of f._ptr in vprintf.c from (unsigned char *) to (char *).
+Hopefully this is right for the systems that use this code (I don't).
+
+Support for pipes under MSDOS added.
--- /dev/null
+March 2001:
+
+It looks like the revised 1003.2 standard will actually follow the
+rules given below. Hallelujah!
+
+October 1998:
+
+The 1003.2 work has been at a stand-still for ages. Who knows if or
+when a new revision will actually happen...
+
+August 1995:
+
+Although the published 1003.2 standard contained the incorrect
+comparison rules of 11.2 draft as described below, no actual implementation
+of awk (that I know of) actually used those rules.
+
+A revision of the 1003.2 standard is in progress, and in the May 1995
+draft, the rules were fixed (based on my submissions for interpretation
+requests) to match the description given below. Thus, the next version
+of the standard will have a correct description of the comparison
+rules.
+
+June 1992:
+
+Right now, the numeric vs. string comparisons are screwed up in draft
+11.2. What prompted me to check it out was the note in gnu.bug.utils
+which observed that gawk was doing the comparison $1 == "000"
+numerically. I think that we can agree that intuitively, this should
+be done as a string comparison. Version 2.13.2 of gawk follows the
+current POSIX draft. Following is how I (now) think this
+stuff should be done.
+
+1. A numeric literal or the result of a numeric operation has the NUMERIC
+ attribute.
+
+2. A string literal or the result of a string operation has the STRING
+ attribute.
+
+3. Fields, getline input, FILENAME, ARGV elements, ENVIRON elements and the
+ elements of an array created by split() that are numeric strings
+ have the STRNUM attribute. Otherwise, they have the STRING attribute.
+ Uninitialized variables also have the STRNUM attribute.
+
+4. Attributes propagate across assignments, but are not changed by
+ any use. (Although a use may cause the entity to acquire an additional
+ value such that it has both a numeric and string value -- this leaves the
+ attribute unchanged.)
+
+When two operands are compared, either string comparison or numeric comparison
+may be used, depending on the attributes of the operands, according to the
+following (symmetric) matrix:
+
+ +----------------------------------------------
+ | STRING NUMERIC STRNUM
+--------+----------------------------------------------
+ |
+STRING | string string string
+ |
+NUMERIC | string numeric numeric
+ |
+STRNUM | string numeric numeric
+--------+----------------------------------------------
+
+So, the following program should print all OKs.
+
+echo '0e2 0a 0 0b
+0e2 0a 0 0b' |
+$AWK '
+NR == 1 {
+ num = 0
+ str = "0e2"
+
+ print ++test ": " ( (str == "0e2") ? "OK" : "OOPS" )
+ print ++test ": " ( ("0e2" != 0) ? "OK" : "OOPS" )
+ print ++test ": " ( ("0" != $2) ? "OK" : "OOPS" )
+ print ++test ": " ( ("0e2" == $1) ? "OK" : "OOPS" )
+
+ print ++test ": " ( (0 == "0") ? "OK" : "OOPS" )
+ print ++test ": " ( (0 == num) ? "OK" : "OOPS" )
+ print ++test ": " ( (0 != $2) ? "OK" : "OOPS" )
+ print ++test ": " ( (0 == $1) ? "OK" : "OOPS" )
+
+ print ++test ": " ( ($1 != "0") ? "OK" : "OOPS" )
+ print ++test ": " ( ($1 == num) ? "OK" : "OOPS" )
+ print ++test ": " ( ($2 != 0) ? "OK" : "OOPS" )
+ print ++test ": " ( ($2 != $1) ? "OK" : "OOPS" )
+ print ++test ": " ( ($3 == 0) ? "OK" : "OOPS" )
+ print ++test ": " ( ($3 == $1) ? "OK" : "OOPS" )
+ print ++test ": " ( ($2 != $4) ? "OK" : "OOPS" ) # 15
+}
+{
+ a = "+2"
+ b = 2
+ if (NR % 2)
+ c = a + b
+ print ++test ": " ( (a != b) ? "OK" : "OOPS" ) # 16 and 22
+
+ d = "2a"
+ b = 2
+ if (NR % 2)
+ c = d + b
+ print ++test ": " ( (d != b) ? "OK" : "OOPS" )
+
+ print ++test ": " ( (d + 0 == b) ? "OK" : "OOPS" )
+
+ e = "2"
+ print ++test ": " ( (e == b "") ? "OK" : "OOPS" )
+
+ a = "2.13"
+ print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" )
+
+ a = "2.130000"
+ print ++test ": " ( (a != 2.13) ? "OK" : "OOPS" )
+
+ if (NR == 2) {
+ CONVFMT = "%.6f"
+ print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" )
+ }
+}'
--- /dev/null
+This is a list of known problems in gawk 3.1.
+I don't know when this will be fixed, if ever. See also FUTURES
+and the gawk.texi doc for other things that need doing.
+
+1. The interactions with the lexer and yyerror need reworking. It is possible
+ to get line numbers that are one line off if --compat or --posix is
+ true and either `nextfile' or `delete array' are used.
+
+ Really the whole lexical analysis stuff needs reworking.
--- /dev/null
+README:
+
+This is GNU Awk 3.1.5. It is upwardly compatible with the Bell Labs
+research version of awk. It is almost completely compliant with the
+1993 POSIX 1003.2 standard for awk. (See the note below about POSIX.)
+
+This is a bug fix release. See NEWS and ChangeLog for details.
+
+Work to be done is described briefly in the FUTURES file. Changes in this
+version are summarized in the NEWS file. Please read the LIMITATIONS file.
+
+Read the file POSIX.STD for a discussion of how the standard says
+comparisons should be done vs. how they really should be done and how
+gawk does them.
+
+To format the documentation with TeX, use at least version 2000-10-27.17
+of texinfo.tex. There is a usable copy of texinfo.tex in the doc directory.
+
+INSTALLATION:
+
+Check whether there is a system-specific README file for your system under
+the `README_d' directory. If there's something there that you should
+have read and didn't, and you bug me about it, I'm going to yell at you.
+
+See the file INSTALL for installation instructions.
+
+If you have neither bison nor yacc, use the awkgram.c file here. It was
+generated with bison, and has no proprietary code in it. (Note that
+modifying awkgram.y without bison or yacc will be difficult, at best.
+You might want to get a copy of bison from the FSF too.)
+
+If you have a Windows32, MS-DOS or OS/2 system, use the stuff in the `pc'
+directory. Similarly, there is a separate directory for VMS.
+
+Ports for the Atari and Tandem are supplied, but they are unsupported.
+Thus, their code appears in the `unsupported' directory.
+
+Appendix B of ``GAWK: Effective Awk Programming'' discusses configuration
+in detail. The configuration process is based on GNU Autoconf and
+Automake.
+
+After successful compilation, do `make check' to run the test suite.
+There should be no output from the `cmp' invocations except in the
+cases where there are small differences in floating point values, and
+possibly in the case of strftime. Several of the tests ignore errors
+on purpose; those are not a problem. If there are other differences,
+please investigate and report the problem.
+
+PRINTING THE MANUAL
+
+The `doc' directory contains a recent version of texinfo.tex, which will
+be necessary for printing the manual. Use `make dvi' to get a DVI file
+from the manual. In the `doc' directory, use `make postscript' to get
+PostScript versions of the manual, the man page, and the reference card.
+
+BUG REPORTS AND FIXES (Un*x systems):
+
+Please coordinate changes through Arnold Robbins. In particular, see
+the section in the manual on reporting bugs. Note that comp.lang.awk
+is about the worst place to post a gawk bug report. Please, use the
+mechanisms outlined in the manual.
+
+Email should be sent to bug-gawk@gnu.org. This address sends mail to
+Arnold Robbins and the general GNU utilities bug list. The advantage
+to using this address is that bug reports are archived at GNU Central.
+
+Arnold Robbins
+
+BUG REPORTS AND FIXES, non-Unix systems:
+
+Amiga:
+ Fred Fish
+ fnf@ninemoons.com
+
+Alpha/Linux:
+ Michal Jaegermann
+ michal@gortel.phys.ualberta.ca
+
+BeOS:
+ Martin Brown
+ mc@whoever.com
+
+MS-DOS:
+ Scott Deifik
+ scottd@amgen.com
+
+ Darrel Hankerson
+ hankedr@mail.auburn.edu
+
+MS-Windows:
+ Juan Grigera
+ juan@biophnet.unlp.edu.ar
+
+OS/2:
+ andreas.buening@@nexgo.de
+
+Tandem:
+ Stephen Davies
+ scldad@sdc.com.au
+
+VMS:
+ Pat Rankin
+ rankin@pactechdata.com
--- /dev/null
+Sat Feb 18 23:07:55 EST 1995
+
+Starting with 2.15.6, gawk will preserve the value of NF and $0 for
+the last record read into the END rule(s). This is important to you
+if your program uses
+
+ print
+
+in an END rule to mean
+
+ print ""
+
+(i.e., print nothing). Examine your awk programs carefully to make sure
+that they use `print ""' instead of `print', otherwise you will get
+strange results.
+
+If you send me email about this, without having read this
+file, I will yell at you.
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+
+Compiling GAWK on VMS:
+
+ There's a DCL command procedure that will issue all the necessary
+CC and LINK commands, and there's also a Makefile for use with the MMS
+utility. From the source directory, use either
+ |$ @[.VMS]VMSBUILD.COM
+or
+ |$ MMS/DECRIPTION=[.VMS]DECSRIP.MMS GAWK
+
+DEC C -- use either vmsbuild.com or descrip.mms as is.
+VAX C -- use `@vmsbuild VAXC' or `MMS/MACRO=("VAXC")'. On a system
+ with both VAX C and DEC C installed where DEC C is the default,
+ use `MMS/MACRO=("VAXC","CC=CC/VAXC")' for the MMS variant; for
+ the vmsbuild.com variant, any need for `/VAXC' will be detected
+ automatically.
+GNU C -- use `@vmsbuild GNUC' or `MMS/MACRO=("GNUC")'. On a system
+ where the GCC command is not already defined, use either
+ `@vmsbuild GNUC DO_GNUC_SETUP' or
+ `MMS/MACRO=("GNUC","DO_GNUC_SETUP")'.
+
+ Tested under Alpha/VMS V7.1 using DEC C V6.4. GAWK should work
+without modifications for VMS V4.6 and up.
+
+
+Installing GAWK on VMS:
+
+ All that's needed is a 'foreign' command, which is a DCL symbol
+whose value begins with a dollar sign.
+ |$ GAWK :== $device:[directory]GAWK
+(Substitute the actual location of gawk.exe for 'device:[directory]'.)
+That symbol should be placed in the user's login.com or in the system-
+wide sylogin.com procedure so that it will be defined every time the
+user logs on.
+
+ Optionally, the help entry can be loaded into a VMS help library.
+ |$ LIBRARY/HELP SYS$HELP:HELPLIB [.VMS]GAWK.HLP
+(You may want to substitute a site-specific help library rather than
+the standard VMS library 'HELPLIB'.) After loading the help text,
+ |$ HELP GAWK
+will provide information about both the gawk implementation and the
+awk programming language.
+
+ The logical name AWK_LIBRARY can designate a default location
+for awk program files. For the '-f' option, if the specified filename
+has no device or directory path information in it, Gawk will look in
+the current directory first, then in the directory specified by the
+translation of AWK_LIBRARY if it the file wasn't found. If the file
+still isn't found, then ".awk" will be appended and the file access
+will be re-tried. If AWK_LIBRARY is not defined, that portion of the
+file search will fail benignly.
+
+
+Running GAWK on VMS:
+
+ Command line parsing and quoting conventions are significantly
+different on VMS, so examples in _The_GAWK_Manual_ or the awk book
+often need minor changes. They *are* minor though, and all the awk
+programs should run correctly.
+
+ Here are a couple of trivial tests:
+ |$ gawk -- "BEGIN {print ""Hello, World!""}"
+ |$ gawk -"W" version !could also be -"W version" or "-W version"
+Note that upper- and mixed-case text must be quoted.
+
+ The VMS port of Gawk includes a DCL-style interface in addition
+to the original shell-style interface. See the help entry for details.
+One side-effect of dual command line parsing is that if there's only a
+single parameter (as in the quoted string program above), the command
+becomes ambiguous. To work-around this, the normally optional "--"
+flag is required to force shell rather than DCL parsing. If any other
+dash-type options (or multiple parameters such as data files to be
+processed) are present, there is no ambiguity and "--" can be omitted.
+
+ The logical name AWKPATH can be used to override the default
+search path of "SYS$DISK:[],AWK_LIBRARY:" when looking for awk program
+files specified by the '-f' option. The format of AWKPATH is a comma-
+separated list of directory specifications. When defining it, the
+value should be quoted so that it retains a single translation, not a
+multi-translation RMS searchlist.
+
--- /dev/null
+Tue Mar 11 13:21:26 IST 2003
+============================
+
+On AIX 4.2 systems, you need:
+
+ ./configure --disable-nls && make all check install
--- /dev/null
+Sun May 2 18:40:46 IDT 1999
+
+See the README.1st file in the atari directory.
+
+--------------------------------------------------------
+Gawk on the Atari has been compiled and tested using gcc, both
+with and without -mshort flag. Other compilers can be used but if
+sizeof(pointer) != sizeof(int) this code will not compile correctly
+with a non-ANSI compiler (prototypes and library).
+
+Compiled executables were tested and passed successfully a test suite
+similar to 'make test'. Required changes are minor and minor
+modifications are due to differences in environment and/or shell. If
+a need will arise a modified test suite with a driving Makefile (for
+gulam) is available on a request from Michal Jaegermann,
+michal@gortel.phys.ualberta.ca or michal@ellpspace.math.ualberta.ca,
+via e-mail.
+
+Sample files atari/Makefile.st, atari/Makefile.awklib and
+atari/config.h assume gcc compilation and execution under TOS; it is
+likely that one would want to change it for another setup. If they
+are ok then copy atari/Makefile.st to Makefile, atari/config.h to
+config.h and atari/Makefile.awklib to awklib/Makefile.. Pay attention
+to code fragments bracketed by '#ifdef atarist ... #endif'. These
+modifications may not be required/desired with a different OS and/or
+libraries.
--- /dev/null
+README for GNU awk under BeOS
+Last updated MCB, Tue Feb 6 10:15:46 GMT 2001
+
+BeOS port contact: Martin C Brown (mc@whoever.com)
+
+Building/Installing
+--------------------------
+
+Since BeOS DR9, all the tools that you should need to build gawk are now
+included with BeOS. The process is basically identical to the Unix process
+of running configure and then make. Full instructions are given below:
+
+You can compile gawk under BeOS by extracting the standard sources,
+and running the configure script. You MUST specify the location prefix
+for the installation directory. Under BeOS DR9 and beyond the best
+directory to use is /boot/home/config, so the configure command
+would be:
+
+$ configure --prefix=/boot/home/config
+
+This will install the compiled application into /boot/home/config/bin,
+which is already specified in the standard PATH.
+
+Once the configuration process has been completed, you can run make and
+then make install:
+
+$ make
+....
+$ make install
+
+Socket Notes
+----------------------
+
+Due to the socket implementation under BeOS not all of the features under
+gawk's socket implementation may work properly. In particular:
+
+ BeOS does not support a BSD SO_LINGER option, so sockets cannot remain
+ open after a close if data is still present on the incoming buffer.
+
+ BeOS does not allow data to be read from a socket without removing the data
+ from the buffer (peek). If you need to use this feature in gawk, create a
+ separate input buffer and peek into your own copy, rather than the OS version.
+
+ BeOS does not support RAW socket connections, only UDP or TCP.
+
+Note that these are BeOS Unix-layer compatibility problems, and only affect certain
+aspects of network communication. Most socket based gawk scripts, and any scripts
+that do not rely on sockets should work fine (excepting any other notes in this section).
+
+File Handle Notes
+---------------------------
+
+Expect the multiple file test (when running make check) to fail. The reason for this is
+explained in the email shown below:
+
+-------------------------------------------------------
+From mc@whoever.com Sun Jul 23 17:06:38 2000
+Date: Sun, 23 Jul 2000 07:23:49 +0100
+Subject: Re: gawk-3.0.5 results on BeOS
+From: Martin C Brown <mc@whoever.com>
+To: Aharon Robbins <arnold@skeeve.com>, <haible@ilog.fr>
+
+Arnold/Bruno,
+
+> This is a known BeOS problem. I am cc'ing the BeOS port person.
+> Sorry I don't have a fix.
+
+This problem is directly related to the FOPEN_MAX/OPEN_MAX parameter used in
+the stdio library by the BeOS. It seems that the BeOS strictly enforces this
+number to the point that opening the 128th file causes all previously opened
+files (except stdin/out/err) to be closed - hence the bad number.
+
+I've tried this outside of gawk and the same thing happens, so it's not a
+gawk problem.
+
+I've spent the past few days trying to find a suitable workaround, but it's
+obviously difficult trying to patch a kernel from the outside :))
+
+I'll be reporting this as a bug to Be shortly.
+
+MC
+
+--
+Martin 'MC' Brown, mc@mcslp.com http://www.mcwords.com
+Writer, Author, Consultant
+'Life is pain, anyone who says differently is selling something'
--- /dev/null
+From: courierdavid@hotmail.com
+Newsgroups: comp.lang.awk
+Subject: Re: Compiling gawk extensions under Cygwin
+Date: 14 Mar 2005 20:47:09 -0800
+Organization: http://groups.google.com
+Lines: 67
+Message-ID: <1110862029.175727.109280@o13g2000cwo.googlegroups.com>
+References: <1e4e8dbe.0501140813.18248833@posting.google.com>
+ <u62nb2-pro.ln1@news.heiming.de>
+NNTP-Posting-Host: 194.237.142.24
+Mime-Version: 1.0
+Content-Type: text/plain; charset="iso-8859-1"
+X-Trace: posting.google.com 1110862033 8921 127.0.0.1 (15 Mar 2005 04:47:13 GMT)
+X-Complaints-To: groups-abuse@google.com
+NNTP-Posting-Date: Tue, 15 Mar 2005 04:47:13 +0000 (UTC)
+User-Agent: G2/0.2
+Complaints-To: groups-abuse@google.com
+Injection-Info: o13g2000cwo.googlegroups.com; posting-host=194.237.142.24;
+ posting-account=Iz4C5wwAAABx1yG_ft8eEAI99Wu1Tku1
+Path: news.012.net.il!seanews2.seabone.net!newsfeed.albacom.net!news.mailgate.org!newsfeed.stueberl.de!proxad.net!64.233.160.134.MISMATCH!postnews.google.com!o13g2000cwo.googlegroups.com!not-for-mail
+Xref: news.012.net.il comp.lang.awk:21835
+
+Thanks for your help there Michael. I wouldn't have thought of that one
+myself without your help :-)
+
+Anyway - for those who must stick with Cygwin here's a method that
+works using the mingw32 makefiles and some modifications:
+
+Basically you need to extract all exportable symbol names from the
+gawk.exe file into a text file and then create a dummy library file
+which we can link against on Cygwin. You then throw the library file
+away because in reality we use the gawk.exe file as the provider of
+those functions.
+
+1. First grab the gawk source, e.g. gawk-3.1.4.tar.bz2 and decompress
+it.
+2. Move to the gawk-3.1.4 directory you just created.
+3. cp pc/* . (copy the pc directory into the main one)
+4. edit makefile - uncomment lines "DYN_FLAGS", "DYN_EXP", "DYN_OBJ"
+and "DYN_MAKEXP=$(DMEmingw32)
+5. make mingw32 (make a gawk.exe)
+6. run "gcc -o gawk.exe array.o builtin.o eval.o field.o gawkmisc.o
+io.o main.o ext.o msg.o node.o profile.o re.o version.o dlfcn.o
+gawk.exp awkgram.o getid.o popen.o getopt.o getopt1.o dfa.o regex.o
+random.o" (i.e. remove the -s from the compile command from the
+makefile so the symbols are left in gawk.exe)
+
+now export all symbols from gawk.exe into foo.def so that we can put
+these in our library
+7. echo EXPORTS > foo.def
+8. nm gawk.exe | grep -E ' [TBD] _' | sed 's/.* [TBD] _//' >> foo.def
+9. cp foo.def gawkw32.def
+
+build the new library with all symbols included
+10. make mingw32
+
+Now you will see a file "libgawk.a" which you can link against to
+create extensions. For example to build an extension called "file" run:
+
+gcc -shared -dll -DHAVE_CONFIG_H -I . extension/file.c -o file.dll -L .
+-lgawk
+
+Then you can load it in gawk using the expression:
+
+extension("./file.dll", "dlload");
+
+You must use the gawk you compiled from source though. It won't work
+with any other gawk unfortunately :-( But that's OK because the
+stripped gawk is not too big in size.
+
+Cheers,
+Dave.
+
+Michael Heiming wrote:
+> In comp.lang.awk David Smith <courierdavid@hotmail.com>:
+> > Has anyone managed to compile gawk extensions (such as "filefuncs")
+> > under Cygwin?
+>
+> Solution is pretty simple, install a real OS, Linux/*BSD or any
+> other unix and this and further problems won't happen.
+>
+> Good luck
+>
+> --
+> Michael Heiming (X-PGP-Sig > GPG-Key ID: EDD27B94)
+> mail: echo zvpunry@urvzvat.qr | perl -pe 'y/a-z/n-za-m/'
+> #bofh excuse 242: Software uses US measurements, but the OS
+> is in metric...
--- /dev/null
+Wed Jul 28 16:28:42 IDT 2004
+============================
+As of gawk 3.1.4, configure should correctly handle HP-UX and
+I18N issues. -- Arnold
+--------------------------------------------------------------
+2003-12-10 15:19:38 EST
+Michael Elizabeth Chastain <mec.gnu@mindspring.com>
+
+I built and tested gawk on hppa-hp-hpux11.11 and ia64-hp-hpux11.23.
+All the tests in the test suite passed.
+
+I built with these compilers:
+
+ gcc 3.3.2
+ hp ansi C from /opt/ansic/bin
+ hp aCC from /opt/aCC/bin
+
+I ran into these problems:
+
+ NLS does not work; configure with --disable-nls.
+ -D_XOPEN_SOURCE=500 does not work.
+ Multibyte support is not available.
+
+To get multibyte support, the following ugly hack might work:
+--- gawk-3.1.3.orig/custom.h 2003-06-09 17:45:53.000000000 +0200
++++ gawk-3.1.3/custom.h 2003-12-17 15:55:04.000000000 +0100
+@@ -101,4 +101,7 @@
+ #undef HAVE_TZSET
+ #define HAVE_TZSET 1
+ #define _TZSET 1
++/* an ugly hack: */
++#include <sys/_mbstate_t.h>
++#define HAVE_MBRTOWC 1
+ #endif
+
+-------------------------------
+Mon, 27 May 2002 17:55:46 +0800
+
+The network support "|&" may not work under HP-UX 11.
+An error message appears similar to this:
+gawk: test_script.awk:3: fatal: get_a_record: iop->buf: can't allocate -61246
+bytes of memory (not enough space)
+
+Solution:
+This is a bug in the fstat() call of HP-UX 11.00, please apply
+the cumulative ARPA Transport patch PHNE_26771 to fix it.
+
+The following is the related description in PHNE_26771:
+
+ Customer's application gets the wrong value from fstat().
+ Resolution:
+ The value returned via st_blksize is now retrieved
+ from the same info as in 10.20.
+
+In case you cannot apply the HP patch, the attached patch to gawk source
+might work.
+
+Xiang Zhao <xiangz@163.net>
+Stepan Kasal <kasal@math.cas.cz>
+
+diff -ur gawk-3.1.3.a0/posix/gawkmisc.c gawk-3.1.3.a1/posix/gawkmisc.c
+--- gawk-3.1.3.a0/posix/gawkmisc.c Sun May 25 15:26:19 2003
++++ gawk-3.1.3.a1/posix/gawkmisc.c Fri Jul 11 08:56:03 2003
+@@ -126,7 +126,13 @@
+ * meant for in the first place.
+ */
+ #ifdef HAVE_ST_BLKSIZE
+-#define DEFBLKSIZE (stb->st_blksize > 0 ? stb->st_blksize : BUFSIZ)
++ /*
++ * 100k must be enough for everybody,
++ * bigger number means probably a bug in fstat()
++ */
++#define MAXBLKSIZE 102400
++#define DEFBLKSIZE (stb->st_blksize > 0 && stb->st_blksize <= MAXBLKSIZE \
++ ? stb->st_blksize : BUFSIZ)
+ #else
+ #define DEFBLKSIZE BUFSIZ
+ #endif
--- /dev/null
+Tue Mar 11 13:19:45 IST 2003
+============================
+
+On real Itanium systems, builds with GCC are fine. If you're using the
+Intel compiler `ecc', you need:
+
+ CC=ecc ./configure && make all check install CFLAGS='-g -Drestrict='
+
+Tue Apr 16 13:55:15 IDT 2002
+============================
+The current version of the IA-64 environment builds gawk without any problems.
+
+Wed Apr 25 17:17:01 IDT 2001
+============================
+
+The Intel IA-64 emulation environment that sits on top of 32-bit Linux
+has problems. Gawk does not work on it.
+
+1. The `sgicc' compiler lies to `configure' and pretends it's gcc. But it
+really isn't, and several things don't work.
+
+2. Even if used with gcc, the executable doesn't run; somehow quoted
+strings don't stay as one argument to gawk, which is, of course,
+disastrous.
+
+3. It's flaky; initially `configure' wouldn't even get past the getpgrp
+test. Then later it would.
+
+Arnold Robbins
+arnold@skeeve.com
--- /dev/null
+Thu Apr 17 14:41:17 EDT 1997
+
+Some Linux systems, notably RedHat systems through RedHat 4.1, have the
+symbolic links for /dev/stdin and /dev/stdout messed up. Specifically,
+/dev/stdin is linked to ../proc/self/fd/1 and /dev/stdout to
+../proc/self/fd/0. This is backwards. This causes strange behavior
+when using those files from within gawk.
+
+Removing and redoing the symlinks fixes the problem. It is fixed in
+post-4.1 RedHat Linux.
+
+Arnold Robbins
+arnold@gnu.org
+
+Sun Aug 3 15:07:06 EDT 1997
+
+As of version 3.1 of gawk, this is no longer a problem, since gawk now
+completely interprets the special file names internally.
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+Mon Jul 4 09:55:22 IDT 2005
+============================
+
+If you use GCC 4.0 under Mac OS X to compile gawk with optimization,
+AND multibyte support is *disabled*, the `ignrcas2' test fails. This is
+a compiler bug. Either compile it without optimization, or use gcc-3.3.
+
+All the other tests pass.
+
+Happily, the default is for the multibyte support to be enabled, so all
+the tests pass by defualt.
+
+The notes below no longer seem to apply.
+
+Sun Dec 3 18:11:09 IST 2000
+============================
+
+The `posix' test will fail because of output format differences but this
+is apparently otherwise benign.
+
+Gawk uses the system's mktime(3) routine, even though Autoconf thinks
+it's broken, so Caveat Emptor.
+
+If you ask me about either of these I will fuss at you for not having
+done your homework.
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+Fri Jun 3 12:20:17 IDT 2005
+============================
+
+As noted in the NEWS file, as of 3.1.5, gawk uses character values instead
+of byte values for `index', `length', `substr' and `match'. This works
+in multibyte and unicode locales.
+
+Wed Jun 18 16:47:31 IDT 2003
+============================
+
+Multibyte locales can cause occasional weirdness, in particular with
+ranges inside brackets: /[....]/. Something that works great for ASCII
+will choke for, e.g., en_US.UTF-8. One such program is test/gsubtst5.awk.
+
+By default, the test suite runs with LC_ALL=C and LANG=C. You
+can change this by doing (from a Bourne-style shell):
+
+ $ GAWKLOCALE=some_locale make check
+
+Then the test suite will set LC_ALL and LANG to the given locale.
+
+As of this writing, this works for en_US.UTF-8, and all tests
+pass except gsubtst5.
+
+For the normal case of RS = "\n", the locale is largely irrelevant.
+For other single byte record separators, using LC_ALL=C will give you
+much better performance when reading records. Otherwise, gawk has to
+make several function calls, *per input character* to find the record
+terminator. You have been warned.
--- /dev/null
+This is the README for GNU awk 3.1 under Windows32, OS/2, and DOS.
+
+ Gawk has been compiled and tested under OS/2, DOS, and Windows32 using
+the GNU development tools from DJ Delorie (DJGPP; DOS with special
+support for long filenames under Win95), Eberhard Mattes (EMX; OS/2,
+DOS, and Windows32 with rsxnt), and Jan-Jaap van der Heijden and Mumit Khan
+(Mingw32; Windows32). Microsoft Visual C/C++ can be used to build a Windows32
+version for Windows 9x/NT, and MSC can be used to build 16-bit versions
+for DOS and OS/2. (As of 3.1.2, the MSC version doesn't work, but the
+maintainer for it is working on fixing it.)
+
+ The cygwin environment (http://www.cygwin.com) may also be used
+to compile and run gawk under Windows. For cygwin, building and
+installation is the same as under Unix:
+
+ tar -xvpzf gawk-3.1.x.tar.gz
+ cd gawk-3.1.x
+ ./configure && make
+
+The `configure' step takes a long time, but works otherwise.
+
+******************************** N O T E **********************************
+* The `|&' operator only works when gawk is compiled for cygwin. Neither *
+* socket support nor two-way pipes work in any other Windows environment! *
+***************************************************************************
+
+Building gawk
+-------------
+
+Building on DOS or Windows environments can be troublesome, in part due
+to shell limitations, the long filename issue, and various Windows32 pipe
+considerations. The situation is somewhat better on OS/2. The general
+recommendation is to use tools (especially make) which are compatible
+or built with the compiler to be used on gawk.
+
+Building versions which do not understand long filenames on systems
+that offer long names is a special case. The maintainers unpack the
+distribution and process using utilities (unzip, make, cmp) which do not
+use long filenames. (For example, the djgpp tools will work if LFN=n is
+set in the environment.)
+
+Copy the files in the `pc' directory (EXCEPT for `ChangeLog') to the
+directory with the rest of the gawk sources. (The subdirectories of
+`pc' need not be copied.) The makefile contains a configuration
+section with comments, and may need to be edited in order to work
+with your make utility.
+
+The "prefix" line in the Makefile is used during the install of gawk
+(and in building igawk.bat and igawk.cmd). Since the libraries for
+gawk will be installed under $(prefix)/lib/awk (e.g., /gnu/lib/awk),
+it is convenient to have this directory in DEFPATH of config.h.
+
+The makefile contains a number of targets for building various DOS and
+OS/2 versions. A list of targets will be printed if the make command is
+given without a target. As an example, to build gawk using the djgpp
+tools, enter "make djgpp".
+
+
+Testing and installing gawk
+---------------------------
+
+The command "make test" (and possibly "make install") requires several
+Unix-like tools, including an sh-like shell, sed, cp, and cmp. Only
+dmake and GNU make are known to work on "make test".
+
+There are two methods for the install: Method 1 uses a typical Unix-like
+approach and requires cat, cp, mkdir, sed, and sh; method 2 uses gawk
+and batch files. See the configuration section of the makefile.
+
+The file test/Makefile will need some editing (especially for DOS). A
+sample makefile with comments appears in pc/Makefile.tst, and can be
+used to modify test/Makefile for your platform. In addition, some
+files in the test directory may need to have their end-of-line markers
+converted, as described in Makefile.tst.
+
+As with building gawk, the OS, shell, and long filename issues come into
+play when testing, too. If you are testing gawk on a LFN aware system with
+some LFN aware tools, you may have problems if the shell that you specify in
+test/Makefile is not LFN aware. This problem will apply whether or not
+you are building a LFN aware gawk. See the comments in pc/Makefile.tst
+for more information on this.
+
+It is routine to install by hand, but note that the install target also
+builds igawk.bat and igawk.cmd, which are used to add an include
+facility to gawk (and which require sh).
+
+
+Notes
+-----
+
+1. Collections containing gawk and various utilities for OS/2 or DOS
+include the GNUish Project, Rommel's OS/2 collection at LEO, and the
+djgpp collection.
+
+The GNUish Project was designed to bring GNU-like programs to small
+systems running OS/2 and DOS. Binary distributions of gawk are
+maintained in GNUish, and include 16bit OS/2 and DOS, 32bit djgpp,
+and Windows32 versions. Information on GNUish is available via
+
+ http://www.simtel.net/simtel.net/
+or
+ ftp://ftp.simtel.net/simtelnet/gnu/gnuish
+
+Documentation appears in gnuish.htm (html) or gnuish.inf (info).
+
+Kai Uwe Rommel <rommel@leo.org> maintains a (mostly OS/2) collection at
+
+ http://www.leo.org/archiv/os2 or ftp://ftp.leo.org
+
+It contains emx-compiled (32bit) versions of gawk for OS/2, DOS, and Windows32,
+along with many OS/2 utilities.
+
+The djgpp collection at
+
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/
+
+contains a djgpp-compiled (32bit) version of gawk, along with many
+djgpp-compiled utilities.
+
+The Mingw32 collection at http://www.mingw.org contains links to ported
+software. The site by Jan-Jaap van der Heijden
+
+ http://agnes.dida.physik.uni-essen.de/~janjaap/
+
+is apparently no longer maintained, but it was accessible as of Jan 2001
+and may contain files of interest.
+
+
+2. The following table illustrates some of the differences among the various
+compiled versions of gawk. For example, the djgpp version runs on all the
+systems, but with differing capabilities: it supports long filenames under
+Win-9x but not under NT, and it runs as a DPMI application under OS/2 (which
+translates into "works in the DOS-box under OS/2, but not as a true OS/2
+application").
+
+ DOS Win/WfW Win9x NT OS/2
+ -------------------------------------------------------
+ djgpp | DPMI DPMI DPMI DPMI,NoLFN DPMI
+ emx(1) | N N N N OS2
+ emxbnd(2) | VCPI,DPMI DPMI DPMI,NoLFN DPMI,NoLFN DPMI,OS2
+ emxnt(3) | N N Windows32 Windows32 N
+ msc(4) | 16 16 16,NoLFN 16,NoLFN 16,DOS
+ msc6bnd | 16 16 16,NoLFN 16,NoLFN 16,DOS,OS2
+ msc6os2 | N N N N 16,OS2
+ vcWin32 | N N Windows32 Windows32 N
+ mingw32 | N N Windows32 Windows32 N
+
+ (1) Requires emxrt.
+
+ (2) May run as a DPMI app in plain DOS and in a DOS-shell under OS/2
+ or Windows, and as a true OS/2 application under OS/2. DPMI
+ requires rsxnt, and VCPI or use as an OS/2 app requires emxrt.
+
+ (3) Requires rsxnt.
+
+ (4) When compiling, MSC 8, when run in Windows 9x, will require that if
+ files are listed in #include statements with LFNs
+ (eg. <patchlevel.h>), that the file be named with the LFN.
+
+ 16 16bit; limited capacity, especially under DOS.
+
+ DOS Runs as a DOS application.
+
+ DPMI Dos Protected Mode Interface; program runs as a DOS application.
+ Under plain DOS, a DPMI server (such as csdpmi from the djgpp
+ archives) is required. See also VCPI.
+
+ emxrt The emx runtime, available from LEO.
+
+ N Not supported.
+
+ NoLFN No long filename support.
+
+ OS2 Runs as an OS/2 application.
+
+ rsxnt Runtimes for use with DPMI or Windows32.
+
+ VCPI Virtual Control Program Interface; program runs as a DOS app.
+ Memory managers (such as emm386) may need adjustment. VCPI cannot
+ be used under OS/2, Win/WfW, Win-95, or NT. See also DPMI.
+
+Windows32 Uses/supports Windows32 features (such as long filenames).
+
+Reportedly, NTEmacs (another Windows32 program) can run programs such as
+Windows32-gawk asynchronously. Similarly, as native OS/2 versions are a
+plus under OS/2 even for command-line programs, native Windows32 versions
+may be desired under NT and Win95.
+
+Users interested in Windows32 applications may also wish to examine the
+Cygnus cygwin project at http://sources.redhat.com/cygwin/ or the
+Mingw32 work at http://www.mingw.org. Windows32 gawk will often require
+that utilities run from within gawk be Windows32 (e.g., the tests place this
+requirement on the cat utility).
+
+
+3. An sh-like shell may be useful for awk programming (and is essential
+for running "make test"). Stewartson's sh (OS/2 and DOS) is a good
+choice, and may be found in GNUish.
+
+Stewartson's shell uses a configuration file (see "Command Line Building"
+in the sh manual page), and it may be necessary to edit the entry for
+gawk. The following entries are suggested:
+
+ -- $(EXTENDED_LINE) -- -- Comment only, not part of file --
+ gawk = unix ignoretype # emxbnd
+ gawk = unix # djgpp; msc* with Stewartson's stdargv
+ # No entry for emx or for msc* without stdargv
+ gawk = ignoretype # if you want something which which always work
+ # --but without the use of @-include files.
+
+However, users of djgpp versions of gawk may prefer "dos" over "unix"
+in the above, due to the way djgpp handles @-include files. Entries
+for other other utilities (such as sed and wc) may need to be edited
+in order to match your specific collection of programs.
+
+Daisuke Aoyama <jack@st.rim.or.jp> has ported Bash 1.14.7 to djgpp.
+This version worked flawlessly in tests with djgpp gawk and make. bash
+is now part of the djgpp collection; the older port may be found on
+
+ http://www.neongenesis.com/~jack/djgpp-work/beta/index.html
+
+Under OS/2, bash should be a good choice; however, there has been some
+trouble getting a solid version. As of Feb-95, there are two bash ports,
+available at LEO under shells/gnu/.
+
+LEO also contains a Korn shell (ksh), tcsh, zsh, and a demo of
+Hamilton's C shell, but these have not been tested with gawk by the
+maintainers. Reports are welcomed.
+
+Users of the emx versions of gawk may wish to set EMXSHELL, which
+overrides COMSPEC when running shells from emx programs. Similarly,
+the djgpp version of gawk respects SHELL.
+
+Compatibility among shells and various utilities (including gawk)
+continues to be a problem. Stewartson's shell may be the best choice
+for emx-compiled programs (although djgpp-bash almost works with
+emx on DOS). GNU make is recommended if using djgpp-bash.
+
+Beginning with 3.0.4, the MSC (DOS/Windows32) and Mingw32 versions write
+pipe and system() commands to a temporary file, and then execute
+with SHELL or COMSPEC. The current mechanism defaults to dos-style
+shell conventions unless the shell is one of sh, bash, csh, tcsh, sh32,
+sh16, or ksh.
+
+
+4. GNU make is available at LEO for OS/2, in the djgpp collection
+for DOS, and in the Mingw32 collection for Windows32.
+
+dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS
+Dept., University of Waterloo. OS/2 and DOS versions can be found as
+part of the GNUish project. Note that DOS users will need the DOS-only
+version (due to the swap requirement).
+
+Ndmake is by D.G. Kneller. This ShareWare program was later released
+as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is
+available at
+
+ ftp://ftp.simtel.net/simtelnet/msdos/c/ndmake45.zip
+
+
+5. Stewartson's shell contains sources for a setargv-replacement
+for MSC, which can add enhanced command-line processing capabilities
+to gawk. See the makefile. Note that there is a fatal bug in
+stdargv.c, triggered in the case of no closing quote. The following
+patch treats this case as if a quote was inserted as the last
+character on the command-line.
+
+478,479c478,482
+< else
+< spos = &spos[strlen (cpos)];
+---
+> else {
+> /* No matching quote. Fake it. */
+> spos = cpos + strlen (cpos) + 1;
+> break;
+> }
+
+
+Known bugs
+----------
+
+1. DJGPP version 1 has known problems with signals, and in the way it
+handles command-lines. Older versions of this file contain notes on
+other bugs, and on a few bugs uncovered in the v2 betas. Testing of
+gawk with DJGPP v1 ended with gawk-3.0. djgpp-2.01 and djgpp ports of
+GNU make 3.75 or later are strongly preferred, in part due to enhanced
+support for sh-like shells.
+
+2. emx does not support DST. On 2-Jan-96, Mattes writes:
+
+ Quotation from ISO 9899-1990:
+
+ 7.12.3.5 The strftime function
+ [...]
+ %Z is replaced by the time zone name or abbreviation, or by no
+ characters if no time zone is determinable.
+
+ As emx does not yet support DST, it does not know which one of the two
+ time zones (with DST vs. without DST) applies. In consequence, `no
+ time zone is determinable'.
+
+As a workaround, it may be possible to edit do_strftime() of builtin.c
+according to Mattes' recommendation:
+
+ If you happen to know whether DST applies or not for a given struct
+ tm, just set its tm_isdst to a positive value or to zero, respectively.
+ Then, strftime() will replace %Z with the name of the time zone.
+
+However, this probably won't yield a generic solution given that the rules
+for when DST starts and stops vary depending upon your location and the
+rules have changed over time. Most versions of UNIX maintain this
+information in a database (of sorts). In Solaris, for instance, it can be
+found in /usr/share/zoneinfo/*. The setting of the TZ environment variable
+(eg. TZ=US/Pacific) is then used to lookup the specifics for that locale.
+
+3. The 16-bit DOS version can exhaust memory on scripts such as Henry
+Spencer's "awf". Use GNU C versions if possible.
+
+4. builtin.c of gawk-3.0.[1-6] triggers a bug in MSC 6.00A. The makefile
+works around the bug by compiling builtin.c without optimizations (-Od).
+In limited testing, it appears that inserting some dummy code in
+builtin.c can provide a better solution than disabling optimizations.
+
+5. There are problems with system() when using the rsx package with emx
+programs (rsx is used in DPMI environments such as MS-Win). The djgpp
+versions are preferred in this case.
+
+6. In contrast to getpid() on UNIX, the getpid() in Microsoft C/C++ 1.52
+(AKA 8.0) sometimes returns negative numbers. The DOS Gawk developers felt
+that it was best to use Microsoft's built-in function; but at the same time,
+we are placing this warning here, because this behavior will undoubtably be
+surprising to many.
+
+7. MSC 6 fails the strftlng test. The funstack test exhausts memory
+on the 16bit DOS versions.
+
+8. Eli Zaretskii writes: "Make can crash with SIGFPE after finishing all
+the tests. This happens on Windows 95 only, and Gawk 3.0.3 does that as
+well (as do older versions of Make). The cause for this is the log(-1)
+call in the last test. Based on some limited testing, I'd say that the
+problem is in sloppy Windows handling of the FPU: it doesn't clean up the
+FPU after a program exits, so if Make has SIGFPE unmasked, it crashes."
+
+9. gawk built from the mingw32 and vcWin32 targets continues to have
+problems with pipes; in particular, the pipeio1 test fails.
+
+10. As mentioned above, `|&' only works with cygwin.
+
+
+Gawk thanks
+-----------
+
+The DOS maintainers wish to express their thanks to Eli Zaretskii
+<eliz@is.elta.co.il> for his work and for the many conversations
+concerning gawk, make, and djgpp. His FAQ for djgpp is essential
+reading, and he was always willing to answer our questions (even when
+we didn't read the relevant portions of the FAQ :).
+
+We are indebted to Juan Grigera <juan@biophnet.unlp.edu.ar> for the
+Visual C++ target, and for additional help on changes for Windows32.
+
+
+----
+If you have any problems with the DOS or OS/2 versions of Gawk,
+please send bug reports (along with the version and compiler used) to
+
+ Scott Deifik, scottd@amgen.com (DOS versions)
+or
+ gawk-maintainer@unixos2.org (OS/2 version)
+ Darrel Hankerson, hankedr@mail.auburn.edu
+
+Support for Windows32 started in gawk-3.0.3. Reports on
+the Visual C++ version (vcWin32) may be sent to
+
+ Juan Grigera, juan@biophnet.unlp.edu.ar (Visual C++ version)
+
+with a copy to Scott Deifik. Other Windows32 reports may go to Darrel
+Hankerson.
--- /dev/null
+This is the README for dynamic extension support for GNU awk 3.1.2 under Windows32
+This part of the README is directed to the gawk maintainers.
+
+The implementation consists of
+
+pc/dlfcn.h
+pc/dlfcn.c
+ An implementation of the POSIX dynamic loading functions for Windows32.
+ Bugs and limitations:
+ the RTLD_* flags are ignored
+ passing NULL as the module name is not really supported.
+ dlerror() doesn't always generate useful output.
+
+pc/w32dynamic.patch
+ A patch to pc/Makefile. This adds macros to allow dynamic loading
+ to be compiled in. The macros (DYN_EXP, DYN_OBJ, DYN_FLAGS, and
+ DYN_MAKEXP) are commented-out by default (which is the default on
+ Unix as well). I've added definitions only for MS VC and MinGW.
+ I also added support for pgawk under MS VC and MinGW.
+
+pc/gawkw32.def
+ A list of functions to export from gawk.exe. Every function used
+ in an extension DLL needs to be in this file. I've added the ones
+ required by the provided examples, but some thought should go into
+ determining a useful set of API functions. From a maintenance
+ perspective, it's important that the ordinals (the number following @)
+ never change. You can use an existing DLL with a gawk.exe which has
+ new exported functions, but if you change the ordinal of an existing
+ function, you have to recompile all the extensions that use it.
+
+extension/Makefile.pc
+ A make file which compiles a few of the extension examples.
+ Only readfile, ordchr, and arrayparm are built, since the
+ other functions didn't compile without sizeable modifications.
+
+extension/pcext.def
+ A module definition file which exports dlload.
+
+extension/w32dynamic.patch
+ A patch to readfile.c to have it open files in binary mode. Without
+ this, the bytes read doesn't always match the file size.
+
+w32dynamic.patch
+ A patch to awk.h. This makes the temporary variable _t static and
+ adds an attribute to some data declarations when WIN32_EXTENSION is
+ defined. The issue is that data imported from a separate module has
+ a different level of indirection from the same data in the
+ original module. The difference can be made transparent by adding
+ __declspec(dllimport)) to the declarations used in the importing module.
+ Since _t doesn't actually have to be shared, I've just made it
+ static to the extension module and avoided the problem.
+
+README_d/README.pcdynamic
+ This file.
+
+The remainder of the file is intended for people installing and using gawk
+and probably ought to be added to README.pc
+---
+To compile gawk with dynamic extension support, uncomment the
+definitions of DYN_FLAGS, DYN_EXP, DYN_OBJ, and DYN_MAKEXP in the
+configuration section of Makefile. There are two definitions for
+DYN_MAKEXP -- pick the one that matches your target.
+
+To build some of the example extension libraries, cd to the extension
+directory and copy Makefile.pc to Makefile. You can then build using the same
+two targets. To run the example awk scripts, you'll need to either change the
+call to the `extension' function to match the name of the library (for
+instance, change "./ordchr.so" to "ordchr.dll" or simply "ordchr"), or rename
+the library to match the call (for instance, rename ordchr.dll to ordchr.so).
+
+If you build gawk.exe with one compiler but want to build an extension library
+with the other, you need to copy the import library. Visual C uses a library
+called gawk.lib, while MinGW uses a library called libgawk.a. These files
+are equivalent and will interoperate if you give them the correct name.
+The resulting shared libraries are also interoperable.
+
+To create your own extension library, you can use the examples as models, but
+you're essentially on your own. Post to comp.lang.awk or send e-mail to
+ptjm@interlog.com if you have problems getting started. If you need to access
+functions or variables which are not exported by gawk.exe, add them to
+gawkw32.def and rebuild. You should also add ATTRIBUTE_EXPORTED to the
+declaration in awk.h of any variables you add to gawkw32.def.
+
+Note that extension libraries have the name of the awk executable embedded in
+them at link time, so they will work only with gawk.exe. In particular, they won't
+work if you rename gawk.exe to awk.exe or if you try to use pgawk.exe. You can
+perform profiling by temporarily renaming pgawk.exe to gawk.exe. You can resolve
+this problem by changing the program name in the definition of DYN_MAKEXP for
+your compiler.
+
+On Windows32, libraries are sought first in the current directory, then in the
+directory containing gawk.exe, and finally through the PATH environment
+variable.
--- /dev/null
+Tue Dec 24 22:41:39 EST 1996
+
+SCO's awk has a -e option which is similar to gawk's --source option,
+allowing you to specify the script anywhere on the awk command line.
+
+This can be a problem, since gawk will install itself as `awk' in
+$(bindir). If this is ahead of /bin and /usr/bin in the search path,
+several of SCO's scripts that use -e will break, since gawk does not
+accept this option.
+
+The solution is simple. After doing a `make install', do:
+
+ rm -f /usr/local/bin/awk # or wherever it is installed.
+
+This removes the `awk' symlink so that SCO's programs will continue
+to work.
+
+If you complain to me about this, I will fuss at you for not having
+done your homework.
+
+Arnold Robbins
+arnold@gnu.org
+
+---------------------------
+Date: 14 Oct 1997 12:17 +0000
+From: Leigh Hebblethwaite <LHebblethwaite@transoft.com>
+To: bug-gnu-utils@prep.ai.mit.edu
+To: arnold@gnu.org
+
+I've just built gawk 3.0.3 on my system and have experienced a problem
+with the routine pipeio2.awk in the test suite. However the problem
+appears to be in the tr command rather than gawk.
+
+I'm using SCO Open Server 5. On the version I have there appears to be
+a problem with tr such that:
+
+ tr [0-9]. ...........
+
+does NOT translate 9s. This means that the output from:
+
+ echo " 5 6 7 8 9 10 11" | tr [0-9]. ...........
+
+is:
+
+ . . . . 9 .. ..
+
+This problem causes the pipeio2 test to be reported as a failure.
+
+Note that the following variation on the tr command works fine:
+
+ tr 0123456789. ...........
+
+For your info the details of my system are summarised by the out put
+of the uname -X command, which is:
+
+System = SCO_SV
+Node = sgscos5
+Release = 3.2v5.0.2
+KernelID = 96/01/23
+Machine = Pentium
+BusType = EISA
+Serial = 4EC023443
+Users = 5-user
+OEM# = 0
+Origin# = 1
+NumCPU = 1
+
+
--- /dev/null
+Tue Jan 30 10:51:39 IST 2001
+
+There will be linker warnings on SGI Irix will be building gawk.
+These are related to use of dlopen and the dynamic loading of
+builtins. The warnings can be ignored.
+======================================
+Tue May 2 11:40:54 IDT 2000
+
+GCC and gawk often don't mix on SGI systems. Use the native C compiler to
+compile gawk. `make test' should work ok, although the `tweakfld' test
+may fail. That's ok; see README.ultrix for the details on that one.
+
+Note that the SGI compiler will complain about some constructs in
+regex.c and dfa.c. It's ok to ignore those complaints.
+
+If you ask me about this, I will fuss at you for not having done
+your homework!
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+Solaris Problem #1:
+===================
+From: carson@lehman.com
+Date: Fri, 7 Feb 1997 01:05:58 -0500
+To: arnold@gnu.ai.mit.edu
+Subject: Solaris 2.5.1 x86 bug in gawk-3.0.2
+
+awktab.c has the following bogus logic:
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+
+Solaris x86 obviously dosn't define sparc or __sparc.
+
+What you _meant_ to say was:
+
+if (defined(__sun) && defined(__SVR4))
+
+(which identifies Solaris 2.x under both Sun's cc and gcc)
+
+--
+Carson Gaspar -- carson@cs.columbia.edu carson@lehman.com
+http://www.cs.columbia.edu/~carson/home.html
+<This is the boring business .sig - no outre sayings here>
+
+ * * * * * * *
+
+Solution to Problem #1:
+=======================
+Tue Oct 20 21:25:11 IST 1998
+
+This has been fixed in 3.1.0 with the bisonfix.sed script.
+
+Arnold Robbins
+arnold@gnu.org
+
+Solaris Problem #2:
+===================
+Tue Apr 13 16:57:45 IDT 1999
+
+There is a known problem in that the `manyfiles' test will fail under
+Solaris if you set your soft limit on the number of file descriptors to
+above 256. This is due to a "feature" of fdopen that an fd must be
+less than 256 (see fdopen(3)).
+
+IMHO this is Sun's problem, not mine.
+
+Arnold Robbins
+arnold@gnu.org
+
+Solution (a) to Problem #2:
+===========================
+Now fixed in the code via Paul Eggert's 2001-09-0 patch. See the
+ChangeLog.
+
+Solution (b) to Problem #2:
+===========================
+From: Paul Nevai <nevai@math.ohio-state.edu>
+Subject: Re: gawk-3.0.4
+To: arnold@skeeve.com (Aharon Robbins)
+Date: Tue, 6 Jul 1999 09:09:05 -0400 (EDT)
+
+Dear Aharon:
+
+Toda raba. Why don't you add something like that to README_d/README.solaris
+file:
+
+for the SunOS do in
+
+/bin/sh: ulimit -n 256; ulimit -a; make test
+/bin/tcsh: limit descriptors 256; ulimit -a; make test
+
+otherwise "make test" will fail
+
+Shalom, Paul
+
+Aharon Robbins wrote to Paul Nevai:
+# >From the README_d/README.solaris file:
+#
+# Tue Apr 13 16:57:45 IDT 1999
+#
+# There is a known problem in that the `manyfiles' test will fail under
+# Solaris if you set your soft limit on the number of file descriptors to
+# above 256. This is due to a "feature" of fdopen that an fd must be
+# less than 256 (see fdopen(3)).
+#
+# IMHO this is Sun's problem, not mine.
+#
+# Arnold Robbins
+# arnold@gnu.org
+#
+# Double check your settings with ulimit; I suspect that this is
+# your problem.
+#
+# Thanks,
+#
+# Arnold
+# --
+# Aharon (Arnold) Robbins arnold@skeeve.com [ <<=== NOTE: NEW ADDRESS!! ]
+# P.O. Box 354 Home Phone: +972 8 979-0381 Fax: +1 603 761-6761
+# Nof Ayalon Cell Phone: +972 51 297-545 (See www.efax.com)
+# D.N. Shimshon 99784 Laundry increases exponentially in the
+# ISRAEL number of children. -- Miriam Robbins
+#
+#
+
+
+
+Paul Nevai pali+@osu.edu
+Department of Mathematics nevai@math.ohio-state.edu
+The Ohio State University http://www.math.ohio-state.edu/~nevai/
+231 West Eighteenth Avenue http://www.math.ohio-state.edu/~jat/
+Columbus, Ohio 43210-1174 1-614-292-5310 (Office/Answering Device)
+The United States of America 1-614-292-1479 (Math Dept Fax)
+
+Solaris Problem #3:
+===================
+Sun Feb 9 10:35:51 IST 2003
+
+Certain versions of Sun C give compilation errors under Solaris 5.5, 5.6 and
+possibly later. Here's what I was told:
+
+> We have this version of cc here:
+> cc -V
+> cc: Sun WorkShop 6 update 1 C 5.2 2000/09/11
+>
+> Probably, the others use different combinations of OS and CC.
+> A quick fix was this (we use csh-syntax here):
+>
+> setenv CC "/opt/SUNWspro/bin/cc -Xc"
+> ./configure
+> make check
+
--- /dev/null
+Sun Jan 19 23:13:50 EST 1997
+
+> Machine: SONY NWS-5000 (MIPS r4000)
+> OS : NEWS-OS 4.2.1 (4.3BSD compatible)
+> This OS doesn't have `uname'
+> Tools : gcc-2.7.2.1, bison-1.25, cmp-2.7, bash-2.0
+
+This system has the same problem with the test/tweakfld case that Ultrix MIPS
+has. See the README.ultrix file for details.
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+Sun Jan 7 23:49:46 EST 1996
+
+GCC and Autoconf disagree about the type of the array argument passed
+to getgroups(2). You can thus ignore the warning that gcc will
+generate under SunOS 4.1.x for io.c.
+
+If you send me email about this without having read this file, I will
+fuss at you!
+
+Arnold Robbins
+arnold@gnu.org
+
+Tue Jan 30 07:01:39 EST 1996
+
+The manyfiles test fails under SunOS 4.1.4. There appears to be some
+bug in libc (shared and static) for SunOS 4.1.4. I got a working gawk
+binary by linking in /usr/5lib/libc.a statically.
+
+
+,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,
+ Jim Farrell | phone 610-940-6020 | Platinum technology
+Systems Administrator | vmail 800-526-9096 x7512 | 620 W. Germantown Pike
+ jwf@platinum.com | fax 610-940-6021 | Plymouth Meeting,Pa,19462
+'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'
--- /dev/null
+The Tandem port was done on a Cyclone machine running D20.
+The port is pretty clean and all facilities seem to work except for
+some of the I/O piping stuff which is just too foreign a concept for
+Tandem.
+
+Usage is as for UNIX except that D20 requires all "{" and "}" characters
+to be escaped with "~" on the command line (not in script files) and the
+standard Tandem syntax for "/in filename,out filename/" must be used
+instead of the usual UNIX "<" and ">" for file redirection. (Redirection
+options on getline, print etc are supported.)
+
+The -mr=val option has been "stolen" to enable Tandem users to
+process fixed-length records with no "end-of-line" character. That
+is, -mr=74 tells gawk to read the input file as fixed 74-byte
+records.
+
+To build a Tandem executable from source, down-load all of the files
+so that the file names on the Tandem box are, for example ARRAYC or
+AWKH. That is, make all of the file names conform to the restrictions
+of D20. The "totally Tandem-specific" files are in the tandem
+"subvolume" and should be copied to the main src directory before
+building gawk.
+
+The file compit can then be used to compile and bind an executable.
+Sorry, no make and no autoconfig.
+
+This is my first UNIX port to Tandem so I may well have missed the best
+way of doing things: I just desperately needed a working awk at a
+Tandem shop.
+
+Cheers,
+Stephen Davies
+(scldad@sdc.com.au)
--- /dev/null
+Date: Sat, 22 Apr 2000 06:07:06 -0600 (MDT)
+From: "Nelson H. F. Beebe" <beebe@math.utah.edu>
+To: arnold@gnu.org
+Cc: beebe@math.utah.edu, sysstaff@math.utah.edu, othmer@math.utah.edu
+Subject: gawk-3.0.4 and a GNU/Linux gotcha
+
+Yesterday, I was assisting a colleague install some software on his
+GNU/Linux machine for which uname -r reports 2.2.14.
+
+A (mis)feature of this system, which I've never encountered before,
+broke the build of one of my programs, and also of gawk-3.0.4.
+
+Namely, the kernel will not execute anything that resides in /tmp,
+though it will if the same script is in /usr/tmp!
+
+% cat /tmp/foo.sh
+#! /bin/sh
+echo hello
+
+ls -l /tmp/foo.sh
+-rwxr-xr-x 1 othmer math 22 Apr 21 10:34 /tmp/foo.sh*
+
+% /tmp/foo.sh
+bash: /tmp/foo.sh: Permission denied
+
+% cp /tmp/foo.sh /usr/tmp
+
+% /usr/tmp/foo.sh
+hello
+
+Thus, programs that do a temporary install in /tmp, as some of mine do
+in order to run the validation suite, will fail.
+
+gawk-3.0.4, and likely other gawk versions, hits this problem too. It
+fails because test/poundbang starts with
+
+#! /tmp/gawk -f
+
+I tracked down where it comes from:
+
+% grep /tmp /etc/fstab
+/dev/hda3 /tmp ext2 rw,nosuid,noexec,nouser,auto,async,nodev 1 1
+ !!!!!!
+
+Since this is done via a mount command, potentially ANY directory tree
+could be mounted with noexec.
--- /dev/null
+When compiling on DECstation running Ultrix 4.0 a command 'cc -c -O
+regex.c' is causing an infinite loop in an optimizer. Other sources
+compile fine with -O flag. If you are going to use this flag either
+add a special rule to Makefile for a compilation of regex.c, or issue
+'cc -c regex.c' before hitting 'make'.
+
+From: Steve Simmons <scs@wotan.iti.org>
+Subject: Non-bug report on gawk 2.13.2
+To: david@cs.dal.ca, arnold@skeeve.atl.ga.us
+Date: Thu, 25 Jul 1991 13:45:38 -0300
+
+Just fyi -- it passes tests with flying colors under Ultrix 4.2. The
+README.ultrix file applies more than ever. You might want to add
+these paragraphs to it:
+
+ As of Ultrix 4.2 the optimise works for regex.c, but you must give an
+ additional switch to get everything optimised. Using '-Olimit 1500'
+ does the job. Without the switch gawk will compile and run correctly,
+ but you will get complaints about lost optimisations in builtin.c,
+ awk.tab.c and regex.c.
+
+From: Arnold Robbins <arnold@math.utah.edu>
+Date: Sun Sep 8 07:05:07 EDT 1996
+
+On Decstations using Ultrix 4.3, the tweakfld test case will fail. It
+appears that routines in the math library return very small but non-zero
+numbers in cases where most other systems return zero.
+
+From: Juergen Kahrs <jkahrs@castor.atlas.de>
+Date: Wed Jan 17 13:15:34 MET 2001
+
+On Ultrix 4.3, configure like this:
+
+ ./configure --disable-nls
+
+In custom.h, we defined HAVE_MKTIME in order to avoid a linker error.
+If you compile with
+
+ make check
+
+every test will pass, except for the badargs test:
+
+ *** Error code 1 (ignored)
+
+This shouldnt cause problems.
+
--- /dev/null
+Sat Jan 28 22:07:17 EST 1995
+
+Some older versions of yacc (notably Ultrix's) have limits on the depth
+of the parse stack. This only shows up when gawk is dealing with deeply
+nested control structures, such as those in `awf'.
+
+The problem goes away if you use either bison or Berkeley yacc.
+
+Arnold Robbins
+arnold@gnu.org
--- /dev/null
+# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.9.5])])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# This was merged into AC_PROG_CC in Autoconf.
+
+AU_DEFUN([AM_PROG_CC_STDC],
+[AC_PROG_CC
+AC_DIAGNOSE([obsolete], [$0:
+ your code should no longer depend upon `am_cv_prog_cc_stdc', but upon
+ `ac_cv_prog_cc_stdc'. Remove this warning and the assignment when
+ you adjust the code. You can also remove the above call to
+ AC_PROG_CC if you already called it elsewhere.])
+am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
+])
+AU_DEFUN([fp_PROG_CC_STDC])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 7
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out. Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+AC_DEFUN([AM_C_PROTOTYPES],
+[AC_REQUIRE([AC_C_PROTOTYPES])
+if test "$ac_cv_prog_cc_stdc" != no; then
+ U= ANSI2KNR=
+else
+ U=_ ANSI2KNR=./ansi2knr
+fi
+# Ensure some checks needed by ansi2knr itself.
+AC_REQUIRE([AC_HEADER_STDC])
+AC_CHECK_HEADERS(string.h)
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/arch.m4])
+m4_include([m4/gettext.m4])
+m4_include([m4/iconv.m4])
+m4_include([m4/intmax_t.m4])
+m4_include([m4/inttypes_h.m4])
+m4_include([m4/lib-ld.m4])
+m4_include([m4/lib-link.m4])
+m4_include([m4/lib-prefix.m4])
+m4_include([m4/longlong.m4])
+m4_include([m4/nls.m4])
+m4_include([m4/po.m4])
+m4_include([m4/progtest.m4])
+m4_include([m4/socket.m4])
+m4_include([m4/stdint_h.m4])
+m4_include([m4/strtod.m4])
+m4_include([m4/uintmax_t.m4])
+m4_include([m4/ulonglong.m4])
--- /dev/null
+.TH ANSI2KNR 1 "19 Jan 1996"
+.SH NAME
+ansi2knr \- convert ANSI C to Kernighan & Ritchie C
+.SH SYNOPSIS
+.I ansi2knr
+[--varargs] input_file [output_file]
+.SH DESCRIPTION
+If no output_file is supplied, output goes to stdout.
+.br
+There are no error messages.
+.sp
+.I ansi2knr
+recognizes function definitions by seeing a non-keyword identifier at the left
+margin, followed by a left parenthesis, with a right parenthesis as the last
+character on the line, and with a left brace as the first token on the
+following line (ignoring possible intervening comments). It will recognize a
+multi-line header provided that no intervening line ends with a left or right
+brace or a semicolon. These algorithms ignore whitespace and comments, except
+that the function name must be the first thing on the line.
+.sp
+The following constructs will confuse it:
+.br
+ - Any other construct that starts at the left margin and follows the
+above syntax (such as a macro or function call).
+.br
+ - Some macros that tinker with the syntax of the function header.
+.sp
+The --varargs switch is obsolete, and is recognized only for
+backwards compatibility. The present version of
+.I ansi2knr
+will always attempt to convert a ... argument to va_alist and va_dcl.
+.SH AUTHOR
+L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
+continues to maintain the current version; most of the code in the current
+version is his work. ansi2knr also includes contributions by Francois
+Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
--- /dev/null
+/* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. */
+
+/*$Id: ansi2knr.c,v 1.3 2000/04/13 03:41:48 lpd Exp $*/
+/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
+
+/*
+ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY. No author or distributor accepts responsibility to anyone for the
+consequences of using it or for whether it serves any particular purpose or
+works at all, unless he says so in writing. Refer to the GNU General Public
+License (the "GPL") for full details.
+
+Everyone is granted permission to copy, modify and redistribute ansi2knr,
+but only under the conditions described in the GPL. A copy of this license
+is supposed to have been given to you along with ansi2knr so you can know
+your rights and responsibilities. It should be in a file named COPYLEFT,
+or, if there is no file named COPYLEFT, a file named COPYING. Among other
+things, the copyright notice and this notice must be preserved on all
+copies.
+
+We explicitly state here what we believe is already implied by the GPL: if
+the ansi2knr program is distributed as a separate set of sources and a
+separate executable file which are aggregated on a storage medium together
+with another program, this in itself does not bring the other program under
+the GPL, nor does the mere fact that such a program or the procedures for
+constructing it invoke the ansi2knr executable bring any other part of the
+program under the GPL.
+*/
+
+/*
+ * Usage:
+ ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
+ * --filename provides the file name for the #line directive in the output,
+ * overriding input_file (if present).
+ * If no input_file is supplied, input is read from stdin.
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes function definitions by seeing a non-keyword
+ * identifier at the left margin, followed by a left parenthesis, with a
+ * right parenthesis as the last character on the line, and with a left
+ * brace as the first token on the following line (ignoring possible
+ * intervening comments and/or preprocessor directives), except that a line
+ * consisting of only
+ * identifier1(identifier2)
+ * will not be considered a function definition unless identifier2 is
+ * the word "void", and a line consisting of
+ * identifier1(identifier2, <<arbitrary>>)
+ * will not be considered a function definition.
+ * ansi2knr will recognize a multi-line header provided that no intervening
+ * line ends with a left or right brace or a semicolon. These algorithms
+ * ignore whitespace, comments, and preprocessor directives, except that
+ * the function name must be the first thing on the line. The following
+ * constructs will confuse it:
+ * - Any other construct that starts at the left margin and
+ * follows the above syntax (such as a macro or function call).
+ * - Some macros that tinker with the syntax of function headers.
+ */
+
+/*
+ * The original and principal author of ansi2knr is L. Peter Deutsch
+ * <ghost@aladdin.com>. Other authors are noted in the change history
+ * that follows (in reverse chronological order):
+
+ lpd 2000-04-12 backs out Eggert's changes because of bugs:
+ - concatlits didn't declare the type of its bufend argument;
+ - concatlits didn't recognize when it was inside a comment;
+ - scanstring could scan backward past the beginning of the string; when
+ - the check for \ + newline in scanstring was unnecessary.
+
+ 2000-03-05 Paul Eggert <eggert@twinsun.com>
+
+ Add support for concatenated string literals.
+ * ansi2knr.c (concatlits): New decl.
+ (main): Invoke concatlits to concatenate string literals.
+ (scanstring): Handle backslash-newline correctly. Work with
+ character constants. Fix bug when scanning backwards through
+ backslash-quote. Check for unterminated strings.
+ (convert1): Parse character constants, too.
+ (appendline, concatlits): New functions.
+ * ansi2knr.1: Document this.
+
+ lpd 1999-08-17 added code to allow preprocessor directives
+ wherever comments are allowed
+ lpd 1999-04-12 added minor fixes from Pavel Roskin
+ <pavel_roskin@geocities.com> for clean compilation with
+ gcc -W -Wall
+ lpd 1999-03-22 added hack to recognize lines consisting of
+ identifier1(identifier2, xxx) as *not* being procedures
+ lpd 1999-02-03 made indentation of preprocessor commands consistent
+ lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
+ endless loop; quoted strings within an argument list
+ confused the parser
+ lpd 1999-01-24 added a check for write errors on the output,
+ suggested by Jim Meyering <meyering@ascend.com>
+ lpd 1998-11-09 added further hack to recognize identifier(void)
+ as being a procedure
+ lpd 1998-10-23 added hack to recognize lines consisting of
+ identifier1(identifier2) as *not* being procedures
+ lpd 1997-12-08 made input_file optional; only closes input and/or
+ output file if not stdin or stdout respectively; prints
+ usage message on stderr rather than stdout; adds
+ --filename switch (changes suggested by
+ <ceder@lysator.liu.se>)
+ lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
+ compilers that don't understand void, as suggested by
+ Tom Lane
+ lpd 1996-01-15 changed to require that the first non-comment token
+ on the line following a function header be a left brace,
+ to reduce sensitivity to macros, as suggested by Tom Lane
+ <tgl@sss.pgh.pa.us>
+ lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
+ undefined preprocessor symbols as 0; changed all #ifdefs
+ for configuration symbols to #ifs
+ lpd 1995-04-05 changed copyright notice to make it clear that
+ including ansi2knr in a program does not bring the entire
+ program under the GPL
+ lpd 1994-12-18 added conditionals for systems where ctype macros
+ don't handle 8-bit characters properly, suggested by
+ Francois Pinard <pinard@iro.umontreal.ca>;
+ removed --varargs switch (this is now the default)
+ lpd 1994-10-10 removed CONFIG_BROKETS conditional
+ lpd 1994-07-16 added some conditionals to help GNU `configure',
+ suggested by Francois Pinard <pinard@iro.umontreal.ca>;
+ properly erase prototype args in function parameters,
+ contributed by Jim Avera <jima@netcom.com>;
+ correct error in writeblanks (it shouldn't erase EOLs)
+ lpd 1989-xx-xx original version
+ */
+
+/* Most of the conditionals here are to make ansi2knr work with */
+/* or without the GNU configure machinery. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if HAVE_CONFIG_H
+
+/*
+ For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
+ This will define HAVE_CONFIG_H and so, activate the following lines.
+ */
+
+# if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+#else /* not HAVE_CONFIG_H */
+
+/* Otherwise do it the hard way */
+
+# ifdef BSD
+# include <strings.h>
+# else
+# ifdef VMS
+ extern int strlen(), strncmp();
+# else
+# include <string.h>
+# endif
+# endif
+
+#endif /* not HAVE_CONFIG_H */
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+/*
+ malloc and free should be declared in stdlib.h,
+ but if you've got a K&R compiler, they probably aren't.
+ */
+# ifdef MSDOS
+# include <malloc.h>
+# else
+# ifdef VMS
+ extern char *malloc();
+ extern void free();
+# else
+ extern char *malloc();
+ extern int free();
+# endif
+# endif
+
+#endif
+
+/* Define NULL (for *very* old compilers). */
+#ifndef NULL
+# define NULL (0)
+#endif
+
+/*
+ * The ctype macros don't always handle 8-bit characters correctly.
+ * Compensate for this here.
+ */
+#ifdef isascii
+# undef HAVE_ISASCII /* just in case */
+# define HAVE_ISASCII 1
+#else
+#endif
+#if STDC_HEADERS || !HAVE_ISASCII
+# define is_ascii(c) 1
+#else
+# define is_ascii(c) isascii(c)
+#endif
+
+#define is_space(c) (is_ascii(c) && isspace(c))
+#define is_alpha(c) (is_ascii(c) && isalpha(c))
+#define is_alnum(c) (is_ascii(c) && isalnum(c))
+
+/* Scanning macros */
+#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
+
+/* Forward references */
+char *ppdirforward();
+char *ppdirbackward();
+char *skipspace();
+char *scanstring();
+int writeblanks();
+int test1();
+int convert1();
+
+/* The main program */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{ FILE *in = stdin;
+ FILE *out = stdout;
+ char *filename = 0;
+ char *program_name = argv[0];
+ char *output_name = 0;
+#define bufsize 5000 /* arbitrary size */
+ char *buf;
+ char *line;
+ char *more;
+ char *usage =
+ "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
+ /*
+ * In previous versions, ansi2knr recognized a --varargs switch.
+ * If this switch was supplied, ansi2knr would attempt to convert
+ * a ... argument to va_alist and va_dcl; if this switch was not
+ * supplied, ansi2knr would simply drop any such arguments.
+ * Now, ansi2knr always does this conversion, and we only
+ * check for this switch for backward compatibility.
+ */
+ int convert_varargs = 1;
+ int output_error;
+
+ while ( argc > 1 && argv[1][0] == '-' ) {
+ if ( !strcmp(argv[1], "--varargs") ) {
+ convert_varargs = 1;
+ argc--;
+ argv++;
+ continue;
+ }
+ if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
+ filename = argv[2];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
+ argv[1]);
+ fprintf(stderr, usage);
+ exit(1);
+ }
+ switch ( argc )
+ {
+ default:
+ fprintf(stderr, usage);
+ exit(0);
+ case 3:
+ output_name = argv[2];
+ out = fopen(output_name, "w");
+ if ( out == NULL ) {
+ fprintf(stderr, "%s: Cannot open output file %s\n",
+ program_name, output_name);
+ exit(1);
+ }
+ /* falls through */
+ case 2:
+ in = fopen(argv[1], "r");
+ if ( in == NULL ) {
+ fprintf(stderr, "%s: Cannot open input file %s\n",
+ program_name, argv[1]);
+ exit(1);
+ }
+ if ( filename == 0 )
+ filename = argv[1];
+ /* falls through */
+ case 1:
+ break;
+ }
+ if ( filename )
+ fprintf(out, "#line 1 \"%s\"\n", filename);
+ buf = malloc(bufsize);
+ if ( buf == NULL )
+ {
+ fprintf(stderr, "Unable to allocate read buffer!\n");
+ exit(1);
+ }
+ line = buf;
+ while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+ {
+test: line += strlen(line);
+ switch ( test1(buf) )
+ {
+ case 2: /* a function header */
+ convert1(buf, out, 1, convert_varargs);
+ break;
+ case 1: /* a function */
+ /* Check for a { at the start of the next line. */
+ more = ++line;
+f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
+ goto wl;
+ if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
+ goto wl;
+ switch ( *skipspace(ppdirforward(more), 1) )
+ {
+ case '{':
+ /* Definitely a function header. */
+ convert1(buf, out, 0, convert_varargs);
+ fputs(more, out);
+ break;
+ case 0:
+ /* The next line was blank or a comment: */
+ /* keep scanning for a non-comment. */
+ line += strlen(line);
+ goto f;
+ default:
+ /* buf isn't a function header, but */
+ /* more might be. */
+ fputs(buf, out);
+ strcpy(buf, more);
+ line = buf;
+ goto test;
+ }
+ break;
+ case -1: /* maybe the start of a function */
+ if ( line != buf + (bufsize - 1) ) /* overflow check */
+ continue;
+ /* falls through */
+ default: /* not a function */
+wl: fputs(buf, out);
+ break;
+ }
+ line = buf;
+ }
+ if ( line != buf )
+ fputs(buf, out);
+ free(buf);
+ if ( output_name ) {
+ output_error = ferror(out);
+ output_error |= fclose(out);
+ } else { /* out == stdout */
+ fflush(out);
+ output_error = ferror(out);
+ }
+ if ( output_error ) {
+ fprintf(stderr, "%s: error writing to %s\n", program_name,
+ (output_name ? output_name : "stdout"));
+ exit(1);
+ }
+ if ( in != stdin )
+ fclose(in);
+ return 0;
+}
+
+/*
+ * Skip forward or backward over one or more preprocessor directives.
+ */
+char *
+ppdirforward(p)
+ char *p;
+{
+ for (; *p == '#'; ++p) {
+ for (; *p != '\r' && *p != '\n'; ++p)
+ if (*p == 0)
+ return p;
+ if (*p == '\r' && p[1] == '\n')
+ ++p;
+ }
+ return p;
+}
+char *
+ppdirbackward(p, limit)
+ char *p;
+ char *limit;
+{
+ char *np = p;
+
+ for (;; p = --np) {
+ if (*np == '\n' && np[-1] == '\r')
+ --np;
+ for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
+ if (np[-1] == 0)
+ return np;
+ if (*np != '#')
+ return p;
+ }
+}
+
+/*
+ * Skip over whitespace, comments, and preprocessor directives,
+ * in either direction.
+ */
+char *
+skipspace(p, dir)
+ char *p;
+ int dir; /* 1 for forward, -1 for backward */
+{
+ for ( ; ; ) {
+ while ( is_space(*p) )
+ p += dir;
+ if ( !(*p == '/' && p[dir] == '*') )
+ break;
+ p += dir; p += dir;
+ while ( !(*p == '*' && p[dir] == '/') ) {
+ if ( *p == 0 )
+ return p; /* multi-line comment?? */
+ p += dir;
+ }
+ p += dir; p += dir;
+ }
+ return p;
+}
+
+/* Scan over a quoted string, in either direction. */
+char *
+scanstring(p, dir)
+ char *p;
+ int dir;
+{
+ for (p += dir; ; p += dir)
+ if (*p == '"' && p[-dir] != '\\')
+ return p + dir;
+}
+
+/*
+ * Write blanks over part of a string.
+ * Don't overwrite end-of-line characters.
+ */
+int
+writeblanks(start, end)
+ char *start;
+ char *end;
+{ char *p;
+ for ( p = start; p < end; p++ )
+ if ( *p != '\r' && *p != '\n' )
+ *p = ' ';
+ return 0;
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ * 0 - definitely not a function definition;
+ * 1 - definitely a function definition;
+ * 2 - definitely a function prototype (NOT USED);
+ * -1 - may be the beginning of a function definition,
+ * append another line and look again.
+ * The reason we don't attempt to convert function prototypes is that
+ * Ghostscript's declaration-generating macros look too much like
+ * prototypes, and confuse the algorithms.
+ */
+int
+test1(buf)
+ char *buf;
+{ char *p = buf;
+ char *bend;
+ char *endfn;
+ int contin;
+
+ if ( !isidfirstchar(*p) )
+ return 0; /* no name at left margin */
+ bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
+ switch ( *bend )
+ {
+ case ';': contin = 0 /*2*/; break;
+ case ')': contin = 1; break;
+ case '{': return 0; /* not a function */
+ case '}': return 0; /* not a function */
+ default: contin = -1;
+ }
+ while ( isidchar(*p) )
+ p++;
+ endfn = p;
+ p = skipspace(p, 1);
+ if ( *p++ != '(' )
+ return 0; /* not a function */
+ p = skipspace(p, 1);
+ if ( *p == ')' )
+ return 0; /* no parameters */
+ /* Check that the apparent function name isn't a keyword. */
+ /* We only need to check for keywords that could be followed */
+ /* by a left parenthesis (which, unfortunately, is most of them). */
+ { static char *words[] =
+ { "asm", "auto", "case", "char", "const", "double",
+ "extern", "float", "for", "if", "int", "long",
+ "register", "return", "short", "signed", "sizeof",
+ "static", "switch", "typedef", "unsigned",
+ "void", "volatile", "while", 0
+ };
+ char **key = words;
+ char *kp;
+ unsigned len = endfn - buf;
+
+ while ( (kp = *key) != 0 )
+ { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+ return 0; /* name is a keyword */
+ key++;
+ }
+ }
+ {
+ char *id = p;
+ int len;
+ /*
+ * Check for identifier1(identifier2) and not
+ * identifier1(void), or identifier1(identifier2, xxxx).
+ */
+
+ while ( isidchar(*p) )
+ p++;
+ len = p - id;
+ p = skipspace(p, 1);
+ if (*p == ',' ||
+ (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
+ )
+ return 0; /* not a function */
+ }
+ /*
+ * If the last significant character was a ), we need to count
+ * parentheses, because it might be part of a formal parameter
+ * that is a procedure.
+ */
+ if (contin > 0) {
+ int level = 0;
+
+ for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
+ level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
+ if (level > 0)
+ contin = -1;
+ }
+ return contin;
+}
+
+/* Convert a recognized function definition or header to K&R syntax. */
+int
+convert1(buf, out, header, convert_varargs)
+ char *buf;
+ FILE *out;
+ int header; /* Boolean */
+ int convert_varargs; /* Boolean */
+{ char *endfn;
+ char *p;
+ /*
+ * The breaks table contains pointers to the beginning and end
+ * of each argument.
+ */
+ char **breaks;
+ unsigned num_breaks = 2; /* for testing */
+ char **btop;
+ char **bp;
+ char **ap;
+ char *vararg = 0;
+
+ /* Pre-ANSI implementations don't agree on whether strchr */
+ /* is called strchr or index, so we open-code it here. */
+ for ( endfn = buf; *(endfn++) != '('; )
+ ;
+top: p = endfn;
+ breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+ if ( breaks == NULL )
+ { /* Couldn't allocate break table, give up */
+ fprintf(stderr, "Unable to allocate break table!\n");
+ fputs(buf, out);
+ return -1;
+ }
+ btop = breaks + num_breaks * 2 - 2;
+ bp = breaks;
+ /* Parse the argument list */
+ do
+ { int level = 0;
+ char *lp = NULL;
+ char *rp = NULL;
+ char *end = NULL;
+
+ if ( bp >= btop )
+ { /* Filled up break table. */
+ /* Allocate a bigger one and start over. */
+ free((char *)breaks);
+ num_breaks <<= 1;
+ goto top;
+ }
+ *bp++ = p;
+ /* Find the end of the argument */
+ for ( ; end == NULL; p++ )
+ { switch(*p)
+ {
+ case ',':
+ if ( !level ) end = p;
+ break;
+ case '(':
+ if ( !level ) lp = p;
+ level++;
+ break;
+ case ')':
+ if ( --level < 0 ) end = p;
+ else rp = p;
+ break;
+ case '/':
+ if (p[1] == '*')
+ p = skipspace(p, 1) - 1;
+ break;
+ case '"':
+ p = scanstring(p, 1) - 1;
+ break;
+ default:
+ ;
+ }
+ }
+ /* Erase any embedded prototype parameters. */
+ if ( lp && rp )
+ writeblanks(lp + 1, rp);
+ p--; /* back up over terminator */
+ /* Find the name being declared. */
+ /* This is complicated because of procedure and */
+ /* array modifiers. */
+ for ( ; ; )
+ { p = skipspace(p - 1, -1);
+ switch ( *p )
+ {
+ case ']': /* skip array dimension(s) */
+ case ')': /* skip procedure args OR name */
+ { int level = 1;
+ while ( level )
+ switch ( *--p )
+ {
+ case ']': case ')':
+ level++;
+ break;
+ case '[': case '(':
+ level--;
+ break;
+ case '/':
+ if (p > buf && p[-1] == '*')
+ p = skipspace(p, -1) + 1;
+ break;
+ case '"':
+ p = scanstring(p, -1) + 1;
+ break;
+ default: ;
+ }
+ }
+ if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+ { /* We found the name being declared */
+ while ( !isidfirstchar(*p) )
+ p = skipspace(p, 1) + 1;
+ goto found;
+ }
+ break;
+ default:
+ goto found;
+ }
+ }
+found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+ { if ( convert_varargs )
+ { *bp++ = "va_alist";
+ vararg = p-2;
+ }
+ else
+ { p++;
+ if ( bp == breaks + 1 ) /* sole argument */
+ writeblanks(breaks[0], p);
+ else
+ writeblanks(bp[-1] - 1, p);
+ bp--;
+ }
+ }
+ else
+ { while ( isidchar(*p) ) p--;
+ *bp++ = p+1;
+ }
+ p = end;
+ }
+ while ( *p++ == ',' );
+ *bp = p;
+ /* Make a special check for 'void' arglist */
+ if ( bp == breaks+2 )
+ { p = skipspace(breaks[0], 1);
+ if ( !strncmp(p, "void", 4) )
+ { p = skipspace(p+4, 1);
+ if ( p == breaks[2] - 1 )
+ { bp = breaks; /* yup, pretend arglist is empty */
+ writeblanks(breaks[0], p + 1);
+ }
+ }
+ }
+ /* Put out the function name and left parenthesis. */
+ p = buf;
+ while ( p != endfn ) putc(*p, out), p++;
+ /* Put out the declaration. */
+ if ( header )
+ { fputs(");", out);
+ for ( p = breaks[0]; *p; p++ )
+ if ( *p == '\r' || *p == '\n' )
+ putc(*p, out);
+ }
+ else
+ { for ( ap = breaks+1; ap < bp; ap += 2 )
+ { p = *ap;
+ while ( isidchar(*p) )
+ putc(*p, out), p++;
+ if ( ap < bp - 1 )
+ fputs(", ", out);
+ }
+ fputs(") ", out);
+ /* Put out the argument declarations */
+ for ( ap = breaks+2; ap <= bp; ap += 2 )
+ (*ap)[-1] = ';';
+ if ( vararg != 0 )
+ { *vararg = 0;
+ fputs(breaks[0], out); /* any prior args */
+ fputs("va_dcl", out); /* the final arg */
+ fputs(bp[0], out);
+ }
+ else
+ fputs(breaks[0], out);
+ }
+ free((char *)breaks);
+ return 0;
+}
--- /dev/null
+/*
+ * array.c - routines for associative arrays.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Tree walks (``for (iggy in foo)'') and array deletions use expensive
+ * linear searching. So what we do is start out with small arrays and
+ * grow them as needed, so that our arrays are hopefully small enough,
+ * most of the time, that they're pretty full and we're not looking at
+ * wasted space.
+ *
+ * The decision is made to grow the array if the average chain length is
+ * ``too big''. This is defined as the total number of entries in the table
+ * divided by the size of the array being greater than some constant.
+ *
+ * 11/2002: We make the constant a variable, so that it can be tweaked
+ * via environment variable.
+ */
+
+static int AVG_CHAIN_MAX = 2; /* 11/2002: Modern machines are bigger, cut this down from 10. */
+
+#include "awk.h"
+
+static NODE *assoc_find P((NODE *symbol, NODE *subs, unsigned long hash1));
+static void grow_table P((NODE *symbol));
+
+static unsigned long gst_hash_string P((const char *str, size_t len, unsigned long hsize));
+static unsigned long scramble P((unsigned long x));
+static unsigned long awk_hash P((const char *s, size_t len, unsigned long hsize));
+
+unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize)) = awk_hash;
+
+/* array_init --- possibly temporary function for experimentation purposes */
+
+void
+array_init()
+{
+ const char *val;
+ int newval;
+
+ if ((val = getenv("AVG_CHAIN_MAX")) != NULL && ISDIGIT(*val)) {
+ for (newval = 0; *val && ISDIGIT(*val); val++)
+ newval = (newval * 10) + *val - '0';
+
+ AVG_CHAIN_MAX = newval;
+ }
+
+ if ((val = getenv("AWK_HASH")) != NULL && strcmp(val, "gst") == 0)
+ hash = gst_hash_string;
+}
+
+/*
+ * get_actual --- proceed to the actual Node_var_array,
+ * change Node_var_new to an array.
+ * If canfatal and type isn't good, die fatally,
+ * otherwise return the final actual value.
+ */
+
+NODE *
+get_actual(NODE *symbol, int canfatal)
+{
+ int isparam = (symbol->type == Node_param_list
+ && (symbol->flags & FUNC) == 0);
+ NODE *save_symbol = symbol;
+
+ if (isparam) {
+ save_symbol = symbol = stack_ptr[symbol->param_cnt];
+ if (symbol->type == Node_array_ref)
+ symbol = symbol->orig_array;
+ }
+
+ switch (symbol->type) {
+ case Node_var_new:
+ symbol->type = Node_var_array;
+ symbol->var_array = NULL;
+ /* fall through */
+ case Node_var_array:
+ break;
+
+ case Node_array_ref:
+ case Node_param_list:
+ if ((symbol->flags & FUNC) == 0)
+ cant_happen();
+ /* else
+ fall through */
+
+ default:
+ /* notably Node_var but catches also e.g. FS[1] = "x" */
+ if (canfatal) {
+ if ((symbol->flags & FUNC) != 0)
+ fatal(_("attempt to use function `%s' as an array"),
+ save_symbol->vname);
+ else if (isparam)
+ fatal(_("attempt to use scalar parameter `%s' as an array"),
+ save_symbol->vname);
+ else
+ fatal(_("attempt to use scalar `%s' as array"),
+ save_symbol->vname);
+ } else
+ break;
+ }
+
+ return symbol;
+}
+
+/*
+ * array_vname --- print the name of the array
+ *
+ * Returns a pointer to a statically maintained dynamically allocated string.
+ * It's appropriate for printing the name once; if the caller wants
+ * to save it, they have to make a copy.
+ *
+ * Setting MAX_LEN to a positive value (eg. 140) would limit the length
+ * of the output to _roughly_ that length.
+ *
+ * If MAX_LEN == 0, which is the default, the whole stack is printed.
+ */
+#define MAX_LEN 0
+
+char *
+array_vname(register const NODE *symbol)
+{
+ if (symbol->type == Node_param_list)
+ symbol = stack_ptr[symbol->param_cnt];
+
+ if (symbol->type != Node_array_ref || symbol->orig_array->type != Node_var_array)
+ return symbol->vname;
+ else {
+ static char *message = NULL;
+ static size_t msglen = 0;
+ char *s;
+ size_t len;
+ int n;
+ const NODE *save_symbol = symbol;
+ const char *from = _("from %s");
+
+#if (MAX_LEN <= 0) || !defined(HAVE_SNPRINTF)
+ /* This is the default branch. */
+
+ /* First, we have to compute the length of the string: */
+ len = strlen(symbol->vname) + 2; /* "%s (" */
+ n = 0;
+ do {
+ symbol = symbol->prev_array;
+ len += strlen(symbol->vname);
+ n++;
+ } while (symbol->type == Node_array_ref);
+ /*
+ * Each node contributes by strlen(from) minus the length
+ * of "%s" in the translation (which is at least 2)
+ * plus 2 for ", " or ")\0"; this adds up to strlen(from).
+ */
+ len += n * strlen(from);
+
+ /* (Re)allocate memory: */
+ if (message == NULL) {
+ emalloc(message, char *, len, "array_vname");
+ msglen = len;
+ } else if (len > msglen) {
+ erealloc(message, char *, len, "array_vname");
+ msglen = len;
+ } /* else
+ current buffer can hold new name */
+
+ /* We're ready to print: */
+ symbol = save_symbol;
+ s = message;
+ /*
+ * Ancient systems have sprintf() returning char *, not int.
+ * Thus, `s += sprintf(s, from, name);' is a no-no.
+ */
+ sprintf(s, "%s (", symbol->vname);
+ s += strlen(s);
+ for (;;) {
+ symbol = symbol->prev_array;
+ sprintf(s, from, symbol->vname);
+ s += strlen(s);
+ if (symbol->type != Node_array_ref)
+ break;
+ sprintf(s, ", ");
+ s += strlen(s);
+ }
+ sprintf(s, ")");
+
+#else /* MAX_LEN > 0 */
+
+ /*
+ * The following check fails only on
+ * abnormally_long_variable_name.
+ */
+#define PRINT_CHECK \
+ if (n <= 0 || n >= len) \
+ return save_symbol->vname; \
+ s += n; len -= n
+#define PRINT(str) \
+ n = snprintf(s, len, str); \
+ PRINT_CHECK
+#define PRINT_vname(str) \
+ n = snprintf(s, len, str, symbol->vname); \
+ PRINT_CHECK
+
+ if (message == NULL)
+ emalloc(message, char *, MAX_LEN, "array_vname");
+
+ s = message;
+ len = MAX_LEN;
+
+ /* First, print the vname of the node. */
+ PRINT_vname("%s (");
+
+ for (;;) {
+ symbol = symbol->prev_array;
+ /*
+ * When we don't have enough space and this is not
+ * the last node, shorten the list.
+ */
+ if (len < 40 && symbol->type == Node_array_ref) {
+ PRINT("..., ");
+ symbol = symbol->orig_array;
+ }
+ PRINT_vname(from);
+ if (symbol->type != Node_array_ref)
+ break;
+ PRINT(", ");
+ }
+ PRINT(")");
+
+#undef PRINT_CHECK
+#undef PRINT
+#undef PRINT_vname
+#endif /* MAX_LEN <= 0 */
+
+ return message;
+ }
+}
+#undef MAX_LEN
+
+/* concat_exp --- concatenate expression list into a single string */
+
+NODE *
+concat_exp(register NODE *tree)
+{
+ register NODE *r;
+ char *str;
+ char *s;
+ size_t len;
+ int offset;
+ size_t subseplen;
+ const char *subsep;
+
+ if (tree->type != Node_expression_list)
+ return force_string(tree_eval(tree));
+ r = force_string(tree_eval(tree->lnode));
+ if (tree->rnode == NULL)
+ return r;
+ subseplen = SUBSEP_node->var_value->stlen;
+ subsep = SUBSEP_node->var_value->stptr;
+ len = r->stlen + subseplen + 2;
+ emalloc(str, char *, len, "concat_exp");
+ memcpy(str, r->stptr, r->stlen+1);
+ s = str + r->stlen;
+ free_temp(r);
+ for (tree = tree->rnode; tree != NULL; tree = tree->rnode) {
+ if (subseplen == 1)
+ *s++ = *subsep;
+ else {
+ memcpy(s, subsep, subseplen+1);
+ s += subseplen;
+ }
+ r = force_string(tree_eval(tree->lnode));
+ len += r->stlen + subseplen;
+ offset = s - str;
+ erealloc(str, char *, len, "concat_exp");
+ s = str + offset;
+ memcpy(s, r->stptr, r->stlen+1);
+ s += r->stlen;
+ free_temp(r);
+ }
+ r = make_str_node(str, s - str, ALREADY_MALLOCED);
+ r->flags |= TEMP;
+ return r;
+}
+
+/* assoc_clear --- flush all the values in symbol[] before doing a split() */
+
+void
+assoc_clear(NODE *symbol)
+{
+ long i;
+ NODE *bucket, *next;
+
+ if (symbol->var_array == NULL)
+ return;
+ for (i = 0; i < symbol->array_size; i++) {
+ for (bucket = symbol->var_array[i]; bucket != NULL; bucket = next) {
+ next = bucket->ahnext;
+ unref(bucket->ahvalue);
+ unref(bucket); /* unref() will free the ahname_str */
+ }
+ symbol->var_array[i] = NULL;
+ }
+ free(symbol->var_array);
+ symbol->var_array = NULL;
+ symbol->array_size = symbol->table_size = 0;
+ symbol->flags &= ~ARRAYMAXED;
+}
+
+/* hash --- calculate the hash function of the string in subs */
+
+static unsigned long
+awk_hash(register const char *s, register size_t len, unsigned long hsize)
+{
+ register unsigned long h = 0;
+
+ /*
+ * This is INCREDIBLY ugly, but fast. We break the string up into
+ * 8 byte units. On the first time through the loop we get the
+ * "leftover bytes" (strlen % 8). On every other iteration, we
+ * perform 8 HASHC's so we handle all 8 bytes. Essentially, this
+ * saves us 7 cmp & branch instructions. If this routine is
+ * heavily used enough, it's worth the ugly coding.
+ *
+ * OZ's original sdbm hash, copied from Margo Seltzers db package.
+ */
+
+ /*
+ * Even more speed:
+ * #define HASHC h = *s++ + 65599 * h
+ * Because 65599 = pow(2, 6) + pow(2, 16) - 1 we multiply by shifts
+ */
+#define HASHC htmp = (h << 6); \
+ h = *s++ + htmp + (htmp << 10) - h
+
+ unsigned long htmp;
+
+ h = 0;
+
+#if defined(VAXC)
+ /*
+ * This was an implementation of "Duff's Device", but it has been
+ * redone, separating the switch for extra iterations from the
+ * loop. This is necessary because the DEC VAX-C compiler is
+ * STOOPID.
+ */
+ switch (len & (8 - 1)) {
+ case 7: HASHC;
+ case 6: HASHC;
+ case 5: HASHC;
+ case 4: HASHC;
+ case 3: HASHC;
+ case 2: HASHC;
+ case 1: HASHC;
+ default: break;
+ }
+
+ if (len > (8 - 1)) {
+ register size_t loop = len >> 3;
+ do {
+ HASHC;
+ HASHC;
+ HASHC;
+ HASHC;
+ HASHC;
+ HASHC;
+ HASHC;
+ HASHC;
+ } while (--loop);
+ }
+#else /* ! VAXC */
+ /* "Duff's Device" for those who can handle it */
+ if (len > 0) {
+ register size_t loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do { /* All fall throughs */
+ HASHC;
+ case 7: HASHC;
+ case 6: HASHC;
+ case 5: HASHC;
+ case 4: HASHC;
+ case 3: HASHC;
+ case 2: HASHC;
+ case 1: HASHC;
+ } while (--loop);
+ }
+ }
+#endif /* ! VAXC */
+
+ if (h >= hsize)
+ h %= hsize;
+ return h;
+}
+
+/* assoc_find --- locate symbol[subs] */
+
+static NODE * /* NULL if not found */
+assoc_find(NODE *symbol, register NODE *subs, unsigned long hash1)
+{
+ register NODE *bucket;
+ const char *s1_str;
+ size_t s1_len;
+ NODE *s2;
+
+ for (bucket = symbol->var_array[hash1]; bucket != NULL;
+ bucket = bucket->ahnext) {
+ /*
+ * This used to use cmp_nodes() here. That's wrong.
+ * Array indexes are strings; compare as such, always!
+ */
+ s1_str = bucket->ahname_str;
+ s1_len = bucket->ahname_len;
+ s2 = subs;
+
+ if (s1_len == s2->stlen) {
+ if (s1_len == 0 /* "" is a valid index */
+ || memcmp(s1_str, s2->stptr, s1_len) == 0)
+ return bucket;
+ }
+ }
+ return NULL;
+}
+
+/* in_array --- test whether the array element symbol[subs] exists or not,
+ * return pointer to value if it does.
+ */
+
+NODE *
+in_array(NODE *symbol, NODE *subs)
+{
+ register unsigned long hash1;
+ NODE *ret;
+
+ symbol = get_array(symbol);
+
+ /*
+ * Evaluate subscript first, it could have side effects.
+ */
+ subs = concat_exp(subs); /* concat_exp returns a string node */
+ if (symbol->var_array == NULL) {
+ free_temp(subs);
+ return NULL;
+ }
+ hash1 = hash(subs->stptr, subs->stlen, (unsigned long) symbol->array_size);
+ ret = assoc_find(symbol, subs, hash1);
+ free_temp(subs);
+ if (ret)
+ return ret->ahvalue;
+ else
+ return NULL;
+}
+
+/*
+ * assoc_lookup:
+ * Find SYMBOL[SUBS] in the assoc array. Install it with value "" if it
+ * isn't there. Returns a pointer ala get_lhs to where its value is stored.
+ *
+ * SYMBOL is the address of the node (or other pointer) being dereferenced.
+ * SUBS is a number or string used as the subscript.
+ */
+
+NODE **
+assoc_lookup(NODE *symbol, NODE *subs, int reference)
+{
+ register unsigned long hash1;
+ register NODE *bucket;
+
+ assert(symbol->type == Node_var_array);
+
+ (void) force_string(subs);
+
+ if (symbol->var_array == NULL) {
+ symbol->array_size = symbol->table_size = 0; /* sanity */
+ symbol->flags &= ~ARRAYMAXED;
+ grow_table(symbol);
+ hash1 = hash(subs->stptr, subs->stlen,
+ (unsigned long) symbol->array_size);
+ } else {
+ hash1 = hash(subs->stptr, subs->stlen,
+ (unsigned long) symbol->array_size);
+ bucket = assoc_find(symbol, subs, hash1);
+ if (bucket != NULL) {
+ free_temp(subs);
+ return &(bucket->ahvalue);
+ }
+ }
+
+ if (do_lint && reference) {
+ subs->stptr[subs->stlen] = '\0';
+ lintwarn(_("reference to uninitialized element `%s[\"%s\"]'"),
+ array_vname(symbol), subs->stptr);
+ }
+
+ /* It's not there, install it. */
+ if (do_lint && subs->stlen == 0)
+ lintwarn(_("subscript of array `%s' is null string"),
+ array_vname(symbol));
+
+ /* first see if we would need to grow the array, before installing */
+ symbol->table_size++;
+ if ((symbol->flags & ARRAYMAXED) == 0
+ && (symbol->table_size / symbol->array_size) > AVG_CHAIN_MAX) {
+ grow_table(symbol);
+ /* have to recompute hash value for new size */
+ hash1 = hash(subs->stptr, subs->stlen,
+ (unsigned long) symbol->array_size);
+ }
+
+ getnode(bucket);
+ bucket->type = Node_ahash;
+
+ /*
+ * Freeze this string value --- it must never
+ * change, no matter what happens to the value
+ * that created it or to CONVFMT, etc.
+ *
+ * One day: Use an atom table to track array indices,
+ * and avoid the extra memory overhead.
+ */
+ bucket->flags |= MALLOC;
+ bucket->ahname_ref = 1;
+
+ /* For TEMP node, reuse the storage directly */
+ if ((subs->flags & TEMP) != 0) {
+ bucket->ahname_str = subs->stptr;
+ bucket->ahname_len = subs->stlen;
+ bucket->ahname_str[bucket->ahname_len] = '\0';
+ subs->flags &= ~TEMP; /* for good measure */
+ freenode(subs);
+ } else {
+ emalloc(bucket->ahname_str, char *, subs->stlen + 2, "assoc_lookup");
+ bucket->ahname_len = subs->stlen;
+ memcpy(bucket->ahname_str, subs->stptr, subs->stlen);
+ bucket->ahname_str[bucket->ahname_len] = '\0';
+ }
+
+ bucket->ahvalue = Nnull_string;
+ bucket->ahnext = symbol->var_array[hash1];
+ symbol->var_array[hash1] = bucket;
+ return &(bucket->ahvalue);
+}
+
+/* do_delete --- perform `delete array[s]' */
+
+/*
+ * `symbol' is array
+ * `tree' is subscript
+ */
+
+void
+do_delete(NODE *sym, NODE *tree)
+{
+ register unsigned long hash1;
+ register NODE *bucket, *last;
+ NODE *subs;
+ register NODE *symbol = get_array(sym);
+
+ if (tree == NULL) { /* delete array */
+ assoc_clear(symbol);
+ return;
+ }
+
+ last = NULL; /* shut up gcc -Wall */
+ hash1 = 0; /* ditto */
+
+ /*
+ * Always evaluate subscript, it could have side effects.
+ */
+ subs = concat_exp(tree); /* concat_exp returns string node */
+
+ if (symbol->var_array != NULL) {
+ hash1 = hash(subs->stptr, subs->stlen,
+ (unsigned long) symbol->array_size);
+ last = NULL;
+ for (bucket = symbol->var_array[hash1]; bucket != NULL;
+ last = bucket, bucket = bucket->ahnext) {
+ /*
+ * This used to use cmp_nodes() here. That's wrong.
+ * Array indexes are strings; compare as such, always!
+ */
+ const char *s1_str;
+ size_t s1_len;
+ NODE *s2;
+
+ s1_str = bucket->ahname_str;
+ s1_len = bucket->ahname_len;
+ s2 = subs;
+
+ if (s1_len == s2->stlen) {
+ if (s1_len == 0 /* "" is a valid index */
+ || memcmp(s1_str, s2->stptr, s1_len) == 0)
+ break;
+ }
+ }
+ } else
+ bucket = NULL; /* The array is empty. */
+
+ if (bucket == NULL) {
+ if (do_lint)
+ lintwarn(_("delete: index `%s' not in array `%s'"),
+ subs->stptr, array_vname(sym));
+ free_temp(subs);
+ return;
+ }
+
+ free_temp(subs);
+
+ if (last != NULL)
+ last->ahnext = bucket->ahnext;
+ else
+ symbol->var_array[hash1] = bucket->ahnext;
+ unref(bucket->ahvalue);
+ unref(bucket); /* unref() will free the ahname_str */
+ symbol->table_size--;
+ if (symbol->table_size <= 0) {
+ memset(symbol->var_array, '\0',
+ sizeof(NODE *) * symbol->array_size);
+ symbol->table_size = symbol->array_size = 0;
+ symbol->flags &= ~ARRAYMAXED;
+ free((char *) symbol->var_array);
+ symbol->var_array = NULL;
+ }
+}
+
+/* do_delete_loop --- simulate ``for (iggy in foo) delete foo[iggy]'' */
+
+/*
+ * The primary hassle here is that `iggy' needs to have some arbitrary
+ * array index put in it before we can clear the array, we can't
+ * just replace the loop with `delete foo'.
+ */
+
+void
+do_delete_loop(NODE *symbol, NODE *tree)
+{
+ long i;
+ NODE **lhs;
+ Func_ptr after_assign = NULL;
+
+ symbol = get_array(symbol);
+
+ if (symbol->var_array == NULL)
+ return;
+
+ /* get first index value */
+ for (i = 0; i < symbol->array_size; i++) {
+ if (symbol->var_array[i] != NULL) {
+ lhs = get_lhs(tree->lnode, & after_assign, FALSE);
+ unref(*lhs);
+ *lhs = make_string(symbol->var_array[i]->ahname_str,
+ symbol->var_array[i]->ahname_len);
+ if (after_assign)
+ (*after_assign)();
+ break;
+ }
+ }
+
+ /* blast the array in one shot */
+ assoc_clear(symbol);
+}
+
+/* grow_table --- grow a hash table */
+
+static void
+grow_table(NODE *symbol)
+{
+ NODE **old, **new, *chain, *next;
+ int i, j;
+ unsigned long hash1;
+ unsigned long oldsize, newsize, k;
+ /*
+ * This is an array of primes. We grow the table by an order of
+ * magnitude each time (not just doubling) so that growing is a
+ * rare operation. We expect, on average, that it won't happen
+ * more than twice. The final size is also chosen to be small
+ * enough so that MS-DOG mallocs can handle it. When things are
+ * very large (> 8K), we just double more or less, instead of
+ * just jumping from 8K to 64K.
+ */
+ static const long sizes[] = { 13, 127, 1021, 8191, 16381, 32749, 65497,
+#if ! defined(MSDOS) && ! defined(OS2) && ! defined(atarist)
+ 131101, 262147, 524309, 1048583, 2097169,
+ 4194319, 8388617, 16777259, 33554467,
+ 67108879, 134217757, 268435459, 536870923,
+ 1073741827
+#endif
+ };
+
+ /* find next biggest hash size */
+ newsize = oldsize = symbol->array_size;
+ for (i = 0, j = sizeof(sizes)/sizeof(sizes[0]); i < j; i++) {
+ if (oldsize < sizes[i]) {
+ newsize = sizes[i];
+ break;
+ }
+ }
+
+ if (newsize == oldsize) { /* table already at max (!) */
+ symbol->flags |= ARRAYMAXED;
+ return;
+ }
+
+ /* allocate new table */
+ emalloc(new, NODE **, newsize * sizeof(NODE *), "grow_table");
+ memset(new, '\0', newsize * sizeof(NODE *));
+
+ /* brand new hash table, set things up and return */
+ if (symbol->var_array == NULL) {
+ symbol->table_size = 0;
+ goto done;
+ }
+
+ /* old hash table there, move stuff to new, free old */
+ old = symbol->var_array;
+ for (k = 0; k < oldsize; k++) {
+ if (old[k] == NULL)
+ continue;
+
+ for (chain = old[k]; chain != NULL; chain = next) {
+ next = chain->ahnext;
+ hash1 = hash(chain->ahname_str,
+ chain->ahname_len, newsize);
+
+ /* remove from old list, add to new */
+ chain->ahnext = new[hash1];
+ new[hash1] = chain;
+ }
+ }
+ free(old);
+
+done:
+ /*
+ * note that symbol->table_size does not change if an old array,
+ * and is explicitly set to 0 if a new one.
+ */
+ symbol->var_array = new;
+ symbol->array_size = newsize;
+}
+
+/* set_SUBSEP --- make sure SUBSEP always has a string value */
+
+void
+set_SUBSEP(void)
+{
+
+ (void) force_string(SUBSEP_node->var_value);
+ return;
+}
+
+/* pr_node --- print simple node info */
+
+static void
+pr_node(NODE *n)
+{
+ if ((n->flags & (NUMCUR|NUMBER)) != 0)
+ printf("%g", n->numbr);
+ else
+ printf("%.*s", (int) n->stlen, n->stptr);
+}
+
+/* assoc_dump --- dump the contents of an array */
+
+NODE *
+assoc_dump(NODE *symbol)
+{
+ long i;
+ NODE *bucket;
+
+ if (symbol->var_array == NULL) {
+ printf(_("%s: empty (null)\n"), symbol->vname);
+ return tmp_number((AWKNUM) 0);
+ }
+
+ if (symbol->table_size == 0) {
+ printf(_("%s: empty (zero)\n"), symbol->vname);
+ return tmp_number((AWKNUM) 0);
+ }
+
+ printf(_("%s: table_size = %d, array_size = %d\n"), symbol->vname,
+ (int) symbol->table_size, (int) symbol->array_size);
+
+ for (i = 0; i < symbol->array_size; i++) {
+ for (bucket = symbol->var_array[i]; bucket != NULL;
+ bucket = bucket->ahnext) {
+ printf("%s: I: [len %d <%.*s>] V: [",
+ symbol->vname,
+ (int) bucket->ahname_len,
+ (int) bucket->ahname_len,
+ bucket->ahname_str);
+ pr_node(bucket->ahvalue);
+ printf("]\n");
+ }
+ }
+
+ return tmp_number((AWKNUM) 0);
+}
+
+/* do_adump --- dump an array: interface to assoc_dump */
+
+NODE *
+do_adump(NODE *tree)
+{
+ NODE *r, *a;
+
+ a = tree->lnode;
+
+ if (a->type == Node_param_list) {
+ printf(_("%s: is parameter\n"), a->vname);
+ a = stack_ptr[a->param_cnt];
+ }
+
+ if (a->type == Node_array_ref) {
+ printf(_("%s: array_ref to %s\n"), a->vname,
+ a->orig_array->vname);
+ a = a->orig_array;
+ }
+
+ r = assoc_dump(a);
+
+ return r;
+}
+
+/*
+ * The following functions implement the builtin
+ * asort function. Initial work by Alan J. Broder,
+ * ajb@woti.com.
+ */
+
+/* dup_table --- duplicate input symbol table "symbol" */
+
+static void
+dup_table(NODE *symbol, NODE *newsymb)
+{
+ NODE **old, **new, *chain, *bucket;
+ long i;
+ unsigned long cursize;
+
+ /* find the current hash size */
+ cursize = symbol->array_size;
+
+ new = NULL;
+
+ /* input is a brand new hash table, so there's nothing to copy */
+ if (symbol->var_array == NULL)
+ newsymb->table_size = 0;
+ else {
+ /* old hash table there, dupnode stuff into a new table */
+
+ /* allocate new table */
+ emalloc(new, NODE **, cursize * sizeof(NODE *), "dup_table");
+ memset(new, '\0', cursize * sizeof(NODE *));
+
+ /* do the copying/dupnode'ing */
+ old = symbol->var_array;
+ for (i = 0; i < cursize; i++) {
+ if (old[i] != NULL) {
+ for (chain = old[i]; chain != NULL;
+ chain = chain->ahnext) {
+ /* get a node for the linked list */
+ getnode(bucket);
+ bucket->type = Node_ahash;
+ bucket->flags |= MALLOC;
+ bucket->ahname_ref = 1;
+
+ /*
+ * copy the corresponding name and
+ * value from the original input list
+ */
+ emalloc(bucket->ahname_str, char *, chain->ahname_len + 2, "dup_table");
+ bucket->ahname_len = chain->ahname_len;
+
+ memcpy(bucket->ahname_str, chain->ahname_str, chain->ahname_len);
+ bucket->ahname_str[bucket->ahname_len] = '\0';
+
+ bucket->ahvalue = dupnode(chain->ahvalue);
+
+ /*
+ * put the node on the corresponding
+ * linked list in the new table
+ */
+ bucket->ahnext = new[i];
+ new[i] = bucket;
+ }
+ }
+ }
+ newsymb->table_size = symbol->table_size;
+ }
+
+ newsymb->var_array = new;
+ newsymb->array_size = cursize;
+}
+
+/* merge --- do a merge of two sorted lists */
+
+static NODE *
+merge(NODE *left, NODE *right)
+{
+ NODE *ans, *cur;
+
+ /*
+ * The use of cmp_nodes() here means that IGNORECASE influences the
+ * comparison. This is OK, but it may be surprising. This comment
+ * serves to remind us that we know about this and that it's OK.
+ */
+ if (cmp_nodes(left->ahvalue, right->ahvalue) <= 0) {
+ ans = cur = left;
+ left = left->ahnext;
+ } else {
+ ans = cur = right;
+ right = right->ahnext;
+ }
+
+ while (left != NULL && right != NULL) {
+ if (cmp_nodes(left->ahvalue, right->ahvalue) <= 0) {
+ cur->ahnext = left;
+ cur = left;
+ left = left->ahnext;
+ } else {
+ cur->ahnext = right;
+ cur = right;
+ right = right->ahnext;
+ }
+ }
+
+ cur->ahnext = (left != NULL ? left : right);
+
+ return ans;
+}
+
+/* merge_sort --- recursively sort the left and right sides of a list */
+
+static NODE *
+merge_sort(NODE *left, unsigned long size)
+{
+ NODE *right, *tmp;
+ int i, half;
+
+ if (size <= 1)
+ return left;
+
+ /* walk down the list, till just one before the midpoint */
+ tmp = left;
+ half = size / 2;
+ for (i = 0; i < half-1; i++)
+ tmp = tmp->ahnext;
+
+ /* split the list into two parts */
+ right = tmp->ahnext;
+ tmp->ahnext = NULL;
+
+ /* sort the left and right parts of the list */
+ left = merge_sort(left, half);
+ right = merge_sort(right, size-half);
+
+ /* merge the two sorted parts of the list */
+ return merge(left, right);
+}
+
+
+/*
+ * assoc_from_list -- Populate an array with the contents of a list of NODEs,
+ * using increasing integers as the key.
+ */
+
+static void
+assoc_from_list(NODE *symbol, NODE *list)
+{
+ NODE *next;
+ unsigned long i = 0;
+ register unsigned long hash1;
+ char buf[100];
+
+ for (; list != NULL; list = next) {
+ next = list->ahnext;
+
+ /* make an int out of i++ */
+ i++;
+ sprintf(buf, "%lu", i);
+ assert(list->ahname_str == NULL);
+ assert(list->ahname_ref == 1);
+ emalloc(list->ahname_str, char *, strlen(buf) + 2, "assoc_from_list");
+ list->ahname_len = strlen(buf);
+ strcpy(list->ahname_str, buf);
+
+ /* find the bucket where it belongs */
+ hash1 = hash(list->ahname_str, list->ahname_len,
+ symbol->array_size);
+
+ /* link the node into the chain at that bucket */
+ list->ahnext = symbol->var_array[hash1];
+ symbol->var_array[hash1] = list;
+ }
+}
+
+/*
+ * assoc_sort_inplace --- sort all the values in symbol[], replacing
+ * the sorted values back into symbol[], indexed by integers starting with 1.
+ */
+
+typedef enum asort_how { VALUE, INDEX } ASORT_TYPE;
+
+static NODE *
+assoc_sort_inplace(NODE *symbol, ASORT_TYPE how)
+{
+ unsigned long i, num;
+ NODE *bucket, *next, *list;
+
+ if (symbol->var_array == NULL
+ || symbol->array_size <= 0
+ || symbol->table_size <= 0)
+ return tmp_number((AWKNUM) 0);
+
+ /* build a linked list out of all the entries in the table */
+ if (how == VALUE) {
+ list = NULL;
+ num = 0;
+ for (i = 0; i < symbol->array_size; i++) {
+ for (bucket = symbol->var_array[i]; bucket != NULL; bucket = next) {
+ next = bucket->ahnext;
+ if (bucket->ahname_ref == 1) {
+ free(bucket->ahname_str);
+ bucket->ahname_str = NULL;
+ bucket->ahname_len = 0;
+ } else {
+ NODE *r;
+
+ getnode(r);
+ *r = *bucket;
+ unref(bucket);
+ bucket = r;
+ bucket->flags |= MALLOC;
+ bucket->ahname_ref = 1;
+ bucket->ahname_str = NULL;
+ bucket->ahname_len = 0;
+ }
+ bucket->ahnext = list;
+ list = bucket;
+ num++;
+ }
+ symbol->var_array[i] = NULL;
+ }
+ } else { /* how == INDEX */
+ list = NULL;
+ num = 0;
+ for (i = 0; i < symbol->array_size; i++) {
+ for (bucket = symbol->var_array[i]; bucket != NULL; bucket = next) {
+ next = bucket->ahnext;
+
+ /* toss old value */
+ unref(bucket->ahvalue);
+
+ /* move index into value */
+ if (bucket->ahname_ref == 1) {
+ bucket->ahvalue = make_str_node(bucket->ahname_str,
+ bucket->ahname_len, ALREADY_MALLOCED);
+ bucket->ahname_str = NULL;
+ bucket->ahname_len = 0;
+ } else {
+ NODE *r;
+
+ bucket->ahvalue = make_string(bucket->ahname_str, bucket->ahname_len);
+ getnode(r);
+ *r = *bucket;
+ unref(bucket);
+ bucket = r;
+ bucket->flags |= MALLOC;
+ bucket->ahname_ref = 1;
+ bucket->ahname_str = NULL;
+ bucket->ahname_len = 0;
+ }
+
+ bucket->ahnext = list;
+ list = bucket;
+ num++;
+ }
+ symbol->var_array[i] = NULL;
+ }
+ }
+
+ /*
+ * Sort the linked list of NODEs.
+ * (The especially nice thing about using a merge sort here is that
+ * we require absolutely no additional storage. This is handy if the
+ * array has grown to be very large.)
+ */
+ list = merge_sort(list, num);
+
+ /*
+ * now repopulate the original array, using increasing
+ * integers as the key
+ */
+ assoc_from_list(symbol, list);
+
+ return tmp_number((AWKNUM) num);
+}
+
+/* asort_actual --- do the actual work to sort the input array */
+
+static NODE *
+asort_actual(NODE *tree, ASORT_TYPE how)
+{
+ NODE *array = get_array(tree->lnode);
+
+ if (tree->rnode != NULL) { /* 2nd optional arg */
+ NODE *dest = get_array(tree->rnode->lnode);
+
+ assoc_clear(dest);
+ dup_table(array, dest);
+ array = dest;
+ }
+
+ return assoc_sort_inplace(array, how);
+}
+
+/* do_asort --- sort array by value */
+
+NODE *
+do_asort(NODE *tree)
+{
+ return asort_actual(tree, VALUE);
+}
+
+/* do_asorti --- sort array by index */
+
+NODE *
+do_asorti(NODE *tree)
+{
+ return asort_actual(tree, INDEX);
+}
+
+/*
+From bonzini@gnu.org Mon Oct 28 16:05:26 2002
+Date: Mon, 28 Oct 2002 13:33:03 +0100
+From: Paolo Bonzini <bonzini@gnu.org>
+To: arnold@skeeve.com
+Subject: Hash function
+Message-ID: <20021028123303.GA6832@biancaneve>
+
+Here is the hash function I'm using in GNU Smalltalk. The scrambling is
+needed if you use powers of two as the table sizes. If you use primes it
+is not needed.
+
+To use double-hashing with power-of-two size, you should use the
+_gst_hash_string(str, len) as the primary hash and
+scramble(_gst_hash_string (str, len)) | 1 as the secondary hash.
+
+Paolo
+
+*/
+/*
+ * ADR: Slightly modified to work w/in the context of gawk.
+ */
+
+static unsigned long
+gst_hash_string(const char *str, size_t len, unsigned long hsize)
+{
+ unsigned long hashVal = 1497032417; /* arbitrary value */
+ unsigned long ret;
+
+ while (len--) {
+ hashVal += *str++;
+ hashVal += (hashVal << 10);
+ hashVal ^= (hashVal >> 6);
+ }
+
+ ret = scramble(hashVal);
+ if (ret >= hsize)
+ ret %= hsize;
+
+ return ret;
+}
+
+static unsigned long
+scramble(unsigned long x)
+{
+ if (sizeof(long) == 4) {
+ int y = ~x;
+
+ x += (y << 10) | (y >> 22);
+ x += (x << 6) | (x >> 26);
+ x -= (x << 16) | (x >> 16);
+ } else {
+ x ^= (~x) >> 31;
+ x += (x << 21) | (x >> 11);
+ x += (x << 5) | (x >> 27);
+ x += (x << 27) | (x >> 5);
+ x += (x << 31);
+ }
+
+ return x;
+}
--- /dev/null
+/*
+ * awk.h -- Definitions for gawk.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* ------------------------------ Includes ------------------------------ */
+
+/*
+ * config.h absolutely, positively, *M*U*S*T* be included before
+ * any system headers. Otherwise, extreme death, destruction
+ * and loss of life results.
+ *
+ * Well, OK, gawk just won't work on systems using egcs and LFS. But
+ * that's almost as bad.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1 /* enable GNU extensions */
+#endif /* _GNU_SOURCE */
+
+#include <stdio.h>
+#include <assert.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif /* HAVE_LIMITS_H */
+#include <ctype.h>
+#include <setjmp.h>
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0)
+#ifndef LOCALEDIR
+#define LOCALEDIR NULL
+#endif /* LOCALEDIR */
+#endif
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
+extern int errno;
+#endif
+#ifdef HAVE_SIGNUM_H
+#include <signum.h>
+#endif
+
+#ifndef NO_MBSUPPORT
+#include "mbsupport.h" /* defines MBS_SUPPORT */
+#endif
+
+#if defined(MBS_SUPPORT)
+/* We can handle multibyte strings. */
+#include <wchar.h>
+#include <wctype.h>
+#endif
+
+#ifdef STDC_HEADERS
+#include <float.h>
+#endif
+
+/* ----------------- System dependencies (with more includes) -----------*/
+
+/* This section is the messiest one in the file, not a lot that can be done */
+
+/* First, get the ctype stuff right; from Jim Meyering */
+#if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
+#define IN_CTYPE_DOMAIN(c) 1
+#else
+#define IN_CTYPE_DOMAIN(c) isascii((unsigned char) c)
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (IN_CTYPE_DOMAIN(c) && isblank((unsigned char) c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isgraph((unsigned char) c))
+#else
+#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isprint((unsigned char) c) && !isspace((unsigned char) c))
+#endif
+
+#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char) c))
+#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char) c))
+#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char) c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char) c))
+#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char) c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char) c))
+#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (unsigned char) (c))
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char) c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char) c))
+#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char) c))
+
+#ifndef TOUPPER
+#define TOUPPER(c) toupper((unsigned char) c)
+#endif
+#ifndef TOLOWER
+#define TOLOWER(c) tolower((unsigned char) c)
+#endif
+
+#ifdef __STDC__
+#define P(s) s
+#define MALLOC_ARG_T size_t
+#else /* not __STDC__ */
+#define P(s) ()
+#define MALLOC_ARG_T unsigned
+#define volatile
+#endif /* not __STDC__ */
+
+#ifndef VMS
+#include <sys/types.h>
+#include <sys/stat.h>
+#else /* VMS */
+#include <stddef.h>
+#include <stat.h>
+#include <file.h> /* avoid <fcntl.h> in io.c */
+#endif /* VMS */
+
+#if ! defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else /* not STDC_HEADERS */
+#include "protos.h"
+#endif /* not STDC_HEADERS */
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif /* NEED_MEMORY_H */
+#else /* not HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#endif /* not HAVE_STRING_H */
+
+#ifdef NeXT
+#if __GNUC__ < 2 || __GNUC_MINOR__ < 7
+#include <libc.h>
+#endif
+#undef atof
+#define getopt GNU_getopt
+#define GFMT_WORKAROUND
+#endif /* NeXT */
+
+#if defined(atarist) || defined(VMS)
+#include <unixlib.h>
+#endif /* atarist || VMS */
+
+#if ! defined(MSDOS) && ! defined(OS2) && ! defined(WIN32) && ! defined(__EMX__) && ! defined(__CYGWIN__) && ! defined(O_BINARY) /*duh*/
+#define O_BINARY 0
+#endif
+
+#if defined(TANDEM)
+#define variable variabl
+#define open(name, how, mode) open(name, how) /* !!! ANSI C !!! */
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifndef HAVE_VPRINTF
+/* if you don't have vprintf, try this and cross your fingers. */
+#ifdef HAVE_DOPRNT
+#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
+#else /* not HAVE_DOPRNT */
+you
+lose
+#endif /* not HAVE_DOPRNT */
+#endif /* HAVE_VPRINTF */
+
+#ifndef HAVE_SETLOCALE
+#define setlocale(locale, val) /* nothing */
+#endif /* HAVE_SETLOCALE */
+
+/* use this as lintwarn("...")
+ this is a hack but it gives us the right semantics */
+#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
+
+#ifdef VMS
+#include "vms/redirect.h"
+#endif /*VMS*/
+
+#ifdef atarist
+#include "unsupported/atari/redirect.h"
+#endif
+
+#define GNU_REGEX
+#ifdef GNU_REGEX
+#include "regex.h"
+#include "dfa.h"
+typedef struct Regexp {
+ struct re_pattern_buffer pat;
+ struct re_registers regs;
+ struct dfa dfareg;
+ short dfa;
+ short has_anchor; /* speed up of avoid_dfa kludge, temporary */
+} Regexp;
+#define RESTART(rp,s) (rp)->regs.start[0]
+#define REEND(rp,s) (rp)->regs.end[0]
+#define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
+#define SUBPATEND(rp,s,n) (rp)->regs.end[n]
+#define NUMSUBPATS(rp,s) (rp)->regs.num_regs
+#endif /* GNU_REGEX */
+/* regexp matching flags: */
+#define RE_NEED_START 1 /* need to know start/end of match */
+#define RE_NO_BOL 2 /* for RS, not allowed to match ^ in regexp */
+
+/* Stuff for losing systems. */
+#ifdef STRTOD_NOT_C89
+extern double gawk_strtod();
+#define strtod gawk_strtod
+#endif
+
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __attribute__(x)
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+
+#ifndef ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+#endif /* ATTRIBUTE_NORETURN */
+
+#ifndef ATTRIBUTE_PRINTF
+#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
+#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
+#endif /* ATTRIBUTE_PRINTF */
+
+/* We use __extension__ in some places to suppress -pedantic warnings
+ about GCC extensions. This feature didn't work properly before
+ gcc 2.8. */
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __extension__
+#endif
+
+/* this is defined by Windows32 extension libraries. It must be added to
+ * every variable which is exported (including function pointers) */
+#if defined(WIN32_EXTENSION) && !defined(ATTRIBUTE_EXPORTED)
+# define ATTRIBUTE_EXPORTED __declspec(dllimport)
+#else
+# define ATTRIBUTE_EXPORTED
+#endif
+
+
+/* ------------------ Constants, Structures, Typedefs ------------------ */
+
+#if 0
+/* This isn't right. Figure it out the right way for the next release */
+#ifndef AWKNUM
+#ifdef LDBL_MANT_DIG
+#define AWKNUM long double
+#else
+#endif
+#endif
+#endif
+
+#define AWKNUM double
+
+#ifndef TRUE
+/* a bit hackneyed, but what the heck */
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#define LINT_INVALID 1 /* only warn about invalid */
+#define LINT_ALL 2 /* warn about all things */
+
+/* Figure out what '\a' really is. */
+#ifdef __STDC__
+#define BELL '\a' /* sure makes life easy, don't it? */
+#else
+# if 'z' - 'a' == 25 /* ascii */
+# if 'a' != 97 /* machine is dumb enough to use mark parity */
+# define BELL '\207'
+# else
+# define BELL '\07'
+# endif
+# else
+# define BELL '\057'
+# endif
+#endif
+
+typedef enum nodevals {
+ /* illegal entry == 0 */
+ Node_illegal,
+
+ /* binary operators lnode and rnode are the expressions to work on */
+ Node_times,
+ Node_quotient,
+ Node_mod,
+ Node_plus,
+ Node_minus,
+ Node_cond_pair, /* conditional pair (see Node_line_range) */
+ Node_subscript,
+ Node_concat,
+ Node_exp,
+
+ /* unary operators subnode is the expression to work on */
+ Node_preincrement,
+ Node_predecrement,
+ Node_postincrement,
+ Node_postdecrement,
+ Node_unary_minus,
+ Node_field_spec,
+
+ /* assignments lnode is the var to assign to, rnode is the exp */
+ Node_assign,
+ Node_assign_times,
+ Node_assign_quotient,
+ Node_assign_mod,
+ Node_assign_plus,
+ Node_assign_minus,
+ Node_assign_exp,
+ Node_assign_concat,
+
+ /* boolean binaries lnode and rnode are expressions */
+ Node_and,
+ Node_or,
+
+ /* binary relationals compares lnode and rnode */
+ Node_equal,
+ Node_notequal,
+ Node_less,
+ Node_greater,
+ Node_leq,
+ Node_geq,
+ Node_match,
+ Node_nomatch,
+
+ /* unary relationals works on subnode */
+ Node_not,
+
+ /* program structures */
+ Node_rule_list, /* lnode is a rule, rnode is rest of list */
+ Node_rule_node, /* lnode is pattern, rnode is statement */
+ Node_statement_list, /* lnode is statement, rnode is more list */
+ Node_switch_body, /* lnode is the case list, rnode is default list */
+ Node_case_list, /* lnode is the case, rnode is a statement list */
+ Node_if_branches, /* lnode is to run on true, rnode on false */
+ Node_expression_list, /* lnode is an exp, rnode is more list */
+ Node_param_list, /* lnode is a variable, rnode is more list */
+
+ /* keywords */
+ Node_K_if, /* lnode is conditonal, rnode is if_branches */
+ Node_K_switch, /* lnode is switch value, rnode is body of case statements */
+ Node_K_case, /* lnode is case value, rnode is stuff to run */
+ Node_K_default, /* lnode is empty, rnode is stuff to run */
+ Node_K_while, /* lnode is condtional, rnode is stuff to run */
+ Node_K_for, /* lnode is for_struct, rnode is stuff to run */
+ Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
+ Node_K_break, /* no subs */
+ Node_K_continue, /* no subs */
+ Node_K_print, /* lnode is exp_list, rnode is redirect */
+ Node_K_print_rec, /* lnode is NULL, rnode is redirect */
+ Node_K_printf, /* lnode is exp_list, rnode is redirect */
+ Node_K_next, /* no subs */
+ Node_K_exit, /* subnode is return value, or NULL */
+ Node_K_do, /* lnode is conditional, rnode stuff to run */
+ Node_K_return, /* lnode is return value */
+ Node_K_delete, /* lnode is array, rnode is subscript */
+ Node_K_delete_loop, /* lnode is array, rnode is subscript */
+ Node_K_getline, /* lnode is opt var, rnode is redirection */
+ Node_K_function, /* lnode is statement list, rnode is params */
+ Node_K_nextfile, /* no subs */
+
+ /* I/O redirection for print statements */
+ Node_redirect_output, /* subnode is where to redirect */
+ Node_redirect_append, /* subnode is where to redirect */
+ Node_redirect_pipe, /* subnode is where to redirect */
+ Node_redirect_pipein, /* subnode is where to redirect */
+ Node_redirect_input, /* subnode is where to redirect */
+ Node_redirect_twoway, /* subnode is where to redirect */
+
+ /* Variables */
+ Node_var_new, /* newly created variable, may become an array */
+ Node_var, /* scalar variable, lnode is value */
+ Node_var_array, /* array is ptr to elements, table_size num of eles */
+ Node_val, /* node is a value - type in flags */
+
+ /* Builtins subnode is explist to work on, builtin is func to call */
+ Node_builtin,
+
+ /*
+ * pattern: conditional ',' conditional ; lnode of Node_line_range
+ * is the two conditionals (Node_cond_pair), other word (rnode place)
+ * is a flag indicating whether or not this range has been entered.
+ */
+ Node_line_range,
+
+ /*
+ * boolean test of membership in array
+ * lnode is string-valued, expression rnode is array name
+ */
+ Node_in_array,
+
+ Node_func, /* lnode is param. list, rnode is body */
+ Node_func_call, /* lnode is name, rnode is argument list */
+
+ Node_cond_exp, /* lnode is conditonal, rnode is if_branches */
+ Node_regex, /* a regexp, text, compiled, flags, etc */
+ Node_dynregex, /* a dynamic regexp */
+ Node_hashnode, /* an identifier in the symbol table */
+ Node_ahash, /* an array element */
+ Node_array_ref, /* array passed by ref as parameter */
+
+ Node_BINMODE, /* variables recognized in the grammar */
+ Node_CONVFMT,
+ Node_FIELDWIDTHS,
+ Node_FNR,
+ Node_FS,
+ Node_IGNORECASE,
+ Node_LINT,
+ Node_NF,
+ Node_NR,
+ Node_OFMT,
+ Node_OFS,
+ Node_ORS,
+ Node_RS,
+ Node_TEXTDOMAIN,
+ Node_SUBSEP,
+ Node_final /* sentry value, not legal */
+} NODETYPE;
+
+/*
+ * NOTE - this struct is a rather kludgey -- it is packed to minimize
+ * space usage, at the expense of cleanliness. Alter at own risk.
+ */
+typedef struct exp_node {
+ union {
+ struct {
+ union {
+ struct exp_node *lptr;
+ char *param_name;
+ long ll;
+ } l;
+ union {
+ struct exp_node *rptr;
+ struct exp_node *(*pptr) P((struct exp_node *));
+ Regexp *preg;
+ struct for_loop_header *hd;
+ struct exp_node **av;
+ int r_ent; /* range entered */
+ } r;
+ union {
+ struct exp_node *extra;
+ long xl;
+ char **param_list;
+ } x;
+ char *name;
+ short number;
+ unsigned long reflags;
+# define CASE 1
+# define CONST 2
+# define FS_DFLT 4
+ } nodep;
+ struct {
+ AWKNUM fltnum; /* this is here for optimal packing of
+ * the structure on many machines
+ */
+ char *sp;
+ size_t slen;
+ long sref;
+ int idx;
+#ifdef MBS_SUPPORT
+ wchar_t *wsp;
+ size_t wslen;
+#endif
+ } val;
+ struct {
+ struct exp_node *next;
+ char *name;
+ size_t length;
+ struct exp_node *value;
+ long ref;
+ } hash;
+#define hnext sub.hash.next
+#define hname sub.hash.name
+#define hlength sub.hash.length
+#define hvalue sub.hash.value
+
+#define ahnext sub.hash.next
+#define ahname_str sub.hash.name
+#define ahname_len sub.hash.length
+#define ahvalue sub.hash.value
+#define ahname_ref sub.hash.ref
+ } sub;
+ NODETYPE type;
+ unsigned short flags;
+# define MALLOC 1 /* can be free'd */
+# define TEMP 2 /* should be free'd */
+# define PERM 4 /* can't be free'd */
+# define STRING 8 /* assigned as string */
+# define STRCUR 16 /* string value is current */
+# define NUMCUR 32 /* numeric value is current */
+# define NUMBER 64 /* assigned as number */
+# define MAYBE_NUM 128 /* user input: if NUMERIC then
+ * a NUMBER */
+# define ARRAYMAXED 256 /* array is at max size */
+# define FUNC 512 /* this parameter is really a
+ * function name; see awkgram.y */
+# define FIELD 1024 /* this is a field */
+# define INTLSTR 2048 /* use localized version */
+#ifdef MBS_SUPPORT
+# define WSTRCUR 4096 /* wide str value is current */
+#endif
+} NODE;
+
+#define vname sub.nodep.name
+#define exec_count sub.nodep.reflags
+
+#define lnode sub.nodep.l.lptr
+#define nextp sub.nodep.l.lptr
+#define rnode sub.nodep.r.rptr
+#define source_file sub.nodep.name
+#define source_line sub.nodep.number
+#define param_cnt sub.nodep.number
+#define param sub.nodep.l.param_name
+#define parmlist sub.nodep.x.param_list
+
+#define subnode lnode
+#define builtin sub.nodep.r.pptr
+#define callresult sub.nodep.x.extra
+#define funcbody sub.nodep.x.extra
+
+#define re_reg sub.nodep.r.preg
+#define re_flags sub.nodep.reflags
+#define re_text lnode
+#define re_exp sub.nodep.x.extra
+#define re_cnt sub.nodep.number
+
+#define forloop rnode->sub.nodep.r.hd
+
+#define stptr sub.val.sp
+#define stlen sub.val.slen
+#define stref sub.val.sref
+#define stfmt sub.val.idx
+
+#define wstptr sub.val.wsp
+#define wstlen sub.val.wslen
+
+#define numbr sub.val.fltnum
+
+/* Node_var: */
+#define var_value lnode
+
+/* Node_var_array: */
+#define var_array sub.nodep.r.av
+#define array_size sub.nodep.l.ll
+#define table_size sub.nodep.x.xl
+
+/* Node_array_ref: */
+#define orig_array sub.nodep.x.extra
+#define prev_array rnode
+
+#define printf_count sub.nodep.x.xl
+
+#define condpair lnode
+#define triggered sub.nodep.r.r_ent
+
+/* a regular for loop */
+typedef struct for_loop_header {
+ NODE *init;
+ NODE *cond;
+ NODE *incr;
+} FOR_LOOP_HEADER;
+
+typedef struct iobuf {
+ const char *name; /* filename */
+ int fd; /* file descriptor */
+ struct stat sbuf; /* stat buf */
+ char *buf; /* start data buffer */
+ char *off; /* start of current record in buffer */
+ char *dataend; /* first byte in buffer to hold new data,
+ NULL if not read yet */
+ char *end; /* end of buffer */
+ size_t readsize; /* set from fstat call */
+ size_t size; /* buffer size */
+ ssize_t count; /* amount read last time */
+ size_t scanoff; /* where we were in the buffer when we had
+ to regrow/refill */
+
+ void *opaque; /* private data for open hooks */
+ int (*get_record) P((char **out, struct iobuf *, int *errcode));
+ void (*close_func) P((struct iobuf *)); /* open and close hooks */
+
+ int flag;
+# define IOP_IS_TTY 1
+# define IOP_IS_INTERNAL 2
+# define IOP_NO_FREE 4
+# define IOP_NOFREE_OBJ 8
+# define IOP_AT_EOF 16
+# define IOP_CLOSED 32
+# define IOP_AT_START 64
+} IOBUF;
+
+typedef void (*Func_ptr) P((void));
+
+/* structure used to dynamically maintain a linked-list of open files/pipes */
+struct redirect {
+ unsigned int flag;
+# define RED_FILE 1
+# define RED_PIPE 2
+# define RED_READ 4
+# define RED_WRITE 8
+# define RED_APPEND 16
+# define RED_NOBUF 32
+# define RED_USED 64 /* closed temporarily to reuse fd */
+# define RED_EOF 128
+# define RED_TWOWAY 256
+# define RED_PTY 512
+# define RED_SOCKET 1024
+# define RED_TCP 2048
+ char *value;
+ FILE *fp;
+ FILE *ifp; /* input fp, needed for PIPES_SIMULATED */
+ IOBUF *iop;
+ int pid;
+ int status;
+ struct redirect *prev;
+ struct redirect *next;
+ const char *mode;
+};
+
+/*
+ * structure for our source, either a command line string or a source file.
+ * the same structure is used to remember variable pre-assignments.
+ */
+struct src {
+ enum srctype { CMDLINE = 1, SOURCEFILE,
+ PRE_ASSIGN, PRE_ASSIGN_FS } stype;
+ char *val;
+};
+
+/* for debugging purposes */
+struct flagtab {
+ int val;
+ const char *name;
+};
+
+/* longjmp return codes, must be nonzero */
+/* Continue means either for loop/while continue, or next input record */
+#define TAG_CONTINUE 1
+/* Break means either for/while break, or stop reading input */
+#define TAG_BREAK 2
+/* Return means return from a function call; leave value in ret_node */
+#define TAG_RETURN 3
+
+#ifndef LONG_MAX
+#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
+#endif
+#ifndef ULONG_MAX
+#define ULONG_MAX (~(unsigned long)0)
+#endif
+#ifndef LONG_MIN
+#define LONG_MIN ((long)(-LONG_MAX - 1L))
+#endif
+#define UNLIMITED LONG_MAX
+
+/* -------------------------- External variables -------------------------- */
+/* gawk builtin variables */
+extern long NF;
+extern long NR;
+extern long FNR;
+extern int BINMODE;
+extern int IGNORECASE;
+extern int RS_is_null;
+extern char *OFS;
+extern int OFSlen;
+extern char *ORS;
+extern int ORSlen;
+extern char *OFMT;
+extern char *CONVFMT;
+ATTRIBUTE_EXPORTED extern int CONVFMTidx;
+extern int OFMTidx;
+extern char *TEXTDOMAIN;
+extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
+extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
+extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
+extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
+extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node;
+ATTRIBUTE_EXPORTED extern NODE **stack_ptr;
+extern NODE *Nnull_string;
+extern NODE *Null_field;
+extern NODE **fields_arr;
+extern int sourceline;
+extern char *source;
+extern NODE *expression_value;
+
+#if __GNUC__ < 2
+# if defined(WIN32_EXTENSION)
+static
+# else
+extern
+#endif
+NODE *_t; /* used as temporary in tree_eval */
+#endif
+
+extern NODE *nextfree;
+extern int field0_valid;
+extern int do_traditional;
+extern int do_posix;
+extern int do_intervals;
+extern int do_intl;
+extern int do_non_decimal_data;
+extern int do_dump_vars;
+extern int do_tidy_mem;
+extern int in_begin_rule;
+extern int in_end_rule;
+extern int whiny_users;
+#ifdef NO_LINT
+#define do_lint 0
+#define do_lint_old 0
+#else
+ATTRIBUTE_EXPORTED extern int do_lint;
+extern int do_lint_old;
+#endif
+#ifdef MBS_SUPPORT
+extern int gawk_mb_cur_max;
+#else
+extern const int gawk_mb_cur_max;
+#endif
+
+#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
+extern GETGROUPS_T *groupset;
+extern int ngroups;
+#endif
+
+#ifdef HAVE_LOCALE_H
+extern struct lconv loc;
+#endif /* HAVE_LOCALE_H */
+
+extern const char *myname;
+
+extern char quote;
+extern char *defpath;
+extern char envsep;
+
+extern char casetable[]; /* for case-independent regexp matching */
+
+/* ------------------------- Pseudo-functions ------------------------- */
+
+#define is_identchar(c) (isalnum(c) || (c) == '_')
+
+#define var_uninitialized(n) ((n)->var_value == Nnull_string)
+
+#ifdef MPROF
+#define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), (n)->flags = 0, (n)-exec_count = 0;
+#define freenode(n) free(n)
+#else /* not MPROF */
+#define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
+ else n = more_nodes()
+#ifndef NO_PROFILING
+#define freenode(n) ((n)->flags = 0,\
+ (n)->exec_count = 0, (n)->nextp = nextfree, nextfree = (n))
+#else /* not PROFILING */
+#define freenode(n) ((n)->flags = 0,\
+ (n)->nextp = nextfree, nextfree = (n))
+#endif /* not PROFILING */
+#endif /* not MPROF */
+
+#ifndef GAWKDEBUG
+#define DUPNODE_MACRO 1
+/*
+ * Speed up the path leading to r_dupnode, as well as duplicating TEMP nodes,
+ * on expense of slowing down the access to PERM nodes (by two instructions).
+ * This is right since PERM nodes are realtively rare.
+ *
+ * The code also sets MALLOC flag for PERM nodes, which should not matter.
+ */
+#define DUPNODE_COMMON (_t->flags & (TEMP|PERM)) != 0 ? \
+ (_t->flags &= ~TEMP, _t->flags |= MALLOC, _t) : \
+ r_dupnode(_t)
+#if __GNUC__ >= 2
+#define dupnode(n) ({NODE * _t = (n); DUPNODE_COMMON;})
+#else
+#define dupnode(n) (_t = (n), DUPNODE_COMMON)
+#endif
+#else /* GAWKDEBUG */
+#define dupnode(n) r_dupnode(n)
+#endif /* GAWKDEBUG */
+
+#define get_array(t) get_actual(t, TRUE) /* allowed to die fatally */
+#define get_param(t) get_actual(t, FALSE) /* not allowed */
+
+#ifdef MEMDEBUG
+#undef freenode
+#define get_lhs(p, a, r) r_get_lhs((p), (a), (r))
+#define m_tree_eval(t, iscond) r_tree_eval(t, iscond)
+#else
+#define get_lhs(p, a, r) ((p)->type == Node_var && \
+ ! var_uninitialized(p) ? \
+ (&(p)->var_value) : \
+ r_get_lhs((p), (a), (r)))
+#define TREE_EVAL_MACRO 1
+#if __GNUC__ >= 2
+#define m_tree_eval(t, iscond) __extension__ \
+ ({NODE * _t = (t); \
+ if (_t == (NODE*)NULL) \
+ cant_happen(); \
+ switch(_t->type) { \
+ case Node_val: \
+ if (_t->flags&INTLSTR) \
+ _t = r_force_string(_t); \
+ break; \
+ case Node_var: \
+ if (! var_uninitialized(_t)) { \
+ _t = _t->var_value; \
+ break; \
+ } \
+ /*FALLTHROUGH*/ \
+ default: \
+ _t = r_tree_eval(_t, iscond);\
+ break; \
+ } \
+ _t;})
+#else
+#define m_tree_eval(t, iscond) (_t = (t), _t == (NODE*)NULL ? (cant_happen(), (NODE*)NULL) : \
+ (_t->type == Node_param_list ? \
+ r_tree_eval(_t, iscond) : \
+ ((_t->type == Node_val && (_t->flags&INTLSTR)) ? \
+ r_force_string(_t) : \
+ (_t->type == Node_val ? _t : \
+ (_t->type == Node_var && \
+ ! var_uninitialized(_t) ? _t->var_value : \
+ r_tree_eval(_t, iscond))))))
+#endif /* __GNUC__ */
+#endif /* not MEMDEBUG */
+#define tree_eval(t) m_tree_eval(t, FALSE)
+
+#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
+#define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUMCUR|NUMBER))
+
+#define free_temp(n) do { NODE *_n = (n); if (_n->flags&TEMP) unref(_n);} \
+ while (FALSE)
+
+#define make_string(s, l) make_str_node((s), (size_t) (l), 0)
+#define SCAN 1
+#define ALREADY_MALLOCED 2
+
+#define cant_happen() r_fatal("internal error line %d, file: %s", \
+ __LINE__, __FILE__)
+
+/*
+ * For SunOS 4.1.x which is pre-Standard C, `realloc' doesn't
+ * accept NULL. Sigh. The check must be done for both cases,
+ * since could be using GCC but with stock C library. Sigh, again.
+ */
+#ifdef HAVE_STRINGIZE
+#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
+ (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
+ (str), #var, (long) (x), strerror(errno)),0))
+#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
+ ? (ty)malloc((MALLOC_ARG_T)(x)) \
+ : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
+ ||\
+ (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
+ (str), #var, (long) (x), strerror(errno)),0))
+#else /* HAVE_STRINGIZE */
+#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
+ (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
+ (str), "var", (long) (x), strerror(errno)),0))
+#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
+ ? (ty)malloc((MALLOC_ARG_T)(x)) \
+ : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
+ ||\
+ (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
+ (str), "var", (long) (x), strerror(errno)),0))
+#endif /* HAVE_STRINGIZE */
+
+#ifdef GAWKDEBUG
+#define force_number r_force_number
+#define force_string r_force_string
+#else /* not GAWKDEBUG */
+#ifdef lint
+extern AWKNUM force_number();
+#endif
+#if __GNUC__ >= 2
+#define force_number(n) __extension__ ({NODE *_tn = (n);\
+ (_tn->flags & NUMCUR) ?_tn->numbr : r_force_number(_tn);})
+#define force_string(s) __extension__ ({NODE *_ts = (s);\
+ ((_ts->flags & INTLSTR) ? \
+ r_force_string(_ts) : \
+ ((_ts->flags & STRCUR) && \
+ (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
+ _ts : r_force_string(_ts));})
+#else
+#ifdef MSDOS
+extern double _msc51bug;
+#define force_number(n) (_msc51bug=(_t = (n),\
+ (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t)))
+#else /* not MSDOS */
+#define force_number(n) (_t = (n),\
+ (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t))
+#endif /* not MSDOS */
+#define force_string(s) (_t = (s),(_t->flags & INTLSTR) ? \
+ r_force_string(_t) :\
+ ((_t->flags & STRCUR) && \
+ (_t->stfmt == -1 || \
+ _t->stfmt == CONVFMTidx))? \
+ _t : r_force_string(_t))
+
+#endif /* not __GNUC__ */
+#endif /* not GAWKDEBUG */
+
+#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+#define STREQN(a,b,n) ((n) && *(a)== *(b) && \
+ strncmp((a), (b), (size_t) (n)) == 0)
+
+#define fatal set_loc(__FILE__, __LINE__), r_fatal
+
+/* ------------- Function prototypes or defs (as appropriate) ------------- */
+
+/* array.c */
+extern NODE *get_actual P((NODE *symbol, int canfatal));
+extern char *array_vname P((const NODE *symbol));
+extern void array_init P((void));
+extern NODE *concat_exp P((NODE *tree));
+extern void assoc_clear P((NODE *symbol));
+extern NODE *in_array P((NODE *symbol, NODE *subs));
+extern NODE **assoc_lookup P((NODE *symbol, NODE *subs, int reference));
+extern void do_delete P((NODE *symbol, NODE *tree));
+extern void do_delete_loop P((NODE *symbol, NODE *tree));
+extern void set_SUBSEP P((void));
+extern NODE *assoc_dump P((NODE *symbol));
+extern NODE *do_adump P((NODE *tree));
+extern NODE *do_asort P((NODE *tree));
+extern NODE *do_asorti P((NODE *tree));
+extern unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize));
+/* awkgram.c */
+extern char *tokexpand P((void));
+extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
+extern NODE *install P((char *name, NODE *value));
+extern NODE *lookup P((const char *name));
+extern NODE *variable P((char *name, int can_free, NODETYPE type));
+extern int yyparse P((void));
+extern void dump_funcs P((void));
+extern void dump_vars P((const char *fname));
+extern void release_all_vars P((void));
+extern const char *getfname P((NODE *(*)(NODE *)));
+extern NODE *stopme P((NODE *tree));
+extern void shadow_funcs P((void));
+extern int check_special P((const char *name));
+extern void register_deferred_variable P((const char *name,
+ NODE *(*load_func)(void)));
+/* builtin.c */
+extern double double_to_int P((double d));
+extern NODE *do_exp P((NODE *tree));
+extern NODE *do_fflush P((NODE *tree));
+extern NODE *do_index P((NODE *tree));
+extern NODE *do_int P((NODE *tree));
+extern NODE *do_length P((NODE *tree));
+extern NODE *do_log P((NODE *tree));
+extern NODE *do_mktime P((NODE *tree));
+extern NODE *do_sprintf P((NODE *tree));
+extern void do_printf P((NODE *tree));
+extern void print_simple P((NODE *tree, FILE *fp));
+extern NODE *do_sqrt P((NODE *tree));
+extern NODE *do_substr P((NODE *tree));
+extern NODE *do_strftime P((NODE *tree));
+extern NODE *do_systime P((NODE *tree));
+extern NODE *do_system P((NODE *tree));
+extern void do_print P((NODE *tree));
+extern void do_print_rec P((NODE *tree));
+extern NODE *do_tolower P((NODE *tree));
+extern NODE *do_toupper P((NODE *tree));
+extern NODE *do_atan2 P((NODE *tree));
+extern NODE *do_sin P((NODE *tree));
+extern NODE *do_cos P((NODE *tree));
+extern NODE *do_rand P((NODE *tree));
+extern NODE *do_srand P((NODE *tree));
+extern NODE *do_match P((NODE *tree));
+extern NODE *do_gsub P((NODE *tree));
+extern NODE *do_sub P((NODE *tree));
+extern NODE *do_gensub P((NODE *tree));
+extern NODE *format_tree P((const char *, size_t, NODE *, long));
+extern NODE *do_lshift P((NODE *tree));
+extern NODE *do_rshift P((NODE *tree));
+extern NODE *do_and P((NODE *tree));
+extern NODE *do_or P((NODE *tree));
+extern NODE *do_xor P((NODE *tree));
+extern NODE *do_compl P((NODE *tree));
+extern NODE *do_strtonum P((NODE *tree));
+extern AWKNUM nondec2awknum P((char *str, size_t len));
+extern NODE *do_dcgettext P((NODE *tree));
+extern NODE *do_dcngettext P((NODE *tree));
+extern NODE *do_bindtextdomain P((NODE *tree));
+#ifdef MBS_SUPPORT
+extern int strncasecmpmbs P((const char *, mbstate_t, const char *,
+ mbstate_t, size_t));
+#endif
+/* eval.c */
+extern int interpret P((NODE *volatile tree));
+extern NODE *r_tree_eval P((NODE *tree, int iscond));
+extern int cmp_nodes P((NODE *t1, NODE *t2));
+extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign, int reference));
+extern void set_IGNORECASE P((void));
+extern void set_OFS P((void));
+extern void set_ORS P((void));
+extern void set_OFMT P((void));
+extern void set_CONVFMT P((void));
+extern void set_BINMODE P((void));
+extern void set_LINT P((void));
+extern void set_TEXTDOMAIN P((void));
+extern void update_ERRNO P((void));
+extern void update_ERRNO_saved P((int));
+extern const char *redflags2str P((int));
+extern const char *flags2str P((int));
+extern const char *genflags2str P((int flagval, const struct flagtab *tab));
+extern const char *nodetype2str P((NODETYPE type));
+extern NODE *assign_val P((NODE **lhs_p, NODE *rhs));
+extern void load_casetable P((void));
+extern size_t get_curfunc_arg_count P((void));
+#ifdef PROFILING
+extern void dump_fcall_stack P((FILE *fp));
+#endif
+/* ext.c */
+NODE *do_ext P((NODE *));
+#ifdef DYNAMIC
+void make_builtin P((char *, NODE *(*)(NODE *), int));
+NODE *get_argument P((NODE *, int));
+NODE *get_actual_argument P((NODE *, unsigned int, int, int));
+#define get_scalar_argument(t, i, opt) get_actual_argument((t), (i), (opt), FALSE)
+#define get_array_argument(t, i, opt) get_actual_argument((t), (i), (opt), TRUE)
+void set_value P((NODE *));
+#endif
+/* field.c */
+extern void init_fields P((void));
+extern void set_record P((const char *buf, int cnt));
+extern void reset_record P((void));
+extern void set_NF P((void));
+extern NODE **get_field P((long num, Func_ptr *assign));
+extern NODE *do_split P((NODE *tree));
+extern void set_FS P((void));
+extern void set_RS P((void));
+extern void set_FIELDWIDTHS P((void));
+extern int using_fieldwidths P((void));
+/* gawkmisc.c */
+extern char *gawk_name P((const char *filespec));
+extern void os_arg_fixup P((int *argcp, char ***argvp));
+extern int os_devopen P((const char *name, int flag));
+extern void os_close_on_exec P((int fd, const char *name, const char *what,
+ const char *dir));
+extern int os_isdir P((int fd));
+extern int os_is_setuid P((void));
+extern int os_setbinmode P((int fd, int mode));
+extern void os_restore_mode P((int fd));
+extern size_t optimal_bufsize P((int fd, struct stat *sbuf));
+extern int ispath P((const char *file));
+extern int isdirpunct P((int c));
+#if defined(_MSC_VER) && !defined(_WIN32)
+extern char *memcpy_ulong P((char *dest, const char *src, unsigned long l));
+extern void *memset_ulong P((void *dest, int val, unsigned long l));
+#define memcpy memcpy_ulong
+#define memset memset_ulong
+#endif
+/* io.c */
+extern void register_open_hook P((void *(*open_func)(IOBUF *)));
+extern void set_FNR P((void));
+extern void set_NR P((void));
+extern void do_input P((void));
+extern struct redirect *redirect P((NODE *tree, int *errflg));
+extern NODE *do_close P((NODE *tree));
+extern int flush_io P((void));
+extern int close_io P((int *stdio_problem));
+extern int devopen P((const char *name, const char *mode));
+extern int pathopen P((const char *file));
+extern NODE *do_getline P((NODE *tree));
+extern void do_nextfile P((void)) ATTRIBUTE_NORETURN;
+extern struct redirect *getredirect P((const char *str, int len));
+/* main.c */
+extern int main P((int argc, char **argv));
+extern int arg_assign P((char *arg, int initing));
+/* msg.c */
+extern void err P((const char *s, const char *emsg, va_list argp)) ATTRIBUTE_PRINTF(2, 0);
+#if _MSC_VER == 510
+extern void msg P((va_list va_alist, ...));
+extern void error P((va_list va_alist, ...));
+extern void warning P((va_list va_alist, ...));
+extern void set_loc P((const char *file, int line));
+extern void r_fatal P((va_list va_alist, ...));
+extern void (*lintfunc) P((va_list va_alist, ...));
+#else
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
+extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
+extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
+extern void set_loc (const char *file, int line);
+extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+ATTRIBUTE_EXPORTED
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
+extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
+#else
+extern void (*lintfunc) (const char *mesg, ...);
+#endif
+#else
+extern void msg ();
+extern void error ();
+extern void warning ();
+extern void set_loc ();
+extern void r_fatal ();
+extern void (*lintfunc) ();
+#endif
+#endif
+/* profile.c */
+extern void init_profiling P((int *flag, const char *def_file));
+extern void init_profiling_signals P((void));
+extern void set_prof_file P((const char *filename));
+extern void dump_prog P((NODE *begin, NODE *prog, NODE *end));
+extern void pp_func P((const char *name, size_t namelen, NODE *f));
+extern void pp_string_fp P((FILE *fp, const char *str, size_t namelen,
+ int delim, int breaklines));
+/* node.c */
+extern AWKNUM r_force_number P((NODE *n));
+extern NODE *format_val P((const char *format, int index, NODE *s));
+extern NODE *r_force_string P((NODE *s));
+extern NODE *r_dupnode P((NODE *n));
+extern NODE *copynode P((NODE *n));
+extern NODE *mk_number P((AWKNUM x, unsigned int flags));
+extern NODE *make_str_node P((char *s, unsigned long len, int scan ));
+extern NODE *tmp_string P((char *s, size_t len ));
+extern NODE *more_nodes P((void));
+#ifdef MEMDEBUG
+extern void freenode P((NODE *it));
+#endif
+extern void unref P((NODE *tmp));
+extern int parse_escape P((const char **string_ptr));
+#ifdef MBS_SUPPORT
+extern NODE *str2wstr P((NODE *n, size_t **ptr));
+#define force_wstring(n) str2wstr(n, NULL)
+extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
+extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
+#endif
+/* re.c */
+extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa));
+extern int research P((Regexp *rp, char *str, int start,
+ size_t len, int flags));
+extern void refree P((Regexp *rp));
+extern void reg_error P((const char *s));
+extern Regexp *re_update P((NODE *t));
+extern void resyntax P((int syntax));
+extern void resetup P((void));
+extern int avoid_dfa P((NODE *re, char *str, size_t len)); /* temporary */
+extern int reisstring P((const char *text, size_t len, Regexp *re, const char *buf));
+extern int remaybelong P((const char *text, size_t len));
+extern int isnondecimal P((const char *str, int use_locale));
+
+/* strncasecmp.c */
+#ifndef BROKEN_STRNCASECMP
+extern int strcasecmp P((const char *s1, const char *s2));
+extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
+#endif
+
+#if defined(atarist)
+#if defined(PIPES_SIMULATED)
+/* unsupported/atari/tmpnam.c */
+extern char *tmpnam P((char *buf));
+extern char *tempnam P((const char *path, const char *base));
+#else
+#include <wait.h>
+#endif
+#include <fcntl.h>
+#define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1)
+#else
+#define INVALID_HANDLE (-1)
+#endif /* atarist */
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
+#endif
+
+#ifndef STATIC
+#define STATIC static
+#endif
--- /dev/null
+/* A Bison parser, made by GNU Bison 2.0. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ FUNC_CALL = 258,
+ NAME = 259,
+ REGEXP = 260,
+ ERROR = 261,
+ YNUMBER = 262,
+ YSTRING = 263,
+ RELOP = 264,
+ IO_OUT = 265,
+ IO_IN = 266,
+ ASSIGNOP = 267,
+ ASSIGN = 268,
+ MATCHOP = 269,
+ CONCAT_OP = 270,
+ LEX_BEGIN = 271,
+ LEX_END = 272,
+ LEX_IF = 273,
+ LEX_ELSE = 274,
+ LEX_RETURN = 275,
+ LEX_DELETE = 276,
+ LEX_SWITCH = 277,
+ LEX_CASE = 278,
+ LEX_DEFAULT = 279,
+ LEX_WHILE = 280,
+ LEX_DO = 281,
+ LEX_FOR = 282,
+ LEX_BREAK = 283,
+ LEX_CONTINUE = 284,
+ LEX_PRINT = 285,
+ LEX_PRINTF = 286,
+ LEX_NEXT = 287,
+ LEX_EXIT = 288,
+ LEX_FUNCTION = 289,
+ LEX_GETLINE = 290,
+ LEX_NEXTFILE = 291,
+ LEX_IN = 292,
+ LEX_AND = 293,
+ LEX_OR = 294,
+ INCREMENT = 295,
+ DECREMENT = 296,
+ LEX_BUILTIN = 297,
+ LEX_LENGTH = 298,
+ NEWLINE = 299,
+ SLASH_BEFORE_EQUAL = 300,
+ UNARY = 301
+ };
+#endif
+#define FUNC_CALL 258
+#define NAME 259
+#define REGEXP 260
+#define ERROR 261
+#define YNUMBER 262
+#define YSTRING 263
+#define RELOP 264
+#define IO_OUT 265
+#define IO_IN 266
+#define ASSIGNOP 267
+#define ASSIGN 268
+#define MATCHOP 269
+#define CONCAT_OP 270
+#define LEX_BEGIN 271
+#define LEX_END 272
+#define LEX_IF 273
+#define LEX_ELSE 274
+#define LEX_RETURN 275
+#define LEX_DELETE 276
+#define LEX_SWITCH 277
+#define LEX_CASE 278
+#define LEX_DEFAULT 279
+#define LEX_WHILE 280
+#define LEX_DO 281
+#define LEX_FOR 282
+#define LEX_BREAK 283
+#define LEX_CONTINUE 284
+#define LEX_PRINT 285
+#define LEX_PRINTF 286
+#define LEX_NEXT 287
+#define LEX_EXIT 288
+#define LEX_FUNCTION 289
+#define LEX_GETLINE 290
+#define LEX_NEXTFILE 291
+#define LEX_IN 292
+#define LEX_AND 293
+#define LEX_OR 294
+#define INCREMENT 295
+#define DECREMENT 296
+#define LEX_BUILTIN 297
+#define LEX_LENGTH 298
+#define NEWLINE 299
+#define SLASH_BEFORE_EQUAL 300
+#define UNARY 301
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 26 "awkgram.y"
+
+#ifdef GAWKDEBUG
+#define YYDEBUG 12
+#endif
+
+#include "awk.h"
+
+#define CAN_FREE TRUE
+#define DONT_FREE FALSE
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1;
+#else
+static void yyerror(); /* va_alist */
+#endif
+static char *get_src_buf P((void));
+static int yylex P((void));
+static NODE *node_common P((NODETYPE op));
+static NODE *snode P((NODE *subn, NODETYPE op, int sindex));
+static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr));
+static NODE *append_right P((NODE *list, NODE *new));
+static inline NODE *append_pattern P((NODE **list, NODE *patt));
+static void func_install P((NODE *params, NODE *def));
+static void pop_var P((NODE *np, int freeit));
+static void pop_params P((NODE *params));
+static NODE *make_param P((char *name));
+static NODE *mk_rexp P((NODE *exp));
+static int dup_parms P((NODE *func));
+static void param_sanity P((NODE *arglist));
+static int parms_shadow P((const char *fname, NODE *func));
+static int isnoeffect P((NODETYPE t));
+static int isassignable P((NODE *n));
+static void dumpintlstr P((const char *str, size_t len));
+static void dumpintlstr2 P((const char *str1, size_t len1, const char *str2, size_t len2));
+static void count_args P((NODE *n));
+static int isarray P((NODE *n));
+
+enum defref { FUNC_DEFINE, FUNC_USE };
+static void func_use P((const char *name, enum defref how));
+static void check_funcs P((void));
+
+static int want_regexp; /* lexical scanning kludge */
+static int can_return; /* parsing kludge */
+static int begin_or_end_rule = FALSE; /* parsing kludge */
+static int parsing_end_rule = FALSE; /* for warnings */
+static int in_print = FALSE; /* lexical scanning kludge for print */
+static int in_parens = 0; /* lexical scanning kludge for print */
+static char *lexptr; /* pointer to next char during parsing */
+static char *lexend;
+static char *lexptr_begin; /* keep track of where we were for error msgs */
+static char *lexeme; /* beginning of lexeme for debugging */
+static char *thisline = NULL;
+#define YYDEBUG_LEXER_TEXT (lexeme)
+static int param_counter;
+static char *tokstart = NULL;
+static char *tok = NULL;
+static char *tokend;
+
+static long func_count; /* total number of functions */
+
+#define HASHSIZE 1021 /* this constant only used here */
+NODE *variables[HASHSIZE];
+static int var_count; /* total number of global variables */
+
+extern char *source;
+extern int sourceline;
+extern struct src *srcfiles;
+extern long numfiles;
+extern int errcount;
+extern NODE *begin_block;
+extern NODE *end_block;
+
+/*
+ * This string cannot occur as a real awk identifier.
+ * Use it as a special token to make function parsing
+ * uniform, but if it's seen, don't install the function.
+ * e.g.
+ * function split(x) { return x }
+ * function x(a) { return a }
+ * should only produce one error message, and not core dump.
+ */
+static char builtin_func[] = "@builtin";
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 110 "awkgram.y"
+typedef union YYSTYPE {
+ long lval;
+ AWKNUM fval;
+ NODE *nodeval;
+ NODETYPE nodetypeval;
+ char *sval;
+ NODE *(*ptrval) P((void));
+} YYSTYPE;
+/* Line 190 of yacc.c. */
+#line 261 "y.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 213 of yacc.c. */
+#line 273 "y.tab.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# else
+# define YYSTACK_ALLOC alloca
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) && (! defined (__cplusplus) || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined (__GNUC__) && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 1008
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 67
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 53
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 155
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 293
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 301
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 56, 2, 2, 59, 55, 2, 2,
+ 60, 61, 53, 51, 48, 52, 2, 54, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 47, 66,
+ 49, 2, 50, 46, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 62, 2, 63, 58, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 64, 2, 65, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 57
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short int yyprhs[] =
+{
+ 0, 0, 3, 7, 8, 11, 14, 17, 20, 23,
+ 24, 26, 30, 32, 34, 40, 42, 44, 46, 48,
+ 50, 51, 59, 60, 64, 66, 68, 69, 72, 75,
+ 77, 80, 83, 87, 89, 99, 106, 115, 124, 137,
+ 149, 152, 155, 158, 161, 165, 166, 171, 174, 175,
+ 180, 186, 189, 194, 196, 197, 199, 201, 202, 205,
+ 208, 214, 219, 221, 224, 227, 229, 231, 233, 235,
+ 237, 243, 244, 245, 249, 256, 266, 268, 271, 272,
+ 274, 275, 278, 279, 281, 283, 287, 289, 292, 296,
+ 297, 299, 300, 302, 304, 308, 310, 313, 317, 321,
+ 325, 329, 333, 337, 341, 345, 351, 353, 355, 357,
+ 360, 362, 364, 366, 368, 370, 373, 379, 381, 384,
+ 386, 390, 394, 398, 402, 406, 410, 414, 419, 422,
+ 425, 428, 432, 437, 442, 444, 449, 451, 454, 457,
+ 459, 461, 464, 467, 468, 470, 472, 477, 480, 483,
+ 486, 488, 489, 491, 493, 495
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 68, 0, -1, 97, 69, 97, -1, -1, 69, 70,
+ -1, 69, 1, -1, 71, 72, -1, 71, 81, -1,
+ 75, 72, -1, -1, 104, -1, 104, 48, 104, -1,
+ 16, -1, 17, -1, 113, 80, 114, 116, 97, -1,
+ 4, -1, 3, -1, 74, -1, 42, -1, 43, -1,
+ -1, 34, 76, 73, 60, 99, 115, 97, -1, -1,
+ 79, 78, 5, -1, 54, -1, 45, -1, -1, 80,
+ 82, -1, 80, 1, -1, 96, -1, 117, 97, -1,
+ 117, 97, -1, 113, 80, 114, -1, 95, -1, 22,
+ 60, 104, 115, 97, 113, 87, 97, 114, -1, 25,
+ 60, 104, 115, 97, 82, -1, 26, 97, 82, 25,
+ 60, 104, 115, 97, -1, 27, 60, 4, 37, 4,
+ 115, 97, 82, -1, 27, 60, 86, 117, 97, 104,
+ 117, 97, 86, 115, 97, 82, -1, 27, 60, 86,
+ 117, 97, 117, 97, 86, 115, 97, 82, -1, 28,
+ 81, -1, 29, 81, -1, 32, 81, -1, 36, 81,
+ -1, 33, 101, 81, -1, -1, 20, 83, 101, 81,
+ -1, 84, 81, -1, -1, 91, 85, 92, 93, -1,
+ 21, 4, 62, 103, 63, -1, 21, 4, -1, 21,
+ 60, 4, 61, -1, 104, -1, -1, 84, -1, 88,
+ -1, -1, 88, 89, -1, 88, 1, -1, 23, 90,
+ 118, 97, 80, -1, 24, 118, 97, 80, -1, 7,
+ -1, 52, 7, -1, 51, 7, -1, 8, -1, 77,
+ -1, 30, -1, 31, -1, 102, -1, 60, 104, 119,
+ 103, 115, -1, -1, -1, 10, 94, 108, -1, 18,
+ 60, 104, 115, 97, 82, -1, 18, 60, 104, 115,
+ 97, 82, 19, 97, 82, -1, 44, -1, 96, 44,
+ -1, -1, 96, -1, -1, 49, 109, -1, -1, 100,
+ -1, 4, -1, 100, 119, 4, -1, 1, -1, 100,
+ 1, -1, 100, 119, 1, -1, -1, 104, -1, -1,
+ 103, -1, 104, -1, 103, 119, 104, -1, 1, -1,
+ 103, 1, -1, 103, 1, 104, -1, 103, 119, 1,
+ -1, 112, 105, 104, -1, 104, 38, 104, -1, 104,
+ 39, 104, -1, 104, 14, 104, -1, 104, 37, 4,
+ -1, 104, 107, 104, -1, 104, 46, 104, 47, 104,
+ -1, 108, -1, 13, -1, 12, -1, 45, 13, -1,
+ 9, -1, 49, -1, 106, -1, 50, -1, 77, -1,
+ 56, 77, -1, 60, 103, 115, 37, 4, -1, 109,
+ -1, 108, 109, -1, 110, -1, 109, 58, 109, -1,
+ 109, 53, 109, -1, 109, 54, 109, -1, 109, 55,
+ 109, -1, 109, 51, 109, -1, 109, 52, 109, -1,
+ 35, 111, 98, -1, 109, 11, 35, 111, -1, 112,
+ 40, -1, 112, 41, -1, 56, 109, -1, 60, 104,
+ 115, -1, 42, 60, 102, 115, -1, 43, 60, 102,
+ 115, -1, 43, -1, 3, 60, 102, 115, -1, 112,
+ -1, 40, 112, -1, 41, 112, -1, 7, -1, 8,
+ -1, 52, 109, -1, 51, 109, -1, -1, 112, -1,
+ 4, -1, 4, 62, 103, 63, -1, 59, 110, -1,
+ 64, 97, -1, 65, 97, -1, 61, -1, -1, 117,
+ -1, 66, -1, 47, -1, 48, 97, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short int yyrline[] =
+{
+ 0, 171, 171, 177, 179, 184, 196, 200, 215, 226,
+ 229, 233, 243, 248, 256, 261, 263, 265, 276, 277,
+ 282, 281, 305, 304, 330, 331, 336, 337, 355, 360,
+ 361, 365, 367, 369, 371, 373, 375, 377, 421, 425,
+ 430, 433, 436, 445, 465, 468, 467, 477, 489, 489,
+ 520, 522, 536, 551, 557, 558, 563, 616, 617, 634,
+ 639, 641, 646, 648, 653, 655, 657, 662, 663, 671,
+ 672, 678, 683, 683, 695, 700, 707, 708, 711, 713,
+ 718, 719, 725, 726, 731, 733, 735, 737, 739, 746,
+ 747, 753, 754, 759, 761, 767, 769, 771, 773, 778,
+ 797, 799, 801, 807, 809, 815, 817, 822, 824, 826,
+ 831, 833, 837, 838, 843, 845, 853, 855, 857, 862,
+ 864, 866, 868, 870, 872, 874, 876, 882, 887, 889,
+ 894, 896, 898, 901, 903, 911, 919, 920, 922, 924,
+ 926, 929, 937, 949, 950, 955, 957, 971, 982, 986,
+ 990, 993, 995, 999, 1003, 1006
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "FUNC_CALL", "NAME", "REGEXP", "ERROR",
+ "YNUMBER", "YSTRING", "RELOP", "IO_OUT", "IO_IN", "ASSIGNOP", "ASSIGN",
+ "MATCHOP", "CONCAT_OP", "LEX_BEGIN", "LEX_END", "LEX_IF", "LEX_ELSE",
+ "LEX_RETURN", "LEX_DELETE", "LEX_SWITCH", "LEX_CASE", "LEX_DEFAULT",
+ "LEX_WHILE", "LEX_DO", "LEX_FOR", "LEX_BREAK", "LEX_CONTINUE",
+ "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT", "LEX_FUNCTION",
+ "LEX_GETLINE", "LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR",
+ "INCREMENT", "DECREMENT", "LEX_BUILTIN", "LEX_LENGTH", "NEWLINE",
+ "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'", "'+'", "'-'",
+ "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('", "')'", "'['",
+ "']'", "'{'", "'}'", "';'", "$accept", "start", "program", "rule",
+ "pattern", "action", "func_name", "lex_builtin", "function_prologue",
+ "@1", "regexp", "@2", "a_slash", "statements", "statement_term",
+ "statement", "@3", "simple_stmt", "@4", "opt_simple_stmt", "switch_body",
+ "case_statements", "case_statement", "case_value", "print",
+ "print_expression_list", "output_redir", "@5", "if_statement", "nls",
+ "opt_nls", "input_redir", "opt_param_list", "param_list", "opt_exp",
+ "opt_expression_list", "expression_list", "exp", "assign_operator",
+ "relop_or_less", "a_relop", "common_exp", "simp_exp",
+ "non_post_simp_exp", "opt_variable", "variable", "l_brace", "r_brace",
+ "r_paren", "opt_semi", "semi", "colon", "comma", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 63, 58, 44, 60,
+ 62, 43, 45, 42, 47, 37, 33, 301, 94, 36,
+ 40, 41, 91, 93, 123, 125, 59
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 67, 68, 69, 69, 69, 70, 70, 70, 71,
+ 71, 71, 71, 71, 72, 73, 73, 73, 74, 74,
+ 76, 75, 78, 77, 79, 79, 80, 80, 80, 81,
+ 81, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82, 82, 82, 83, 82, 82, 85, 84,
+ 84, 84, 84, 84, 86, 86, 87, 88, 88, 88,
+ 89, 89, 90, 90, 90, 90, 90, 91, 91, 92,
+ 92, 93, 94, 93, 95, 95, 96, 96, 97, 97,
+ 98, 98, 99, 99, 100, 100, 100, 100, 100, 101,
+ 101, 102, 102, 103, 103, 103, 103, 103, 103, 104,
+ 104, 104, 104, 104, 104, 104, 104, 105, 105, 105,
+ 106, 106, 107, 107, 108, 108, 108, 108, 108, 109,
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 111, 111, 112, 112, 112, 113, 114,
+ 115, 116, 116, 117, 118, 119
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 3, 0, 2, 2, 2, 2, 2, 0,
+ 1, 3, 1, 1, 5, 1, 1, 1, 1, 1,
+ 0, 7, 0, 3, 1, 1, 0, 2, 2, 1,
+ 2, 2, 3, 1, 9, 6, 8, 8, 12, 11,
+ 2, 2, 2, 2, 3, 0, 4, 2, 0, 4,
+ 5, 2, 4, 1, 0, 1, 1, 0, 2, 2,
+ 5, 4, 1, 2, 2, 1, 1, 1, 1, 1,
+ 5, 0, 0, 3, 6, 9, 1, 2, 0, 1,
+ 0, 2, 0, 1, 1, 3, 1, 2, 3, 0,
+ 1, 0, 1, 1, 3, 1, 2, 3, 3, 3,
+ 3, 3, 3, 3, 3, 5, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 2, 5, 1, 2, 1,
+ 3, 3, 3, 3, 3, 3, 3, 4, 2, 2,
+ 2, 3, 4, 4, 1, 4, 1, 2, 2, 1,
+ 1, 2, 2, 0, 1, 1, 4, 2, 2, 2,
+ 1, 0, 1, 1, 1, 2
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 78, 76, 0, 79, 3, 1, 77, 0, 5, 0,
+ 145, 139, 140, 12, 13, 20, 143, 0, 0, 0,
+ 134, 25, 0, 0, 24, 0, 0, 0, 4, 0,
+ 0, 114, 22, 2, 10, 106, 117, 119, 136, 0,
+ 0, 0, 80, 144, 137, 138, 0, 0, 0, 0,
+ 142, 136, 141, 115, 130, 147, 136, 95, 0, 93,
+ 78, 153, 6, 7, 29, 26, 78, 8, 0, 110,
+ 0, 0, 0, 0, 0, 0, 111, 113, 112, 0,
+ 118, 0, 0, 0, 0, 0, 0, 0, 108, 107,
+ 128, 129, 0, 0, 0, 0, 93, 0, 16, 15,
+ 18, 19, 0, 17, 0, 126, 0, 0, 0, 96,
+ 78, 150, 0, 0, 131, 148, 0, 30, 23, 102,
+ 103, 100, 101, 0, 11, 104, 143, 124, 125, 121,
+ 122, 123, 120, 109, 99, 135, 146, 0, 81, 132,
+ 133, 97, 155, 0, 98, 94, 28, 0, 45, 0,
+ 0, 0, 78, 0, 0, 0, 67, 68, 0, 89,
+ 0, 78, 27, 0, 48, 33, 53, 26, 151, 78,
+ 0, 127, 86, 84, 0, 0, 116, 0, 89, 51,
+ 0, 0, 0, 0, 54, 40, 41, 42, 0, 90,
+ 43, 149, 47, 0, 0, 78, 152, 31, 105, 78,
+ 87, 0, 0, 0, 0, 0, 0, 0, 0, 145,
+ 55, 0, 44, 0, 71, 69, 32, 14, 21, 88,
+ 85, 78, 46, 0, 52, 78, 78, 0, 0, 78,
+ 93, 72, 49, 0, 50, 0, 0, 0, 0, 0,
+ 0, 0, 74, 57, 35, 0, 78, 0, 78, 0,
+ 73, 78, 78, 0, 78, 0, 78, 54, 70, 0,
+ 0, 59, 0, 0, 58, 36, 37, 54, 0, 75,
+ 34, 62, 65, 0, 0, 66, 0, 154, 78, 0,
+ 78, 64, 63, 78, 26, 78, 0, 26, 0, 0,
+ 39, 0, 38
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+ -1, 2, 7, 28, 29, 62, 102, 103, 30, 41,
+ 31, 68, 32, 116, 63, 162, 178, 163, 193, 211,
+ 252, 253, 264, 276, 164, 214, 232, 241, 165, 3,
+ 4, 105, 174, 175, 188, 94, 95, 166, 93, 78,
+ 79, 35, 36, 37, 42, 38, 167, 168, 114, 195,
+ 169, 278, 113
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -236
+static const short int yypact[] =
+{
+ -15, -236, 31, -3, -236, -236, -236, 292, -236, -8,
+ -2, -236, -236, -236, -236, -236, 26, 26, 26, 4,
+ 6, -236, 934, 934, -236, 876, 262, 717, -236, -16,
+ 3, -236, -236, -236, 769, 934, 480, -236, 554, 656,
+ 717, 33, 49, -236, -236, -236, 656, 656, 934, 905,
+ 41, -1, 41, -236, 41, -236, -236, -236, 117, 695,
+ -15, -236, -236, -236, -3, -236, -15, -236, 101, -236,
+ 905, 103, 905, 905, 905, 905, -236, -236, -236, 905,
+ 480, 74, 934, 934, 934, 934, 934, 934, -236, -236,
+ -236, -236, 100, 905, 54, 17, 958, 32, -236, -236,
+ -236, -236, 56, -236, 934, -236, 54, 54, 695, 905,
+ -15, -236, 86, 739, -236, -236, 454, -236, -236, 133,
+ -236, 184, 166, 823, 958, 7, 26, 136, 136, 41,
+ 41, 41, 41, -236, 958, -236, -236, 43, 538, -236,
+ -236, 958, -236, 121, -236, 958, -236, 68, -236, 2,
+ 69, 70, -15, 71, 61, 61, -236, -236, 61, 905,
+ 61, -15, -236, 61, -236, -236, 958, -236, 73, -15,
+ 905, -236, -236, -236, 54, 123, -236, 905, 905, 81,
+ 131, 905, 905, 580, 793, -236, -236, -236, 61, 958,
+ -236, -236, -236, 520, 454, -15, -236, -236, 958, -15,
+ -236, 45, 695, 61, 717, 83, 695, 695, 130, -11,
+ -236, 73, -236, 717, 147, -236, -236, -236, -236, -236,
+ -236, -15, -236, 34, -236, -15, -15, 108, 169, -15,
+ 508, -236, -236, 580, -236, 3, 580, 905, 54, 634,
+ 717, 905, 155, -236, -236, 695, -15, 502, -15, 117,
+ 934, -15, -15, 19, -15, 580, -15, 847, -236, 580,
+ 111, -236, 201, 132, -236, -236, -236, 847, 54, -236,
+ -236, -236, -236, 178, 179, -236, 132, -236, -15, 54,
+ -15, -236, -236, -15, -236, -15, 580, -236, 346, 580,
+ -236, 400, -236
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short int yypgoto[] =
+{
+ -236, -236, -236, -236, -236, 165, -236, -236, -236, -236,
+ -24, -236, -236, -150, 152, -178, -236, -165, -236, -235,
+ -236, -236, -236, -236, -236, -236, -236, -236, -236, -22,
+ -7, -236, -236, -236, 21, -32, -17, 47, -236, -236,
+ -236, -41, 66, 175, 76, -14, -5, -181, 52, -236,
+ 9, -71, -130
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -93
+static const short int yytable[] =
+{
+ 33, 53, 43, 44, 45, 208, 179, 64, 51, 51,
+ 58, 51, 56, 216, 106, 107, -93, 194, 109, 210,
+ 261, 51, 268, 97, 65, 65, 228, -92, 1, 1,
+ 10, 5, 279, 109, 51, 109, 98, 99, 66, 90,
+ 91, 6, 262, 263, 172, 201, 219, 173, 60, 220,
+ 61, 40, 39, 115, 34, 242, -93, -93, 244, 117,
+ 40, -92, 180, -56, 46, 110, 47, 60, 51, 51,
+ 51, 51, 51, 51, 59, 100, 101, 266, -92, 270,
+ 110, 269, 110, -92, -56, 26, 96, 96, 50, 52,
+ 51, 54, 210, 96, 96, 136, 108, 234, 104, 87,
+ 240, 80, 210, 142, -82, 1, 118, 120, 290, 126,
+ 112, 292, 43, 133, 54, 111, 137, 119, 109, 121,
+ 122, 123, 124, 143, 200, 176, 125, 61, 177, 181,
+ 182, 184, 64, 64, 288, 205, 64, 291, 64, 61,
+ 134, 64, 69, 204, 224, 183, 135, -93, 127, 128,
+ 129, 130, 131, 132, 191, 227, 141, 231, 139, 140,
+ 145, 215, 197, 66, 66, 110, 64, 66, 237, 66,
+ 138, 110, 66, 238, 251, 69, 161, 196, 111, 277,
+ 70, 64, 76, 77, -83, 281, 282, 223, 217, 84,
+ 85, 86, 218, 69, 87, 67, 58, 66, 70, 203,
+ 250, 55, 171, 71, 72, 283, 189, 0, 271, 272,
+ 0, 0, 66, 0, 233, 76, 77, 198, 235, 236,
+ 229, 71, 239, 249, 202, 189, 199, 51, 206, 207,
+ 243, 0, 0, 76, 77, 0, 51, 0, 275, 255,
+ 96, 257, 0, 0, 259, 260, 21, 265, 248, 267,
+ 0, 96, 273, 274, 221, 24, 256, 0, 225, 226,
+ 230, 0, 0, 0, 0, 9, 10, 0, 0, 11,
+ 12, 284, 0, 286, 0, 0, 287, 0, 289, 0,
+ 0, 0, 0, 0, 245, 0, 247, 96, 0, 0,
+ 246, 0, -78, 8, 0, 9, 10, 254, 0, 11,
+ 12, 258, 17, 18, 19, 20, 185, 186, 13, 14,
+ 187, 0, 190, 22, 23, 192, 80, 0, 48, 0,
+ 280, 26, 49, 0, 0, 0, 15, 16, 0, 0,
+ 0, 285, 17, 18, 19, 20, 1, 21, 0, 0,
+ 212, 0, 0, 22, 23, 0, 24, 146, 25, 9,
+ 10, 26, 27, 11, 12, 222, -9, 0, -9, 0,
+ 0, 0, 0, 0, 147, 0, 148, 149, 150, -61,
+ -61, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 0, 16, 160, 0, 0, 0, 17, 18, 19, 20,
+ -61, 21, 0, 0, 0, 0, 0, 22, 23, 0,
+ 24, 146, 25, 9, 10, 26, 27, 11, 12, 0,
+ 60, -61, 61, 0, 0, 0, 0, 0, 147, 0,
+ 148, 149, 150, -60, -60, 151, 152, 153, 154, 155,
+ 156, 157, 158, 159, 0, 16, 160, 0, 0, 0,
+ 17, 18, 19, 20, -60, 21, 0, 0, 0, 0,
+ 0, 22, 23, 0, 24, 146, 25, 9, 10, 26,
+ 27, 11, 12, 0, 60, -60, 61, 0, 0, 0,
+ 0, 0, 147, 0, 148, 149, 150, 0, 0, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159, 0, 16,
+ 160, 81, 0, 0, 17, 18, 19, 20, 0, 21,
+ 0, 0, 0, 0, 0, 22, 23, 0, 24, 0,
+ 25, 69, 0, 26, 27, 0, 70, 69, 60, 161,
+ 61, 57, 70, 9, 10, 0, 0, 11, 12, 0,
+ -91, 82, 83, 84, 85, 86, 0, 0, 87, 71,
+ 72, 73, 0, 0, 0, 71, 72, 73, 74, -93,
+ 0, 76, 77, 0, 74, 16, 110, 76, 77, 0,
+ 17, 18, 19, 20, -91, 21, 88, 89, 61, 111,
+ 0, 22, 23, 0, 24, 0, 25, 0, 0, 26,
+ 213, -91, 0, 9, 10, 0, -91, 11, 12, 82,
+ 83, 84, 85, 86, 90, 91, 87, 0, 147, 92,
+ 148, 149, 150, 0, 0, 151, 152, 153, 154, 155,
+ 156, 157, 158, 159, 0, 16, 160, 0, 0, 0,
+ 17, 18, 19, 20, 0, 21, 0, 0, 0, 0,
+ 0, 22, 23, 0, 24, 0, 25, 9, 10, 26,
+ 27, 11, 12, 0, 60, 0, 61, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 57, 0, 9,
+ 10, 0, 0, 11, 12, 0, 0, 0, 0, 16,
+ 0, 0, 0, 0, 17, 18, 19, 20, 0, 21,
+ 0, 0, 0, 0, 0, 22, 23, 0, 24, 0,
+ 25, 16, 0, 26, 27, 0, 17, 18, 19, 20,
+ 61, 21, 0, 0, 69, 0, 0, 22, 23, 70,
+ 24, 0, 25, 0, 0, 26, 27, -91, 57, 0,
+ 9, 10, 0, 0, 11, 12, 0, 0, 0, 0,
+ 0, 0, 71, 72, 73, 0, 0, 0, 0, 0,
+ 144, 74, 9, 10, 76, 77, 11, 12, 0, 0,
+ 0, 0, 16, 0, 0, 0, 111, 17, 18, 19,
+ 20, 0, 21, 0, 0, 0, 0, 0, 22, 23,
+ 0, 24, 0, 25, 16, 0, 26, 27, 69, 17,
+ 18, 19, 20, 70, 21, 0, 0, 0, 0, 0,
+ 22, 23, 0, 24, 0, 25, 9, 209, 26, 27,
+ 11, 12, 0, 0, 0, 0, 71, 72, 73, 0,
+ 0, 0, 0, 0, 149, 74, 0, 75, 76, 77,
+ 0, 0, 0, 156, 157, 0, 0, 0, 16, 0,
+ 0, 0, 69, 17, 18, 19, 20, 70, 21, 0,
+ 0, 0, 0, 0, 22, 23, 0, 24, 0, 25,
+ 9, 10, 26, 27, 11, 12, 0, 0, 0, 0,
+ 71, 72, 73, 0, 0, 0, 0, 0, 149, 74,
+ 170, 0, 76, 77, 0, 0, 0, 156, 157, 9,
+ 10, 0, 16, 11, 12, 0, 0, 17, 18, 19,
+ 20, 0, 21, 0, 0, 0, 0, 0, 22, 23,
+ 0, 24, 0, 25, 0, 0, 26, 27, 9, 10,
+ 0, 16, 11, 12, 0, 0, 17, 18, 19, 20,
+ 0, 21, 0, 0, 0, 0, 0, 22, 23, 0,
+ 24, 0, 48, 0, 0, 26, 49, 9, 10, 0,
+ 16, 11, 12, 0, 0, 17, 18, 19, 20, 0,
+ 21, 0, 0, 0, 0, 0, 22, 23, 0, 24,
+ 0, 25, 0, 0, 26, 27, 0, 69, 0, 16,
+ 0, 0, 70, 0, 17, 18, 19, 20, 0, 0,
+ 0, 0, 0, 0, 0, 22, 23, 0, 0, 0,
+ 48, 0, 0, 26, 49, 71, 72, 73, 0, 0,
+ 0, 0, 0, 0, 74, 0, 0, 76, 77
+};
+
+static const short int yycheck[] =
+{
+ 7, 25, 16, 17, 18, 183, 4, 29, 22, 23,
+ 27, 25, 26, 194, 46, 47, 9, 167, 1, 184,
+ 1, 35, 257, 40, 29, 30, 37, 10, 44, 44,
+ 4, 0, 267, 1, 48, 1, 3, 4, 29, 40,
+ 41, 44, 23, 24, 1, 175, 1, 4, 64, 4,
+ 66, 62, 60, 60, 7, 233, 49, 50, 236, 66,
+ 62, 44, 60, 44, 60, 48, 60, 64, 82, 83,
+ 84, 85, 86, 87, 27, 42, 43, 255, 61, 260,
+ 48, 259, 48, 66, 65, 59, 39, 40, 22, 23,
+ 104, 25, 257, 46, 47, 63, 49, 63, 49, 58,
+ 230, 35, 267, 110, 61, 44, 5, 4, 286, 35,
+ 58, 289, 126, 13, 48, 61, 60, 70, 1, 72,
+ 73, 74, 75, 37, 1, 4, 79, 66, 60, 60,
+ 60, 60, 154, 155, 284, 4, 158, 287, 160, 66,
+ 93, 163, 9, 62, 61, 152, 94, 14, 82, 83,
+ 84, 85, 86, 87, 161, 25, 109, 10, 106, 107,
+ 113, 193, 169, 154, 155, 48, 188, 158, 60, 160,
+ 104, 48, 163, 4, 19, 9, 65, 168, 61, 47,
+ 14, 203, 49, 50, 61, 7, 7, 204, 195, 53,
+ 54, 55, 199, 9, 58, 30, 213, 188, 14, 178,
+ 241, 26, 126, 37, 38, 276, 159, -1, 7, 8,
+ -1, -1, 203, -1, 221, 49, 50, 170, 225, 226,
+ 211, 37, 229, 240, 177, 178, 174, 241, 181, 182,
+ 235, -1, -1, 49, 50, -1, 250, -1, 262, 246,
+ 193, 248, -1, -1, 251, 252, 45, 254, 239, 256,
+ -1, 204, 51, 52, 202, 54, 247, -1, 206, 207,
+ 213, -1, -1, -1, -1, 3, 4, -1, -1, 7,
+ 8, 278, -1, 280, -1, -1, 283, -1, 285, -1,
+ -1, -1, -1, -1, 237, -1, 239, 240, -1, -1,
+ 238, -1, 0, 1, -1, 3, 4, 245, -1, 7,
+ 8, 249, 40, 41, 42, 43, 154, 155, 16, 17,
+ 158, -1, 160, 51, 52, 163, 250, -1, 56, -1,
+ 268, 59, 60, -1, -1, -1, 34, 35, -1, -1,
+ -1, 279, 40, 41, 42, 43, 44, 45, -1, -1,
+ 188, -1, -1, 51, 52, -1, 54, 1, 56, 3,
+ 4, 59, 60, 7, 8, 203, 64, -1, 66, -1,
+ -1, -1, -1, -1, 18, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ -1, 35, 36, -1, -1, -1, 40, 41, 42, 43,
+ 44, 45, -1, -1, -1, -1, -1, 51, 52, -1,
+ 54, 1, 56, 3, 4, 59, 60, 7, 8, -1,
+ 64, 65, 66, -1, -1, -1, -1, -1, 18, -1,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, -1, 35, 36, -1, -1, -1,
+ 40, 41, 42, 43, 44, 45, -1, -1, -1, -1,
+ -1, 51, 52, -1, 54, 1, 56, 3, 4, 59,
+ 60, 7, 8, -1, 64, 65, 66, -1, -1, -1,
+ -1, -1, 18, -1, 20, 21, 22, -1, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
+ 36, 11, -1, -1, 40, 41, 42, 43, -1, 45,
+ -1, -1, -1, -1, -1, 51, 52, -1, 54, -1,
+ 56, 9, -1, 59, 60, -1, 14, 9, 64, 65,
+ 66, 1, 14, 3, 4, -1, -1, 7, 8, -1,
+ 10, 51, 52, 53, 54, 55, -1, -1, 58, 37,
+ 38, 39, -1, -1, -1, 37, 38, 39, 46, 11,
+ -1, 49, 50, -1, 46, 35, 48, 49, 50, -1,
+ 40, 41, 42, 43, 44, 45, 12, 13, 66, 61,
+ -1, 51, 52, -1, 54, -1, 56, -1, -1, 59,
+ 60, 61, -1, 3, 4, -1, 66, 7, 8, 51,
+ 52, 53, 54, 55, 40, 41, 58, -1, 18, 45,
+ 20, 21, 22, -1, -1, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, -1, 35, 36, -1, -1, -1,
+ 40, 41, 42, 43, -1, 45, -1, -1, -1, -1,
+ -1, 51, 52, -1, 54, -1, 56, 3, 4, 59,
+ 60, 7, 8, -1, 64, -1, 66, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1, -1, 3,
+ 4, -1, -1, 7, 8, -1, -1, -1, -1, 35,
+ -1, -1, -1, -1, 40, 41, 42, 43, -1, 45,
+ -1, -1, -1, -1, -1, 51, 52, -1, 54, -1,
+ 56, 35, -1, 59, 60, -1, 40, 41, 42, 43,
+ 66, 45, -1, -1, 9, -1, -1, 51, 52, 14,
+ 54, -1, 56, -1, -1, 59, 60, 61, 1, -1,
+ 3, 4, -1, -1, 7, 8, -1, -1, -1, -1,
+ -1, -1, 37, 38, 39, -1, -1, -1, -1, -1,
+ 1, 46, 3, 4, 49, 50, 7, 8, -1, -1,
+ -1, -1, 35, -1, -1, -1, 61, 40, 41, 42,
+ 43, -1, 45, -1, -1, -1, -1, -1, 51, 52,
+ -1, 54, -1, 56, 35, -1, 59, 60, 9, 40,
+ 41, 42, 43, 14, 45, -1, -1, -1, -1, -1,
+ 51, 52, -1, 54, -1, 56, 3, 4, 59, 60,
+ 7, 8, -1, -1, -1, -1, 37, 38, 39, -1,
+ -1, -1, -1, -1, 21, 46, -1, 48, 49, 50,
+ -1, -1, -1, 30, 31, -1, -1, -1, 35, -1,
+ -1, -1, 9, 40, 41, 42, 43, 14, 45, -1,
+ -1, -1, -1, -1, 51, 52, -1, 54, -1, 56,
+ 3, 4, 59, 60, 7, 8, -1, -1, -1, -1,
+ 37, 38, 39, -1, -1, -1, -1, -1, 21, 46,
+ 47, -1, 49, 50, -1, -1, -1, 30, 31, 3,
+ 4, -1, 35, 7, 8, -1, -1, 40, 41, 42,
+ 43, -1, 45, -1, -1, -1, -1, -1, 51, 52,
+ -1, 54, -1, 56, -1, -1, 59, 60, 3, 4,
+ -1, 35, 7, 8, -1, -1, 40, 41, 42, 43,
+ -1, 45, -1, -1, -1, -1, -1, 51, 52, -1,
+ 54, -1, 56, -1, -1, 59, 60, 3, 4, -1,
+ 35, 7, 8, -1, -1, 40, 41, 42, 43, -1,
+ 45, -1, -1, -1, -1, -1, 51, 52, -1, 54,
+ -1, 56, -1, -1, 59, 60, -1, 9, -1, 35,
+ -1, -1, 14, -1, 40, 41, 42, 43, -1, -1,
+ -1, -1, -1, -1, -1, 51, 52, -1, -1, -1,
+ 56, -1, -1, 59, 60, 37, 38, 39, -1, -1,
+ -1, -1, -1, -1, 46, -1, -1, 49, 50
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 44, 68, 96, 97, 0, 44, 69, 1, 3,
+ 4, 7, 8, 16, 17, 34, 35, 40, 41, 42,
+ 43, 45, 51, 52, 54, 56, 59, 60, 70, 71,
+ 75, 77, 79, 97, 104, 108, 109, 110, 112, 60,
+ 62, 76, 111, 112, 112, 112, 60, 60, 56, 60,
+ 109, 112, 109, 77, 109, 110, 112, 1, 103, 104,
+ 64, 66, 72, 81, 96, 113, 117, 72, 78, 9,
+ 14, 37, 38, 39, 46, 48, 49, 50, 106, 107,
+ 109, 11, 51, 52, 53, 54, 55, 58, 12, 13,
+ 40, 41, 45, 105, 102, 103, 104, 103, 3, 4,
+ 42, 43, 73, 74, 49, 98, 102, 102, 104, 1,
+ 48, 61, 115, 119, 115, 97, 80, 97, 5, 104,
+ 4, 104, 104, 104, 104, 104, 35, 109, 109, 109,
+ 109, 109, 109, 13, 104, 115, 63, 60, 109, 115,
+ 115, 104, 97, 37, 1, 104, 1, 18, 20, 21,
+ 22, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 36, 65, 82, 84, 91, 95, 104, 113, 114, 117,
+ 47, 111, 1, 4, 99, 100, 4, 60, 83, 4,
+ 60, 60, 60, 97, 60, 81, 81, 81, 101, 104,
+ 81, 97, 81, 85, 80, 116, 117, 97, 104, 115,
+ 1, 119, 104, 101, 62, 4, 104, 104, 82, 4,
+ 84, 86, 81, 60, 92, 102, 114, 97, 97, 1,
+ 4, 115, 81, 103, 61, 115, 115, 25, 37, 117,
+ 104, 10, 93, 97, 63, 97, 97, 60, 4, 97,
+ 119, 94, 82, 113, 82, 104, 115, 104, 117, 103,
+ 108, 19, 87, 88, 115, 97, 117, 97, 115, 97,
+ 97, 1, 23, 24, 89, 97, 82, 97, 86, 82,
+ 114, 7, 8, 51, 52, 77, 90, 47, 118, 86,
+ 115, 7, 7, 118, 97, 115, 97, 97, 80, 97,
+ 82, 80, 82
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+
+ yyvsp[0] = yylval;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short int *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a look-ahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 172 "awkgram.y"
+ {
+ check_funcs();
+ }
+ break;
+
+ case 4:
+#line 180 "awkgram.y"
+ {
+ begin_or_end_rule = parsing_end_rule = FALSE;
+ yyerrok;
+ }
+ break;
+
+ case 5:
+#line 185 "awkgram.y"
+ {
+ begin_or_end_rule = parsing_end_rule = FALSE;
+ /*
+ * If errors, give up, don't produce an infinite
+ * stream of syntax error messages.
+ */
+ /* yyerrok; */
+ }
+ break;
+
+ case 6:
+#line 197 "awkgram.y"
+ {
+ (yyvsp[-1].nodeval)->rnode = (yyvsp[0].nodeval);
+ }
+ break;
+
+ case 7:
+#line 201 "awkgram.y"
+ {
+ if ((yyvsp[-1].nodeval)->lnode != NULL) {
+ /* pattern rule with non-empty pattern */
+ (yyvsp[-1].nodeval)->rnode = node(NULL, Node_K_print_rec, NULL);
+ } else {
+ /* an error */
+ if (begin_or_end_rule)
+ msg(_("%s blocks must have an action part"),
+ (parsing_end_rule ? "END" : "BEGIN"));
+ else
+ msg(_("each rule must have a pattern or an action part"));
+ errcount++;
+ }
+ }
+ break;
+
+ case 8:
+#line 216 "awkgram.y"
+ {
+ can_return = FALSE;
+ if ((yyvsp[-1].nodeval))
+ func_install((yyvsp[-1].nodeval), (yyvsp[0].nodeval));
+ yyerrok;
+ }
+ break;
+
+ case 9:
+#line 226 "awkgram.y"
+ {
+ (yyval.nodeval) = append_pattern(&expression_value, (NODE *) NULL);
+ }
+ break;
+
+ case 10:
+#line 230 "awkgram.y"
+ {
+ (yyval.nodeval) = append_pattern(&expression_value, (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 11:
+#line 234 "awkgram.y"
+ {
+ NODE *r;
+
+ getnode(r);
+ r->type = Node_line_range;
+ r->condpair = node((yyvsp[-2].nodeval), Node_cond_pair, (yyvsp[0].nodeval));
+ r->triggered = FALSE;
+ (yyval.nodeval) = append_pattern(&expression_value, r);
+ }
+ break;
+
+ case 12:
+#line 244 "awkgram.y"
+ {
+ begin_or_end_rule = TRUE;
+ (yyval.nodeval) = append_pattern(&begin_block, (NODE *) NULL);
+ }
+ break;
+
+ case 13:
+#line 249 "awkgram.y"
+ {
+ begin_or_end_rule = parsing_end_rule = TRUE;
+ (yyval.nodeval) = append_pattern(&end_block, (NODE *) NULL);
+ }
+ break;
+
+ case 14:
+#line 257 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[-3].nodeval); }
+ break;
+
+ case 15:
+#line 262 "awkgram.y"
+ { (yyval.sval) = (yyvsp[0].sval); }
+ break;
+
+ case 16:
+#line 264 "awkgram.y"
+ { (yyval.sval) = (yyvsp[0].sval); }
+ break;
+
+ case 17:
+#line 266 "awkgram.y"
+ {
+ yyerror(_("`%s' is a built-in function, it cannot be redefined"),
+ tokstart);
+ errcount++;
+ (yyval.sval) = builtin_func;
+ /* yyerrok; */
+ }
+ break;
+
+ case 20:
+#line 282 "awkgram.y"
+ {
+ param_counter = 0;
+ }
+ break;
+
+ case 21:
+#line 286 "awkgram.y"
+ {
+ NODE *t;
+
+ t = make_param((yyvsp[-4].sval));
+ t->flags |= FUNC;
+ (yyval.nodeval) = append_right(t, (yyvsp[-2].nodeval));
+ can_return = TRUE;
+ /* check for duplicate parameter names */
+ if (dup_parms((yyval.nodeval)))
+ errcount++;
+ }
+ break;
+
+ case 22:
+#line 305 "awkgram.y"
+ { ++want_regexp; }
+ break;
+
+ case 23:
+#line 307 "awkgram.y"
+ {
+ NODE *n;
+ size_t len = strlen((yyvsp[0].sval));
+
+ if (do_lint) {
+ if (len == 0)
+ lintwarn(_("regexp constant `//' looks like a C++ comment, but is not"));
+ else if (((yyvsp[0].sval))[0] == '*' && ((yyvsp[0].sval))[len-1] == '*')
+ /* possible C comment */
+ lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), tokstart);
+ }
+ getnode(n);
+ n->type = Node_regex;
+ n->re_exp = make_string((yyvsp[0].sval), len);
+ n->re_reg = make_regexp((yyvsp[0].sval), len, FALSE, TRUE);
+ n->re_text = NULL;
+ n->re_flags = CONST;
+ n->re_cnt = 1;
+ (yyval.nodeval) = n;
+ }
+ break;
+
+ case 26:
+#line 336 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 27:
+#line 338 "awkgram.y"
+ {
+ if ((yyvsp[0].nodeval) == NULL)
+ (yyval.nodeval) = (yyvsp[-1].nodeval);
+ else {
+ if (do_lint && isnoeffect((yyvsp[0].nodeval)->type))
+ lintwarn(_("statement may have no effect"));
+ if ((yyvsp[-1].nodeval) == NULL)
+ (yyval.nodeval) = (yyvsp[0].nodeval);
+ else
+ (yyval.nodeval) = append_right(
+ ((yyvsp[-1].nodeval)->type == Node_statement_list ? (yyvsp[-1].nodeval)
+ : node((yyvsp[-1].nodeval), Node_statement_list, (NODE *) NULL)),
+ ((yyvsp[0].nodeval)->type == Node_statement_list ? (yyvsp[0].nodeval)
+ : node((yyvsp[0].nodeval), Node_statement_list, (NODE *) NULL)));
+ }
+ yyerrok;
+ }
+ break;
+
+ case 28:
+#line 356 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 31:
+#line 366 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 32:
+#line 368 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[-1].nodeval); }
+ break;
+
+ case 33:
+#line 370 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 34:
+#line 372 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-6].nodeval), Node_K_switch, (yyvsp[-2].nodeval)); }
+ break;
+
+ case 35:
+#line 374 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_while, (yyvsp[0].nodeval)); }
+ break;
+
+ case 36:
+#line 376 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_K_do, (yyvsp[-5].nodeval)); }
+ break;
+
+ case 37:
+#line 378 "awkgram.y"
+ {
+ /*
+ * Efficiency hack. Recognize the special case of
+ *
+ * for (iggy in foo)
+ * delete foo[iggy]
+ *
+ * and treat it as if it were
+ *
+ * delete foo
+ *
+ * Check that the body is a `delete a[i]' statement,
+ * and that both the loop var and array names match.
+ */
+ if ((yyvsp[0].nodeval) != NULL && (yyvsp[0].nodeval)->type == Node_K_delete && (yyvsp[0].nodeval)->rnode != NULL) {
+ NODE *arr, *sub;
+
+ assert((yyvsp[0].nodeval)->rnode->type == Node_expression_list);
+ arr = (yyvsp[0].nodeval)->lnode; /* array var */
+ sub = (yyvsp[0].nodeval)->rnode->lnode; /* index var */
+
+ if ( (arr->type == Node_var_new
+ || arr->type == Node_var_array
+ || arr->type == Node_param_list)
+ && (sub->type == Node_var_new
+ || sub->type == Node_var
+ || sub->type == Node_param_list)
+ && strcmp((yyvsp[-5].sval), sub->vname) == 0
+ && strcmp((yyvsp[-3].sval), arr->vname) == 0) {
+ (yyvsp[0].nodeval)->type = Node_K_delete_loop;
+ (yyval.nodeval) = (yyvsp[0].nodeval);
+ free((yyvsp[-5].sval)); /* thanks to valgrind for pointing these out */
+ free((yyvsp[-3].sval));
+ }
+ else
+ goto regular_loop;
+ } else {
+ regular_loop:
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_arrayfor,
+ make_for_loop(variable((yyvsp[-5].sval), CAN_FREE, Node_var),
+ (NODE *) NULL, variable((yyvsp[-3].sval), CAN_FREE, Node_var_array)));
+ }
+ }
+ break;
+
+ case 38:
+#line 422 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_for, (NODE *) make_for_loop((yyvsp[-9].nodeval), (yyvsp[-6].nodeval), (yyvsp[-3].nodeval)));
+ }
+ break;
+
+ case 39:
+#line 426 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_for,
+ (NODE *) make_for_loop((yyvsp[-8].nodeval), (NODE *) NULL, (yyvsp[-3].nodeval)));
+ }
+ break;
+
+ case 40:
+#line 432 "awkgram.y"
+ { (yyval.nodeval) = node((NODE *) NULL, Node_K_break, (NODE *) NULL); }
+ break;
+
+ case 41:
+#line 435 "awkgram.y"
+ { (yyval.nodeval) = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); }
+ break;
+
+ case 42:
+#line 437 "awkgram.y"
+ { NODETYPE type;
+
+ if (begin_or_end_rule)
+ yyerror(_("`%s' used in %s action"), "next",
+ (parsing_end_rule ? "END" : "BEGIN"));
+ type = Node_K_next;
+ (yyval.nodeval) = node((NODE *) NULL, type, (NODE *) NULL);
+ }
+ break;
+
+ case 43:
+#line 446 "awkgram.y"
+ {
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`nextfile' is a gawk extension"));
+ }
+ if (do_lint)
+ lintwarn(_("`nextfile' is a gawk extension"));
+ if (begin_or_end_rule) {
+ /* same thing */
+ errcount++;
+ error(_("`%s' used in %s action"), "nextfile",
+ (parsing_end_rule ? "END" : "BEGIN"));
+ }
+ (yyval.nodeval) = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL);
+ }
+ break;
+
+ case 44:
+#line 466 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_K_exit, (NODE *) NULL); }
+ break;
+
+ case 45:
+#line 468 "awkgram.y"
+ {
+ if (! can_return)
+ yyerror(_("`return' used outside function context"));
+ }
+ break;
+
+ case 46:
+#line 473 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[-1].nodeval) == NULL ? Nnull_string : (yyvsp[-1].nodeval),
+ Node_K_return, (NODE *) NULL);
+ }
+ break;
+
+ case 48:
+#line 489 "awkgram.y"
+ { in_print = TRUE; in_parens = 0; }
+ break;
+
+ case 49:
+#line 490 "awkgram.y"
+ {
+ /*
+ * Optimization: plain `print' has no expression list, so $3 is null.
+ * If $3 is an expression list with one element (rnode == null)
+ * and lnode is a field spec for field 0, we have `print $0'.
+ * For both, use Node_K_print_rec, which is faster for these two cases.
+ */
+ if ((yyvsp[-3].nodetypeval) == Node_K_print &&
+ ((yyvsp[-1].nodeval) == NULL
+ || ((yyvsp[-1].nodeval)->type == Node_expression_list
+ && (yyvsp[-1].nodeval)->rnode == NULL
+ && (yyvsp[-1].nodeval)->lnode->type == Node_field_spec
+ && (yyvsp[-1].nodeval)->lnode->lnode->type == Node_val
+ && (yyvsp[-1].nodeval)->lnode->lnode->numbr == 0.0))
+ ) {
+ static int warned = FALSE;
+
+ (yyval.nodeval) = node(NULL, Node_K_print_rec, (yyvsp[0].nodeval));
+
+ if (do_lint && (yyvsp[-1].nodeval) == NULL && begin_or_end_rule && ! warned) {
+ warned = TRUE;
+ lintwarn(
+ _("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
+ }
+ } else {
+ (yyval.nodeval) = node((yyvsp[-1].nodeval), (yyvsp[-3].nodetypeval), (yyvsp[0].nodeval));
+ if ((yyval.nodeval)->type == Node_K_printf)
+ count_args((yyval.nodeval));
+ }
+ }
+ break;
+
+ case 50:
+#line 521 "awkgram.y"
+ { (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_K_delete, (yyvsp[-1].nodeval)); }
+ break;
+
+ case 51:
+#line 523 "awkgram.y"
+ {
+ if (do_lint)
+ lintwarn(_("`delete array' is a gawk extension"));
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`delete array' is a gawk extension"));
+ }
+ (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
+ }
+ break;
+
+ case 52:
+#line 537 "awkgram.y"
+ {
+ /* this is for tawk compatibility. maybe the warnings should always be done. */
+ if (do_lint)
+ lintwarn(_("`delete(array)' is a non-portable tawk extension"));
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`delete(array)' is a non-portable tawk extension"));
+ }
+ (yyval.nodeval) = node(variable((yyvsp[-1].sval), CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
+ }
+ break;
+
+ case 53:
+#line 552 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 54:
+#line 557 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 55:
+#line 559 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 56:
+#line 564 "awkgram.y"
+ {
+ if ((yyvsp[0].nodeval) == NULL) {
+ (yyval.nodeval) = NULL;
+ } else {
+ NODE *dflt = NULL;
+ NODE *head = (yyvsp[0].nodeval);
+ NODE *curr;
+
+ const char **case_values = NULL;
+
+ int maxcount = 128;
+ int case_count = 0;
+ int i;
+
+ emalloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
+ for (curr = (yyvsp[0].nodeval); curr != NULL; curr = curr->rnode) {
+ /* Assure that case statement values are unique. */
+ if (curr->lnode->type == Node_K_case) {
+ char *caseval;
+
+ if (curr->lnode->lnode->type == Node_regex)
+ caseval = curr->lnode->lnode->re_exp->stptr;
+ else
+ caseval = force_string(tree_eval(curr->lnode->lnode))->stptr;
+
+ for (i = 0; i < case_count; i++)
+ if (strcmp(caseval, case_values[i]) == 0)
+ yyerror(_("duplicate case values in switch body: %s"), caseval);
+
+ if (case_count >= maxcount) {
+ maxcount += 128;
+ erealloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
+ }
+ case_values[case_count++] = caseval;
+ } else {
+ /* Otherwise save a pointer to the default node. */
+ if (dflt != NULL)
+ yyerror(_("Duplicate `default' detected in switch body"));
+ dflt = curr;
+ }
+ }
+
+ free(case_values);
+
+ /* Create the switch body. */
+ (yyval.nodeval) = node(head, Node_switch_body, dflt);
+ }
+ }
+ break;
+
+ case 57:
+#line 616 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 58:
+#line 618 "awkgram.y"
+ {
+ if ((yyvsp[0].nodeval) == NULL)
+ (yyval.nodeval) = (yyvsp[-1].nodeval);
+ else {
+ if (do_lint && isnoeffect((yyvsp[0].nodeval)->type))
+ lintwarn(_("statement may have no effect"));
+ if ((yyvsp[-1].nodeval) == NULL)
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_case_list, (NODE *) NULL);
+ else
+ (yyval.nodeval) = append_right(
+ ((yyvsp[-1].nodeval)->type == Node_case_list ? (yyvsp[-1].nodeval) : node((yyvsp[-1].nodeval), Node_case_list, (NODE *) NULL)),
+ ((yyvsp[0].nodeval)->type == Node_case_list ? (yyvsp[0].nodeval) : node((yyvsp[0].nodeval), Node_case_list, (NODE *) NULL))
+ );
+ }
+ yyerrok;
+ }
+ break;
+
+ case 59:
+#line 635 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 60:
+#line 640 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_case, (yyvsp[0].nodeval)); }
+ break;
+
+ case 61:
+#line 642 "awkgram.y"
+ { (yyval.nodeval) = node((NODE *) NULL, Node_K_default, (yyvsp[0].nodeval)); }
+ break;
+
+ case 62:
+#line 647 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 63:
+#line 649 "awkgram.y"
+ {
+ (yyvsp[0].nodeval)->numbr = -(force_number((yyvsp[0].nodeval)));
+ (yyval.nodeval) = (yyvsp[0].nodeval);
+ }
+ break;
+
+ case 64:
+#line 654 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 65:
+#line 656 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 66:
+#line 658 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 70:
+#line 673 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_expression_list, (yyvsp[-1].nodeval)); }
+ break;
+
+ case 71:
+#line 678 "awkgram.y"
+ {
+ in_print = FALSE;
+ in_parens = 0;
+ (yyval.nodeval) = NULL;
+ }
+ break;
+
+ case 72:
+#line 683 "awkgram.y"
+ { in_print = FALSE; in_parens = 0; }
+ break;
+
+ case 73:
+#line 684 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[0].nodeval), (yyvsp[-2].nodetypeval), (NODE *) NULL);
+ if ((yyvsp[-2].nodetypeval) == Node_redirect_twoway
+ && (yyvsp[0].nodeval)->type == Node_K_getline
+ && (yyvsp[0].nodeval)->rnode != NULL
+ && (yyvsp[0].nodeval)->rnode->type == Node_redirect_twoway)
+ yyerror(_("multistage two-way pipelines don't work"));
+ }
+ break;
+
+ case 74:
+#line 696 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_if,
+ node((yyvsp[0].nodeval), Node_if_branches, (NODE *) NULL));
+ }
+ break;
+
+ case 75:
+#line 702 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-6].nodeval), Node_K_if,
+ node((yyvsp[-3].nodeval), Node_if_branches, (yyvsp[0].nodeval))); }
+ break;
+
+ case 80:
+#line 718 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 81:
+#line 720 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_redirect_input, (NODE *) NULL); }
+ break;
+
+ case 82:
+#line 725 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 83:
+#line 727 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 84:
+#line 732 "awkgram.y"
+ { (yyval.nodeval) = make_param((yyvsp[0].sval)); }
+ break;
+
+ case 85:
+#line 734 "awkgram.y"
+ { (yyval.nodeval) = append_right((yyvsp[-2].nodeval), make_param((yyvsp[0].sval))); yyerrok; }
+ break;
+
+ case 86:
+#line 736 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 87:
+#line 738 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 88:
+#line 740 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 89:
+#line 746 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 90:
+#line 748 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 91:
+#line 753 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 92:
+#line 755 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 93:
+#line 760 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_expression_list, (NODE *) NULL); }
+ break;
+
+ case 94:
+#line 762 "awkgram.y"
+ {
+ (yyval.nodeval) = append_right((yyvsp[-2].nodeval),
+ node((yyvsp[0].nodeval), Node_expression_list, (NODE *) NULL));
+ yyerrok;
+ }
+ break;
+
+ case 95:
+#line 768 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 96:
+#line 770 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 97:
+#line 772 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 98:
+#line 774 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 99:
+#line 779 "awkgram.y"
+ {
+ if (do_lint && (yyvsp[0].nodeval)->type == Node_regex)
+ lintwarn(_("regular expression on right of assignment"));
+ /*
+ * Optimization of `x = x y'. Can save lots of time
+ * if done a lot.
+ */
+ if (( (yyvsp[-2].nodeval)->type == Node_var
+ || (yyvsp[-2].nodeval)->type == Node_var_new
+ || (yyvsp[-2].nodeval)->type == Node_param_list)
+ && (yyvsp[-1].nodetypeval) == Node_assign
+ && (yyvsp[0].nodeval)->type == Node_concat
+ && (yyvsp[0].nodeval)->lnode == (yyvsp[-2].nodeval)) {
+ (yyvsp[0].nodeval)->type = Node_assign_concat; /* Just change the type */
+ (yyval.nodeval) = (yyvsp[0].nodeval); /* And use it directly */
+ } else
+ (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 100:
+#line 798 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_and, (yyvsp[0].nodeval)); }
+ break;
+
+ case 101:
+#line 800 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_or, (yyvsp[0].nodeval)); }
+ break;
+
+ case 102:
+#line 802 "awkgram.y"
+ {
+ if ((yyvsp[-2].nodeval)->type == Node_regex)
+ warning(_("regular expression on left of `~' or `!~' operator"));
+ (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), mk_rexp((yyvsp[0].nodeval)));
+ }
+ break;
+
+ case 103:
+#line 808 "awkgram.y"
+ { (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_in_array, (yyvsp[-2].nodeval)); }
+ break;
+
+ case 104:
+#line 810 "awkgram.y"
+ {
+ if (do_lint && (yyvsp[0].nodeval)->type == Node_regex)
+ lintwarn(_("regular expression on right of comparison"));
+ (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 105:
+#line 816 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-4].nodeval), Node_cond_exp, node((yyvsp[-2].nodeval), Node_if_branches, (yyvsp[0].nodeval)));}
+ break;
+
+ case 106:
+#line 818 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 107:
+#line 823 "awkgram.y"
+ { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
+ break;
+
+ case 108:
+#line 825 "awkgram.y"
+ { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
+ break;
+
+ case 109:
+#line 827 "awkgram.y"
+ { (yyval.nodetypeval) = Node_assign_quotient; }
+ break;
+
+ case 110:
+#line 832 "awkgram.y"
+ { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
+ break;
+
+ case 111:
+#line 834 "awkgram.y"
+ { (yyval.nodetypeval) = Node_less; }
+ break;
+
+ case 113:
+#line 839 "awkgram.y"
+ { (yyval.nodetypeval) = Node_greater; }
+ break;
+
+ case 114:
+#line 844 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 115:
+#line 846 "awkgram.y"
+ {
+ (yyval.nodeval) = node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_nomatch,
+ (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 116:
+#line 854 "awkgram.y"
+ { (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_in_array, (yyvsp[-3].nodeval)); }
+ break;
+
+ case 117:
+#line 856 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 118:
+#line 858 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_concat, (yyvsp[0].nodeval)); }
+ break;
+
+ case 120:
+#line 865 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_exp, (yyvsp[0].nodeval)); }
+ break;
+
+ case 121:
+#line 867 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_times, (yyvsp[0].nodeval)); }
+ break;
+
+ case 122:
+#line 869 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_quotient, (yyvsp[0].nodeval)); }
+ break;
+
+ case 123:
+#line 871 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_mod, (yyvsp[0].nodeval)); }
+ break;
+
+ case 124:
+#line 873 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_plus, (yyvsp[0].nodeval)); }
+ break;
+
+ case 125:
+#line 875 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_minus, (yyvsp[0].nodeval)); }
+ break;
+
+ case 126:
+#line 877 "awkgram.y"
+ {
+ if (do_lint && parsing_end_rule && (yyvsp[0].nodeval) == NULL)
+ lintwarn(_("non-redirected `getline' undefined inside END action"));
+ (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_K_getline, (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 127:
+#line 883 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_getline,
+ node((yyvsp[-3].nodeval), (yyvsp[-2].nodetypeval), (NODE *) NULL));
+ }
+ break;
+
+ case 128:
+#line 888 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_postincrement, (NODE *) NULL); }
+ break;
+
+ case 129:
+#line 890 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_postdecrement, (NODE *) NULL); }
+ break;
+
+ case 130:
+#line 895 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_not, (NODE *) NULL); }
+ break;
+
+ case 131:
+#line 897 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[-1].nodeval); }
+ break;
+
+ case 132:
+#line 900 "awkgram.y"
+ { (yyval.nodeval) = snode((yyvsp[-1].nodeval), Node_builtin, (int) (yyvsp[-3].lval)); }
+ break;
+
+ case 133:
+#line 902 "awkgram.y"
+ { (yyval.nodeval) = snode((yyvsp[-1].nodeval), Node_builtin, (int) (yyvsp[-3].lval)); }
+ break;
+
+ case 134:
+#line 904 "awkgram.y"
+ {
+ if (do_lint)
+ lintwarn(_("call of `length' without parentheses is not portable"));
+ (yyval.nodeval) = snode((NODE *) NULL, Node_builtin, (int) (yyvsp[0].lval));
+ if (do_posix)
+ warning(_("call of `length' without parentheses is deprecated by POSIX"));
+ }
+ break;
+
+ case 135:
+#line 912 "awkgram.y"
+ {
+ (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_func_call, make_string((yyvsp[-3].sval), strlen((yyvsp[-3].sval))));
+ (yyval.nodeval)->funcbody = NULL;
+ func_use((yyvsp[-3].sval), FUNC_USE);
+ param_sanity((yyvsp[-1].nodeval));
+ free((yyvsp[-3].sval));
+ }
+ break;
+
+ case 137:
+#line 921 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_preincrement, (NODE *) NULL); }
+ break;
+
+ case 138:
+#line 923 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_predecrement, (NODE *) NULL); }
+ break;
+
+ case 139:
+#line 925 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 140:
+#line 927 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 141:
+#line 930 "awkgram.y"
+ {
+ if ((yyvsp[0].nodeval)->type == Node_val && ((yyvsp[0].nodeval)->flags & (STRCUR|STRING)) == 0) {
+ (yyvsp[0].nodeval)->numbr = -(force_number((yyvsp[0].nodeval)));
+ (yyval.nodeval) = (yyvsp[0].nodeval);
+ } else
+ (yyval.nodeval) = node((yyvsp[0].nodeval), Node_unary_minus, (NODE *) NULL);
+ }
+ break;
+
+ case 142:
+#line 938 "awkgram.y"
+ {
+ /*
+ * was: $$ = $2
+ * POSIX semantics: force a conversion to numeric type
+ */
+ (yyval.nodeval) = node (make_number(0.0), Node_plus, (yyvsp[0].nodeval));
+ }
+ break;
+
+ case 143:
+#line 949 "awkgram.y"
+ { (yyval.nodeval) = NULL; }
+ break;
+
+ case 144:
+#line 951 "awkgram.y"
+ { (yyval.nodeval) = (yyvsp[0].nodeval); }
+ break;
+
+ case 145:
+#line 956 "awkgram.y"
+ { (yyval.nodeval) = variable((yyvsp[0].sval), CAN_FREE, Node_var_new); }
+ break;
+
+ case 146:
+#line 958 "awkgram.y"
+ {
+ NODE *n;
+
+ if ((n = lookup((yyvsp[-3].sval))) != NULL && ! isarray(n))
+ yyerror(_("use of non-array as array"));
+ else if ((yyvsp[-1].nodeval) == NULL) {
+ fatal(_("invalid subscript expression"));
+ } else if ((yyvsp[-1].nodeval)->rnode == NULL) {
+ (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_subscript, (yyvsp[-1].nodeval)->lnode);
+ freenode((yyvsp[-1].nodeval));
+ } else
+ (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_subscript, (yyvsp[-1].nodeval));
+ }
+ break;
+
+ case 147:
+#line 972 "awkgram.y"
+ { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_field_spec, (NODE *) NULL); }
+ break;
+
+ case 149:
+#line 986 "awkgram.y"
+ { yyerrok; }
+ break;
+
+ case 150:
+#line 990 "awkgram.y"
+ { yyerrok; }
+ break;
+
+ case 153:
+#line 999 "awkgram.y"
+ { yyerrok; }
+ break;
+
+ case 154:
+#line 1003 "awkgram.y"
+ { yyerrok; }
+ break;
+
+ case 155:
+#line 1006 "awkgram.y"
+ { yyerrok; }
+ break;
+
+
+ }
+
+/* Line 1037 of yacc.c. */
+#line 2661 "y.tab.c"
+\f
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
+ char *yymsg;
+ int yyx;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yyp = yystpcpy (yyp, yyprefix);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yyprefix = " or ";
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ yydestruct ("Error: popping",
+ yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ yydestruct ("Error: discarding", yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yydestruct ("Error: discarding lookahead",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 1009 "awkgram.y"
+
+
+struct token {
+ const char *operator; /* text to match */
+ NODETYPE value; /* node type */
+ int class; /* lexical class */
+ unsigned flags; /* # of args. allowed and compatability */
+# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */
+# define A(n) (1<<(n))
+# define VERSION_MASK 0xFF00 /* old awk is zero */
+# define NOT_OLD 0x0100 /* feature not in old awk */
+# define NOT_POSIX 0x0200 /* feature not in POSIX */
+# define GAWKX 0x0400 /* gawk extension */
+# define RESX 0x0800 /* Bell Labs Research extension */
+ NODE *(*ptr) P((NODE *)); /* function that implements this keyword */
+};
+
+/* Tokentab is sorted ascii ascending order, so it can be binary searched. */
+/* Function pointers come from declarations in awk.h. */
+
+static const struct token tokentab[] = {
+{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0},
+{"END", Node_illegal, LEX_END, 0, 0},
+#ifdef ARRAYDEBUG
+{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
+#endif
+{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
+{"asort", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asort},
+{"asorti", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asorti},
+{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
+{"bindtextdomain", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
+{"break", Node_K_break, LEX_BREAK, 0, 0},
+#ifdef ALLOW_SWITCH
+{"case", Node_K_case, LEX_CASE, GAWKX, 0},
+#endif
+{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
+{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
+{"continue", Node_K_continue, LEX_CONTINUE, 0, 0},
+{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
+{"dcgettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
+{"dcngettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
+#ifdef ALLOW_SWITCH
+{"default", Node_K_default, LEX_DEFAULT, GAWKX, 0},
+#endif
+{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0},
+{"do", Node_K_do, LEX_DO, NOT_OLD, 0},
+{"else", Node_illegal, LEX_ELSE, 0, 0},
+{"exit", Node_K_exit, LEX_EXIT, 0, 0},
+{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp},
+{"extension", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
+{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
+{"for", Node_K_for, LEX_FOR, 0, 0},
+{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
+{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0},
+{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub},
+{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0},
+{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub},
+{"if", Node_K_if, LEX_IF, 0, 0},
+{"in", Node_illegal, LEX_IN, 0, 0},
+{"index", Node_builtin, LEX_BUILTIN, A(2), do_index},
+{"int", Node_builtin, LEX_BUILTIN, A(1), do_int},
+{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length},
+{"log", Node_builtin, LEX_BUILTIN, A(1), do_log},
+{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
+{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
+{"mktime", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
+{"next", Node_K_next, LEX_NEXT, 0, 0},
+{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
+{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
+{"print", Node_K_print, LEX_PRINT, 0, 0},
+{"printf", Node_K_printf, LEX_PRINTF, 0, 0},
+{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
+{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0},
+{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
+{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
+{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split},
+{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf},
+{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt},
+{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
+#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
+{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
+#endif
+{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime},
+{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
+{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub},
+{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
+#ifdef ALLOW_SWITCH
+{"switch", Node_K_switch, LEX_SWITCH, GAWKX, 0},
+#endif
+{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
+{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
+{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
+{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
+{"while", Node_K_while, LEX_WHILE, 0, 0},
+{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
+};
+
+#ifdef MBS_SUPPORT
+/* Variable containing the current shift state. */
+static mbstate_t cur_mbstate;
+/* Ring buffer containing current characters. */
+#define MAX_CHAR_IN_RING_BUFFER 8
+#define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX)
+static char cur_char_ring[RING_BUFFER_SIZE];
+/* Index for ring buffers. */
+static int cur_ring_idx;
+/* This macro means that last nextc() return a singlebyte character
+ or 1st byte of a multibyte character. */
+#define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1)
+#else /* MBS_SUPPORT */
+/* a dummy */
+#define nextc_is_1stbyte 1
+#endif /* MBS_SUPPORT */
+
+/* getfname --- return name of a builtin function (for pretty printing) */
+
+const char *
+getfname(register NODE *(*fptr)(NODE *))
+{
+ register int i, j;
+
+ j = sizeof(tokentab) / sizeof(tokentab[0]);
+ /* linear search, no other way to do it */
+ for (i = 0; i < j; i++)
+ if (tokentab[i].ptr == fptr)
+ return tokentab[i].operator;
+
+ return NULL;
+}
+
+/* yyerror --- print a syntax error message, show where */
+
+/*
+ * Function identifier purposely indented to avoid mangling
+ * by ansi2knr. Sigh.
+ */
+
+static void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ yyerror(const char *m, ...)
+#else
+/* VARARGS0 */
+ yyerror(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+ const char *mesg = NULL;
+ register char *bp, *cp;
+ char *scan;
+ char *buf;
+ int count;
+ static char end_of_file_line[] = "(END OF FILE)";
+ char save;
+
+ errcount++;
+ /* Find the current line in the input file */
+ if (lexptr && lexeme) {
+ if (thisline == NULL) {
+ cp = lexeme;
+ if (*cp == '\n') {
+ cp--;
+ mesg = _("unexpected newline or end of string");
+ }
+ for (; cp != lexptr_begin && *cp != '\n'; --cp)
+ continue;
+ if (*cp == '\n')
+ cp++;
+ thisline = cp;
+ }
+ /* NL isn't guaranteed */
+ bp = lexeme;
+ while (bp < lexend && *bp && *bp != '\n')
+ bp++;
+ } else {
+ thisline = end_of_file_line;
+ bp = thisline + strlen(thisline);
+ }
+
+ /*
+ * Saving and restoring *bp keeps valgrind happy,
+ * since the guts of glibc uses strlen, even though
+ * we're passing an explict precision. Sigh.
+ *
+ * 8/2003: We may not need this anymore.
+ */
+ save = *bp;
+ *bp = '\0';
+
+ msg("%.*s", (int) (bp - thisline), thisline);
+
+ *bp = save;
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, m);
+ if (mesg == NULL)
+ mesg = m;
+#else
+ va_start(args);
+ if (mesg == NULL)
+ mesg = va_arg(args, char *);
+#endif
+ count = (bp - thisline) + strlen(mesg) + 2 + 1;
+ emalloc(buf, char *, count, "yyerror");
+
+ bp = buf;
+
+ if (lexptr != NULL) {
+ scan = thisline;
+ while (scan < lexeme)
+ if (*scan++ == '\t')
+ *bp++ = '\t';
+ else
+ *bp++ = ' ';
+ *bp++ = '^';
+ *bp++ = ' ';
+ }
+ strcpy(bp, mesg);
+ err("", buf, args);
+ va_end(args);
+ free(buf);
+}
+
+/* get_src_buf --- read the next buffer of source program */
+
+static char *
+get_src_buf()
+{
+ static int samefile = FALSE;
+ static int nextfile = 0;
+ static char *buf = NULL;
+ static size_t buflen = 0;
+ static int fd;
+
+ int n;
+ register char *scan;
+ int newfile;
+ struct stat sbuf;
+ int readcount = 0;
+ int l;
+ char *readloc;
+
+again:
+ newfile = FALSE;
+ if (nextfile > numfiles)
+ return NULL;
+
+ if (srcfiles[nextfile].stype == CMDLINE) {
+ if ((l = strlen(srcfiles[nextfile].val)) == 0) {
+ /*
+ * Yet Another Special case:
+ * gawk '' /path/name
+ * Sigh.
+ */
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("empty program text on command line"));
+ }
+ ++nextfile;
+ goto again;
+ }
+ if (srcfiles[nextfile].val[l-1] == '\n') {
+ /* has terminating newline, can use it directly */
+ sourceline = 1;
+ lexptr = lexptr_begin = srcfiles[nextfile].val;
+ /* fall through to pointer adjustment and return, below */
+ } else {
+ /* copy it into static buffer */
+
+ /* make sure buffer exists and has room */
+ if (buflen == 0) {
+ emalloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } else if (l+2 > buflen) {
+ erealloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } /* else
+ buffer has room, just use it */
+
+ /* copy in data */
+ memcpy(buf, srcfiles[nextfile].val, l);
+ buf[l] = '\n';
+ buf[++l] = '\0';
+
+ /* set vars and return */
+ lexptr = lexptr_begin = buf;
+ }
+ lexend = lexptr + l;
+ nextfile++; /* for next entry to this routine */
+ return lexptr;
+ }
+
+ if (! samefile) {
+ source = srcfiles[nextfile].val;
+ if (source == NULL) { /* read all the source files, all done */
+ if (buf != NULL) {
+ free(buf);
+ buf = NULL;
+ }
+ buflen = 0;
+ return lexeme = lexptr = lexptr_begin = NULL;
+ }
+ fd = pathopen(source);
+ if (fd <= INVALID_HANDLE) {
+ char *in;
+
+ /* suppress file name and line no. in error mesg */
+ in = source;
+ source = NULL;
+ fatal(_("can't open source file `%s' for reading (%s)"),
+ in, strerror(errno));
+ }
+ l = optimal_bufsize(fd, & sbuf);
+ /*
+ * Make sure that something silly like
+ * AWKBUFSIZE=8 make check
+ * works ok.
+ */
+#define A_DECENT_BUFFER_SIZE 128
+ if (l < A_DECENT_BUFFER_SIZE)
+ l = A_DECENT_BUFFER_SIZE;
+#undef A_DECENT_BUFFER_SIZE
+
+ newfile = TRUE;
+
+ /* make sure buffer exists and has room */
+ if (buflen == 0) {
+ emalloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } else if (l+2 > buflen) {
+ erealloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } /* else
+ buffer has room, just use it */
+
+ readcount = l;
+ readloc = lexeme = lexptr = lexptr_begin = buf;
+ samefile = TRUE;
+ sourceline = 1;
+ } else {
+ /*
+ * In same file, ran off edge of buffer.
+ * Shift current line down to front, adjust
+ * pointers and fill in the rest of the buffer.
+ */
+
+ int lexeme_offset = lexeme - lexptr_begin;
+ int lexptr_offset = lexptr - lexptr_begin;
+ int lexend_offset = lexend - lexptr_begin;
+
+ /* find beginning of current line */
+ for (scan = lexeme; scan >= lexptr_begin; scan--) {
+ if (*scan == '\n') {
+ scan++;
+ break;
+ }
+ }
+
+ if (scan <= buf) {
+ /* have to grow the buffer */
+ buflen *= 2;
+ erealloc(buf, char *, buflen, "get_src_buf");
+ } else {
+ /* shift things down */
+ memmove(buf, scan, lexend - scan);
+ /*
+ * make offsets relative to start of line,
+ * not start of buffer.
+ */
+ lexend_offset = lexend - scan;
+ lexeme_offset = lexeme - scan;
+ lexptr_offset = lexptr - scan;
+ }
+
+ /* adjust pointers */
+ lexeme = buf + lexeme_offset;
+ lexptr = buf + lexptr_offset;
+ lexend = buf + lexend_offset;
+ lexptr_begin = buf;
+ readcount = buflen - (lexend - buf);
+ readloc = lexend;
+ }
+
+ /* add more data to buffer */
+ n = read(fd, readloc, readcount);
+ if (n == -1)
+ fatal(_("can't read sourcefile `%s' (%s)"),
+ source, strerror(errno));
+ if (n == 0) {
+ if (newfile) {
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("source file `%s' is empty"), source);
+ }
+ }
+ if (fd != fileno(stdin)) /* safety */
+ close(fd);
+ samefile = FALSE;
+ nextfile++;
+ goto again;
+ }
+ lexend = lexptr + n;
+ return lexptr;
+}
+
+/* tokadd --- add a character to the token buffer */
+
+#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok)
+
+/* tokexpand --- grow the token buffer */
+
+char *
+tokexpand()
+{
+ static int toksize = 60;
+ int tokoffset;
+
+ tokoffset = tok - tokstart;
+ toksize *= 2;
+ if (tokstart != NULL)
+ erealloc(tokstart, char *, toksize, "tokexpand");
+ else
+ emalloc(tokstart, char *, toksize, "tokexpand");
+ tokend = tokstart + toksize;
+ tok = tokstart + tokoffset;
+ return tok;
+}
+
+/* nextc --- get the next input character */
+
+#ifdef MBS_SUPPORT
+
+static int
+nextc(void)
+{
+ if (gawk_mb_cur_max > 1) {
+ if (!lexptr || lexptr >= lexend) {
+ if (! get_src_buf())
+ return EOF;
+ }
+
+ /* Update the buffer index. */
+ cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 :
+ cur_ring_idx + 1;
+
+ /* Did we already check the current character? */
+ if (cur_char_ring[cur_ring_idx] == 0) {
+ /* No, we need to check the next character on the buffer. */
+ int idx, work_ring_idx = cur_ring_idx;
+ mbstate_t tmp_state;
+ size_t mbclen;
+
+ for (idx = 0 ; lexptr + idx < lexend ; idx++) {
+ tmp_state = cur_mbstate;
+ mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
+
+ if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) {
+ /* It is a singlebyte character, non-complete multibyte
+ character or EOF. We treat it as a singlebyte
+ character. */
+ cur_char_ring[work_ring_idx] = 1;
+ break;
+ } else if (mbclen == (size_t)-2) {
+ /* It is not a complete multibyte character. */
+ cur_char_ring[work_ring_idx] = idx + 1;
+ } else {
+ /* mbclen > 1 */
+ cur_char_ring[work_ring_idx] = mbclen;
+ break;
+ }
+ work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
+ 0 : work_ring_idx + 1;
+ }
+ cur_mbstate = tmp_state;
+
+ /* Put a mark on the position on which we write next character. */
+ work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
+ 0 : work_ring_idx + 1;
+ cur_char_ring[work_ring_idx] = 0;
+ }
+
+ return (int) (unsigned char) *lexptr++;
+ }
+ else {
+ int c;
+
+ if (lexptr && lexptr < lexend)
+ c = (int) (unsigned char) *lexptr++;
+ else if (get_src_buf())
+ c = (int) (unsigned char) *lexptr++;
+ else
+ c = EOF;
+
+ return c;
+ }
+}
+
+#else /* MBS_SUPPORT */
+
+#if GAWKDEBUG
+int
+nextc(void)
+{
+ int c;
+
+ if (lexptr && lexptr < lexend)
+ c = (int) (unsigned char) *lexptr++;
+ else if (get_src_buf())
+ c = (int) (unsigned char) *lexptr++;
+ else
+ c = EOF;
+
+ return c;
+}
+#else
+#define nextc() ((lexptr && lexptr < lexend) ? \
+ ((int) (unsigned char) *lexptr++) : \
+ (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \
+ )
+#endif
+
+#endif /* MBS_SUPPORT */
+
+/* pushback --- push a character back on the input */
+
+static inline void
+pushback(void)
+{
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1)
+ cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
+ cur_ring_idx - 1;
+#endif
+ (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
+}
+
+
+/* allow_newline --- allow newline after &&, ||, ? and : */
+
+static void
+allow_newline(void)
+{
+ int c;
+
+ for (;;) {
+ c = nextc();
+ if (c == EOF)
+ break;
+ if (c == '#') {
+ while ((c = nextc()) != '\n' && c != EOF)
+ continue;
+ if (c == EOF)
+ break;
+ }
+ if (c == '\n')
+ sourceline++;
+ if (! ISSPACE(c)) {
+ pushback();
+ break;
+ }
+ }
+}
+
+/* yylex --- Read the input and turn it into tokens. */
+
+static int
+yylex(void)
+{
+ register int c;
+ int seen_e = FALSE; /* These are for numbers */
+ int seen_point = FALSE;
+ int esc_seen; /* for literal strings */
+ int mid;
+ static int did_newline = FALSE;
+ char *tokkey;
+ static int lasttok = 0, eof_warned = FALSE;
+ int inhex = FALSE;
+ int intlstr = FALSE;
+
+ if (nextc() == EOF) {
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+ }
+ pushback();
+#if defined OS2 || defined __EMX__
+ /*
+ * added for OS/2's extproc feature of cmd.exe
+ * (like #! in BSD sh)
+ */
+ if (strncasecmp(lexptr, "extproc ", 8) == 0) {
+ while (*lexptr && *lexptr != '\n')
+ lexptr++;
+ }
+#endif
+ lexeme = lexptr;
+ thisline = NULL;
+ if (want_regexp) {
+ int in_brack = 0; /* count brackets, [[:alnum:]] allowed */
+ /*
+ * Counting brackets is non-trivial. [[] is ok,
+ * and so is [\]], with a point being that /[/]/ as a regexp
+ * constant has to work.
+ *
+ * Do not count [ or ] if either one is preceded by a \.
+ * A `[' should be counted if
+ * a) it is the first one so far (in_brack == 0)
+ * b) it is the `[' in `[:'
+ * A ']' should be counted if not preceded by a \, since
+ * it is either closing `:]' or just a plain list.
+ * According to POSIX, []] is how you put a ] into a set.
+ * Try to handle that too.
+ *
+ * The code for \ handles \[ and \].
+ */
+
+ want_regexp = FALSE;
+ tok = tokstart;
+ for (;;) {
+ c = nextc();
+
+ if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
+ case '[':
+ /* one day check for `.' and `=' too */
+ if (nextc() == ':' || in_brack == 0)
+ in_brack++;
+ pushback();
+ break;
+ case ']':
+ if (tokstart[0] == '['
+ && (tok == tokstart + 1
+ || (tok == tokstart + 2
+ && tokstart[1] == '^')))
+ /* do nothing */;
+ else
+ in_brack--;
+ break;
+ case '\\':
+ if ((c = nextc()) == EOF) {
+ yyerror(_("unterminated regexp ends with `\\' at end of file"));
+ goto end_regexp; /* kludge */
+ } else if (c == '\n') {
+ sourceline++;
+ continue;
+ } else {
+ tokadd('\\');
+ tokadd(c);
+ continue;
+ }
+ break;
+ case '/': /* end of the regexp */
+ if (in_brack > 0)
+ break;
+end_regexp:
+ tokadd('\0');
+ yylval.sval = tokstart;
+ if (do_lint) {
+ int peek = nextc();
+
+ pushback();
+ if (peek == 'i' || peek == 's') {
+ if (source)
+ lintwarn(
+ _("%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"),
+ source, sourceline, peek);
+ else
+ lintwarn(
+ _("tawk regex modifier `/.../%c' doesn't work in gawk"),
+ peek);
+ }
+ }
+ return lasttok = REGEXP;
+ case '\n':
+ pushback();
+ yyerror(_("unterminated regexp"));
+ goto end_regexp; /* kludge */
+ case EOF:
+ yyerror(_("unterminated regexp at end of file"));
+ goto end_regexp; /* kludge */
+ }
+ tokadd(c);
+ }
+ }
+retry:
+
+ /* skipping \r is a hack, but windows is just too pervasive. sigh. */
+ while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ continue;
+
+ lexeme = lexptr ? lexptr - 1 : lexptr;
+ thisline = NULL;
+ tok = tokstart;
+ yylval.nodetypeval = Node_illegal;
+
+ if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
+ case EOF:
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+
+ case '\n':
+ sourceline++;
+ return lasttok = NEWLINE;
+
+ case '#': /* it's a comment */
+ while ((c = nextc()) != '\n') {
+ if (c == EOF) {
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(
+ _("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+ }
+ }
+ sourceline++;
+ return lasttok = NEWLINE;
+
+ case '\\':
+#ifdef RELAXED_CONTINUATION
+ /*
+ * This code puports to allow comments and/or whitespace
+ * after the `\' at the end of a line used for continuation.
+ * Use it at your own risk. We think it's a bad idea, which
+ * is why it's not on by default.
+ */
+ if (! do_traditional) {
+ /* strip trailing white-space and/or comment */
+ while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ continue;
+ if (c == '#') {
+ if (do_lint)
+ lintwarn(
+ _("use of `\\ #...' line continuation is not portable"));
+ while ((c = nextc()) != '\n')
+ if (c == EOF)
+ break;
+ }
+ pushback();
+ }
+#endif /* RELAXED_CONTINUATION */
+ if (nextc() == '\n') {
+ sourceline++;
+ goto retry;
+ } else {
+ yyerror(_("backslash not last character on line"));
+ exit(1);
+ }
+ break;
+
+ case ':':
+ case '?':
+ if (! do_posix)
+ allow_newline();
+ return lasttok = c;
+
+ /*
+ * in_parens is undefined unless we are parsing a print
+ * statement (in_print), but why bother with a check?
+ */
+ case ')':
+ in_parens--;
+ return lasttok = c;
+
+ case '(':
+ in_parens++;
+ /* FALL THROUGH */
+ case '$':
+ case ';':
+ case '{':
+ case ',':
+ case '[':
+ case ']':
+ return lasttok = c;
+
+ case '*':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_times;
+ return lasttok = ASSIGNOP;
+ } else if (do_posix) {
+ pushback();
+ return lasttok = '*';
+ } else if (c == '*') {
+ /* make ** and **= aliases for ^ and ^= */
+ static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+
+ if (nextc() == '=') {
+ if (! did_warn_assgn) {
+ did_warn_assgn = TRUE;
+ if (do_lint)
+ lintwarn(_("POSIX does not allow operator `**='"));
+ if (do_lint_old)
+ warning(_("old awk does not support operator `**='"));
+ }
+ yylval.nodetypeval = Node_assign_exp;
+ return ASSIGNOP;
+ } else {
+ pushback();
+ if (! did_warn_op) {
+ did_warn_op = TRUE;
+ if (do_lint)
+ lintwarn(_("POSIX does not allow operator `**'"));
+ if (do_lint_old)
+ warning(_("old awk does not support operator `**'"));
+ }
+ return lasttok = '^';
+ }
+ }
+ pushback();
+ return lasttok = '*';
+
+ case '/':
+ if (nextc() == '=') {
+ pushback();
+ return lasttok = SLASH_BEFORE_EQUAL;
+ }
+ pushback();
+ return lasttok = '/';
+
+ case '%':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_assign_mod;
+ return lasttok = ASSIGNOP;
+ }
+ pushback();
+ return lasttok = '%';
+
+ case '^':
+ {
+ static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+
+ if (nextc() == '=') {
+ if (do_lint_old && ! did_warn_assgn) {
+ did_warn_assgn = TRUE;
+ warning(_("operator `^=' is not supported in old awk"));
+ }
+ yylval.nodetypeval = Node_assign_exp;
+ return lasttok = ASSIGNOP;
+ }
+ pushback();
+ if (do_lint_old && ! did_warn_op) {
+ did_warn_op = TRUE;
+ warning(_("operator `^' is not supported in old awk"));
+ }
+ return lasttok = '^';
+ }
+
+ case '+':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_plus;
+ return lasttok = ASSIGNOP;
+ }
+ if (c == '+')
+ return lasttok = INCREMENT;
+ pushback();
+ return lasttok = '+';
+
+ case '!':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_notequal;
+ return lasttok = RELOP;
+ }
+ if (c == '~') {
+ yylval.nodetypeval = Node_nomatch;
+ return lasttok = MATCHOP;
+ }
+ pushback();
+ return lasttok = '!';
+
+ case '<':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_leq;
+ return lasttok = RELOP;
+ }
+ yylval.nodetypeval = Node_less;
+ pushback();
+ return lasttok = '<';
+
+ case '=':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_equal;
+ return lasttok = RELOP;
+ }
+ yylval.nodetypeval = Node_assign;
+ pushback();
+ return lasttok = ASSIGN;
+
+ case '>':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_geq;
+ return lasttok = RELOP;
+ } else if (c == '>') {
+ yylval.nodetypeval = Node_redirect_append;
+ return lasttok = IO_OUT;
+ }
+ pushback();
+ if (in_print && in_parens == 0) {
+ yylval.nodetypeval = Node_redirect_output;
+ return lasttok = IO_OUT;
+ }
+ yylval.nodetypeval = Node_greater;
+ return lasttok = '>';
+
+ case '~':
+ yylval.nodetypeval = Node_match;
+ return lasttok = MATCHOP;
+
+ case '}':
+ /*
+ * Added did newline stuff. Easier than
+ * hacking the grammar.
+ */
+ if (did_newline) {
+ did_newline = FALSE;
+ return lasttok = c;
+ }
+ did_newline++;
+ --lexptr; /* pick up } next time */
+ return lasttok = NEWLINE;
+
+ case '"':
+ string:
+ esc_seen = FALSE;
+ while ((c = nextc()) != '"') {
+ if (c == '\n') {
+ pushback();
+ yyerror(_("unterminated string"));
+ exit(1);
+ }
+ if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
+ c == '\\') {
+ c = nextc();
+ if (c == '\n') {
+ sourceline++;
+ continue;
+ }
+ esc_seen = TRUE;
+ tokadd('\\');
+ }
+ if (c == EOF) {
+ pushback();
+ yyerror(_("unterminated string"));
+ exit(1);
+ }
+ tokadd(c);
+ }
+ yylval.nodeval = make_str_node(tokstart,
+ tok - tokstart, esc_seen ? SCAN : 0);
+ yylval.nodeval->flags |= PERM;
+ if (intlstr) {
+ yylval.nodeval->flags |= INTLSTR;
+ intlstr = FALSE;
+ if (do_intl)
+ dumpintlstr(yylval.nodeval->stptr,
+ yylval.nodeval->stlen);
+ }
+ return lasttok = YSTRING;
+
+ case '-':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_minus;
+ return lasttok = ASSIGNOP;
+ }
+ if (c == '-')
+ return lasttok = DECREMENT;
+ pushback();
+ return lasttok = '-';
+
+ case '.':
+ c = nextc();
+ pushback();
+ if (! ISDIGIT(c))
+ return lasttok = '.';
+ else
+ c = '.';
+ /* FALL THROUGH */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* It's a number */
+ for (;;) {
+ int gotnumber = FALSE;
+
+ tokadd(c);
+ switch (c) {
+ case 'x':
+ case 'X':
+ if (do_traditional)
+ goto done;
+ if (tok == tokstart + 2) {
+ int peek = nextc();
+
+ if (ISXDIGIT(peek)) {
+ inhex = TRUE;
+ pushback(); /* following digit */
+ } else {
+ pushback(); /* x or X */
+ goto done;
+ }
+ }
+ break;
+ case '.':
+ /* period ends exponent part of floating point number */
+ if (seen_point || seen_e) {
+ gotnumber = TRUE;
+ break;
+ }
+ seen_point = TRUE;
+ break;
+ case 'e':
+ case 'E':
+ if (inhex)
+ break;
+ if (seen_e) {
+ gotnumber = TRUE;
+ break;
+ }
+ seen_e = TRUE;
+ if ((c = nextc()) == '-' || c == '+') {
+ int c2 = nextc();
+
+ if (ISDIGIT(c2)) {
+ tokadd(c);
+ tokadd(c2);
+ } else {
+ pushback(); /* non-digit after + or - */
+ pushback(); /* + or - */
+ pushback(); /* e or E */
+ }
+ } else if (! ISDIGIT(c)) {
+ pushback(); /* character after e or E */
+ pushback(); /* e or E */
+ } else {
+ pushback(); /* digit */
+ }
+ break;
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'D':
+ case 'd':
+ case 'f':
+ case 'F':
+ if (do_traditional || ! inhex)
+ goto done;
+ /* fall through */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ break;
+ default:
+ done:
+ gotnumber = TRUE;
+ }
+ if (gotnumber)
+ break;
+ c = nextc();
+ }
+ if (c != EOF)
+ pushback();
+ else if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ tokadd('\0');
+ if (! do_traditional && isnondecimal(tokstart, FALSE)) {
+ if (do_lint) {
+ if (ISDIGIT(tokstart[1])) /* not an 'x' or 'X' */
+ lintwarn("numeric constant `%.*s' treated as octal",
+ (int) strlen(tokstart)-1, tokstart);
+ else if (tokstart[1] == 'x' || tokstart[1] == 'X')
+ lintwarn("numeric constant `%.*s' treated as hexadecimal",
+ (int) strlen(tokstart)-1, tokstart);
+ }
+ yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart)));
+ } else
+ yylval.nodeval = make_number(atof(tokstart));
+ yylval.nodeval->flags |= PERM;
+ return lasttok = YNUMBER;
+
+ case '&':
+ if ((c = nextc()) == '&') {
+ yylval.nodetypeval = Node_and;
+ allow_newline();
+ return lasttok = LEX_AND;
+ }
+ pushback();
+ return lasttok = '&';
+
+ case '|':
+ if ((c = nextc()) == '|') {
+ yylval.nodetypeval = Node_or;
+ allow_newline();
+ return lasttok = LEX_OR;
+ } else if (! do_traditional && c == '&') {
+ yylval.nodetypeval = Node_redirect_twoway;
+ return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
+ }
+ pushback();
+ if (in_print && in_parens == 0) {
+ yylval.nodetypeval = Node_redirect_pipe;
+ return lasttok = IO_OUT;
+ } else {
+ yylval.nodetypeval = Node_redirect_pipein;
+ return lasttok = IO_IN;
+ }
+ }
+
+ if (c != '_' && ! ISALPHA(c)) {
+ yyerror(_("invalid char '%c' in expression"), c);
+ exit(1);
+ }
+
+ /*
+ * Lots of fog here. Consider:
+ *
+ * print "xyzzy"$_"foo"
+ *
+ * Without the check for ` lasttok != '$' ', this is parsed as
+ *
+ * print "xxyzz" $(_"foo")
+ *
+ * With the check, it is "correctly" parsed as three
+ * string concatenations. Sigh. This seems to be
+ * "more correct", but this is definitely one of those
+ * occasions where the interactions are funny.
+ */
+ if (! do_traditional && c == '_' && lasttok != '$') {
+ if ((c = nextc()) == '"') {
+ intlstr = TRUE;
+ goto string;
+ }
+ pushback();
+ c = '_';
+ }
+
+ /* it's some type of name-type-thing. Find its length. */
+ tok = tokstart;
+ while (is_identchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ tokadd('\0');
+ emalloc(tokkey, char *, tok - tokstart, "yylex");
+ memcpy(tokkey, tokstart, tok - tokstart);
+ if (c != EOF)
+ pushback();
+ else if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+
+ /* See if it is a special token. */
+
+ if ((mid = check_special(tokstart)) >= 0) {
+ if (do_lint) {
+ if (tokentab[mid].flags & GAWKX)
+ lintwarn(_("`%s' is a gawk extension"),
+ tokentab[mid].operator);
+ if (tokentab[mid].flags & RESX)
+ lintwarn(_("`%s' is a Bell Labs extension"),
+ tokentab[mid].operator);
+ if (tokentab[mid].flags & NOT_POSIX)
+ lintwarn(_("POSIX does not allow `%s'"),
+ tokentab[mid].operator);
+ }
+ if (do_lint_old && (tokentab[mid].flags & NOT_OLD))
+ warning(_("`%s' is not supported in old awk"),
+ tokentab[mid].operator);
+ if ((do_traditional && (tokentab[mid].flags & GAWKX))
+ || (do_posix && (tokentab[mid].flags & NOT_POSIX)))
+ ;
+ else {
+ if (tokentab[mid].class == LEX_BUILTIN
+ || tokentab[mid].class == LEX_LENGTH)
+ yylval.lval = mid;
+ else
+ yylval.nodetypeval = tokentab[mid].value;
+ free(tokkey);
+ return lasttok = tokentab[mid].class;
+ }
+ }
+
+ yylval.sval = tokkey;
+ if (*lexptr == '(')
+ return lasttok = FUNC_CALL;
+ else {
+ static short goto_warned = FALSE;
+
+#define SMART_ALECK 1
+ if (SMART_ALECK && do_lint
+ && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
+ goto_warned = TRUE;
+ lintwarn(_("`goto' considered harmful!\n"));
+ }
+ return lasttok = NAME;
+ }
+}
+
+/* node_common --- common code for allocating a new node */
+
+static NODE *
+node_common(NODETYPE op)
+{
+ register NODE *r;
+
+ getnode(r);
+ r->type = op;
+ r->flags = MALLOC;
+ /* if lookahead is a NL, lineno is 1 too high */
+ if (lexeme && lexeme >= lexptr_begin && *lexeme == '\n')
+ r->source_line = sourceline - 1;
+ else
+ r->source_line = sourceline;
+ r->source_file = source;
+ return r;
+}
+
+/* node --- allocates a node with defined lnode and rnode. */
+
+NODE *
+node(NODE *left, NODETYPE op, NODE *right)
+{
+ register NODE *r;
+
+ r = node_common(op);
+ r->lnode = left;
+ r->rnode = right;
+ return r;
+}
+
+/* snode --- allocate a node with defined subnode and builtin for builtin
+ functions. Checks for arg. count and supplies defaults where
+ possible. */
+
+static NODE *
+snode(NODE *subn, NODETYPE op, int idx)
+{
+ register NODE *r;
+ register NODE *n;
+ int nexp = 0;
+ int args_allowed;
+
+ r = node_common(op);
+
+ /* traverse expression list to see how many args. given */
+ for (n = subn; n != NULL; n = n->rnode) {
+ nexp++;
+ if (nexp > 5)
+ break;
+ }
+
+ /* check against how many args. are allowed for this builtin */
+ args_allowed = tokentab[idx].flags & ARGS;
+ if (args_allowed && (args_allowed & A(nexp)) == 0)
+ fatal(_("%d is invalid as number of arguments for %s"),
+ nexp, tokentab[idx].operator);
+
+ r->builtin = tokentab[idx].ptr;
+
+ /* special case processing for a few builtins */
+ if (nexp == 0 && r->builtin == do_length) {
+ subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL);
+ } else if (r->builtin == do_match) {
+ static short warned = FALSE;
+
+ if (subn->rnode->lnode->type != Node_regex)
+ subn->rnode->lnode = mk_rexp(subn->rnode->lnode);
+
+ if (subn->rnode->rnode != NULL) { /* 3rd argument there */
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("match: third argument is a gawk extension"));
+ }
+ if (do_traditional)
+ fatal(_("match: third argument is a gawk extension"));
+ }
+ } else if (r->builtin == do_sub || r->builtin == do_gsub) {
+ if (subn->lnode->type != Node_regex)
+ subn->lnode = mk_rexp(subn->lnode);
+ if (nexp == 2)
+ append_right(subn, node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL));
+ else if (subn->rnode->rnode->lnode->type == Node_val) {
+ if (do_lint)
+ lintwarn(_("%s: string literal as last arg of substitute has no effect"),
+ (r->builtin == do_sub) ? "sub" : "gsub");
+ } else if (! isassignable(subn->rnode->rnode->lnode)) {
+ yyerror(_("%s third parameter is not a changeable object"),
+ (r->builtin == do_sub) ? "sub" : "gsub");
+ }
+ } else if (r->builtin == do_gensub) {
+ if (subn->lnode->type != Node_regex)
+ subn->lnode = mk_rexp(subn->lnode);
+ if (nexp == 3)
+ append_right(subn, node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL));
+ } else if (r->builtin == do_split) {
+ if (nexp == 2)
+ append_right(subn,
+ node(FS_node, Node_expression_list, (NODE *) NULL));
+ n = subn->rnode->rnode->lnode;
+ if (n->type != Node_regex)
+ subn->rnode->rnode->lnode = mk_rexp(n);
+ if (nexp == 2)
+ subn->rnode->rnode->lnode->re_flags |= FS_DFLT;
+ } else if (r->builtin == do_close) {
+ static short warned = FALSE;
+
+ if ( nexp == 2) {
+ if (do_lint && nexp == 2 && ! warned) {
+ warned = TRUE;
+ lintwarn(_("close: second argument is a gawk extension"));
+ }
+ if (do_traditional)
+ fatal(_("close: second argument is a gawk extension"));
+ }
+ } else if (do_intl /* --gen-po */
+ && r->builtin == do_dcgettext /* dcgettext(...) */
+ && subn->lnode->type == Node_val /* 1st arg is constant */
+ && (subn->lnode->flags & STRCUR) != 0) { /* it's a string constant */
+ /* ala xgettext, dcgettext("some string" ...) dumps the string */
+ NODE *str = subn->lnode;
+
+ if ((str->flags & INTLSTR) != 0)
+ warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore"));
+ /* don't dump it, the lexer already did */
+ else
+ dumpintlstr(str->stptr, str->stlen);
+ } else if (do_intl /* --gen-po */
+ && r->builtin == do_dcngettext /* dcngettext(...) */
+ && subn->lnode->type == Node_val /* 1st arg is constant */
+ && (subn->lnode->flags & STRCUR) != 0 /* it's a string constant */
+ && subn->rnode->lnode->type == Node_val /* 2nd arg is constant too */
+ && (subn->rnode->lnode->flags & STRCUR) != 0) { /* it's a string constant */
+ /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */
+ NODE *str1 = subn->lnode;
+ NODE *str2 = subn->rnode->lnode;
+
+ if (((str1->flags | str2->flags) & INTLSTR) != 0)
+ warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore"));
+ else
+ dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen);
+ }
+
+ r->subnode = subn;
+ if (r->builtin == do_sprintf) {
+ count_args(r);
+ r->lnode->printf_count = r->printf_count; /* hack */
+ }
+ return r;
+}
+
+/* make_for_loop --- build a for loop */
+
+static NODE *
+make_for_loop(NODE *init, NODE *cond, NODE *incr)
+{
+ register FOR_LOOP_HEADER *r;
+ NODE *n;
+
+ emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop");
+ getnode(n);
+ n->type = Node_illegal;
+ r->init = init;
+ r->cond = cond;
+ r->incr = incr;
+ n->sub.nodep.r.hd = r;
+ return n;
+}
+
+/* dup_parms --- return TRUE if there are duplicate parameters */
+
+static int
+dup_parms(NODE *func)
+{
+ register NODE *np;
+ const char *fname, **names;
+ int count, i, j, dups;
+ NODE *params;
+
+ if (func == NULL) /* error earlier */
+ return TRUE;
+
+ fname = func->param;
+ count = func->param_cnt;
+ params = func->rnode;
+
+ if (count == 0) /* no args, no problem */
+ return FALSE;
+
+ if (params == NULL) /* error earlier */
+ return TRUE;
+
+ emalloc(names, const char **, count * sizeof(char *), "dup_parms");
+
+ i = 0;
+ for (np = params; np != NULL; np = np->rnode) {
+ if (np->param == NULL) { /* error earlier, give up, go home */
+ free(names);
+ return TRUE;
+ }
+ names[i++] = np->param;
+ }
+
+ dups = 0;
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (strcmp(names[i], names[j]) == 0) {
+ dups++;
+ error(
+ _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
+ fname, i+1, names[j], j+1);
+ }
+ }
+ }
+
+ free(names);
+ return (dups > 0 ? TRUE : FALSE);
+}
+
+/* parms_shadow --- check if parameters shadow globals */
+
+static int
+parms_shadow(const char *fname, NODE *func)
+{
+ int count, i;
+ int ret = FALSE;
+
+ if (fname == NULL || func == NULL) /* error earlier */
+ return FALSE;
+
+ count = func->lnode->param_cnt;
+
+ if (count == 0) /* no args, no problem */
+ return FALSE;
+
+ /*
+ * Use warning() and not lintwarn() so that can warn
+ * about all shadowed parameters.
+ */
+ for (i = 0; i < count; i++) {
+ if (lookup(func->parmlist[i]) != NULL) {
+ warning(
+ _("function `%s': parameter `%s' shadows global variable"),
+ fname, func->parmlist[i]);
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * install:
+ * Install a name in the symbol table, even if it is already there.
+ * Caller must check against redefinition if that is desired.
+ */
+
+NODE *
+install(char *name, NODE *value)
+{
+ register NODE *hp;
+ register size_t len;
+ register int bucket;
+
+ var_count++;
+ len = strlen(name);
+ bucket = hash(name, len, (unsigned long) HASHSIZE);
+ getnode(hp);
+ hp->type = Node_hashnode;
+ hp->hnext = variables[bucket];
+ variables[bucket] = hp;
+ hp->hlength = len;
+ hp->hvalue = value;
+ hp->hname = name;
+ hp->hvalue->vname = name;
+ return hp->hvalue;
+}
+
+/* lookup --- find the most recent hash node for name installed by install */
+
+NODE *
+lookup(const char *name)
+{
+ register NODE *bucket;
+ register size_t len;
+
+ len = strlen(name);
+ for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)];
+ bucket != NULL; bucket = bucket->hnext)
+ if (bucket->hlength == len && STREQN(bucket->hname, name, len))
+ return bucket->hvalue;
+
+ return NULL;
+}
+
+/* var_comp --- compare two variable names */
+
+static int
+var_comp(const void *v1, const void *v2)
+{
+ const NODE *const *npp1, *const *npp2;
+ const NODE *n1, *n2;
+ int minlen;
+
+ npp1 = (const NODE *const *) v1;
+ npp2 = (const NODE *const *) v2;
+ n1 = *npp1;
+ n2 = *npp2;
+
+ if (n1->hlength > n2->hlength)
+ minlen = n1->hlength;
+ else
+ minlen = n2->hlength;
+
+ return strncmp(n1->hname, n2->hname, minlen);
+}
+
+/* valinfo --- dump var info */
+
+static void
+valinfo(NODE *n, FILE *fp)
+{
+ if (n->flags & STRING) {
+ fprintf(fp, "string (");
+ pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
+ fprintf(fp, ")\n");
+ } else if (n->flags & NUMBER)
+ fprintf(fp, "number (%.17g)\n", n->numbr);
+ else if (n->flags & STRCUR) {
+ fprintf(fp, "string value (");
+ pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
+ fprintf(fp, ")\n");
+ } else if (n->flags & NUMCUR)
+ fprintf(fp, "number value (%.17g)\n", n->numbr);
+ else
+ fprintf(fp, "?? flags %s\n", flags2str(n->flags));
+}
+
+
+/* dump_vars --- dump the symbol table */
+
+void
+dump_vars(const char *fname)
+{
+ int i, j;
+ NODE **table;
+ NODE *p;
+ FILE *fp;
+
+ emalloc(table, NODE **, var_count * sizeof(NODE *), "dump_vars");
+
+ if (fname == NULL)
+ fp = stderr;
+ else if ((fp = fopen(fname, "w")) == NULL) {
+ warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno));
+ warning(_("sending profile to standard error"));
+ fp = stderr;
+ }
+
+ for (i = j = 0; i < HASHSIZE; i++)
+ for (p = variables[i]; p != NULL; p = p->hnext)
+ table[j++] = p;
+
+ assert(j == var_count);
+
+ /* Shazzam! */
+ qsort(table, j, sizeof(NODE *), var_comp);
+
+ for (i = 0; i < j; i++) {
+ p = table[i];
+ if (p->hvalue->type == Node_func)
+ continue;
+ fprintf(fp, "%.*s: ", (int) p->hlength, p->hname);
+ if (p->hvalue->type == Node_var_array)
+ fprintf(fp, "array, %ld elements\n", p->hvalue->table_size);
+ else if (p->hvalue->type == Node_var_new)
+ fprintf(fp, "unused variable\n");
+ else if (p->hvalue->type == Node_var)
+ valinfo(p->hvalue->var_value, fp);
+ else {
+ NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
+
+ valinfo(*lhs, fp);
+ }
+ }
+
+ if (fp != stderr && fclose(fp) != 0)
+ warning(_("%s: close failed (%s)"), fname, strerror(errno));
+
+ free(table);
+}
+
+/* release_all_vars --- free all variable memory */
+
+void
+release_all_vars()
+{
+ int i;
+ NODE *p, *next;
+
+ for (i = 0; i < HASHSIZE; i++)
+ for (p = variables[i]; p != NULL; p = next) {
+ next = p->hnext;
+
+ if (p->hvalue->type == Node_func)
+ continue;
+ else if (p->hvalue->type == Node_var_array)
+ assoc_clear(p->hvalue);
+ else if (p->hvalue->type != Node_var_new) {
+ NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
+
+ unref(*lhs);
+ }
+ unref(p);
+ }
+}
+
+/* finfo --- for use in comparison and sorting of function names */
+
+struct finfo {
+ const char *name;
+ size_t nlen;
+ NODE *func;
+};
+
+/* fcompare --- comparison function for qsort */
+
+static int
+fcompare(const void *p1, const void *p2)
+{
+ const struct finfo *f1, *f2;
+ int minlen;
+
+ f1 = (const struct finfo *) p1;
+ f2 = (const struct finfo *) p2;
+
+ if (f1->nlen > f2->nlen)
+ minlen = f2->nlen;
+ else
+ minlen = f1->nlen;
+
+ return strncmp(f1->name, f2->name, minlen);
+}
+
+/* dump_funcs --- print all functions */
+
+void
+dump_funcs()
+{
+ int i, j;
+ NODE *p;
+ struct finfo *tab = NULL;
+
+ /*
+ * Walk through symbol table countng functions.
+ * Could be more than func_count if there are
+ * extension functions.
+ */
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ j++;
+ }
+ }
+ }
+
+ if (j == 0)
+ return;
+
+ emalloc(tab, struct finfo *, j * sizeof(struct finfo), "dump_funcs");
+
+ /* now walk again, copying info */
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ tab[j].name = p->hname;
+ tab[j].nlen = p->hlength;
+ tab[j].func = p->hvalue;
+ j++;
+ }
+ }
+ }
+
+
+ /* Shazzam! */
+ qsort(tab, j, sizeof(struct finfo), fcompare);
+
+ for (i = 0; i < j; i++)
+ pp_func(tab[i].name, tab[i].nlen, tab[i].func);
+
+ free(tab);
+}
+
+/* shadow_funcs --- check all functions for parameters that shadow globals */
+
+void
+shadow_funcs()
+{
+ int i, j;
+ NODE *p;
+ struct finfo *tab;
+ static int calls = 0;
+ int shadow = FALSE;
+
+ if (func_count == 0)
+ return;
+
+ if (calls++ != 0)
+ fatal(_("shadow_funcs() called twice!"));
+
+ emalloc(tab, struct finfo *, func_count * sizeof(struct finfo), "shadow_funcs");
+
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ tab[j].name = p->hname;
+ tab[j].nlen = p->hlength;
+ tab[j].func = p->hvalue;
+ j++;
+ }
+ }
+ }
+
+ assert(j == func_count);
+
+ /* Shazzam! */
+ qsort(tab, func_count, sizeof(struct finfo), fcompare);
+
+ for (i = 0; i < j; i++)
+ shadow |= parms_shadow(tab[i].name, tab[i].func);
+
+ free(tab);
+
+ /* End with fatal if the user requested it. */
+ if (shadow && lintfunc != warning)
+ lintwarn(_("there were shadowed variables."));
+}
+
+/*
+ * append_right:
+ * Add new to the rightmost branch of LIST. This uses n^2 time, so we make
+ * a simple attempt at optimizing it.
+ */
+
+static NODE *
+append_right(NODE *list, NODE *new)
+{
+ register NODE *oldlist;
+ static NODE *savefront = NULL, *savetail = NULL;
+
+ if (list == NULL || new == NULL)
+ return list;
+
+ oldlist = list;
+ if (savefront == oldlist)
+ list = savetail; /* Be careful: maybe list->rnode != NULL */
+ else
+ savefront = oldlist;
+
+ while (list->rnode != NULL)
+ list = list->rnode;
+ savetail = list->rnode = new;
+ return oldlist;
+}
+
+/*
+ * append_pattern:
+ * A wrapper around append_right, used for rule lists.
+ */
+static inline NODE *
+append_pattern(NODE **list, NODE *patt)
+{
+ NODE *n = node(patt, Node_rule_node, (NODE *) NULL);
+
+ if (*list == NULL)
+ *list = n;
+ else {
+ NODE *n1 = node(n, Node_rule_list, (NODE *) NULL);
+ if ((*list)->type != Node_rule_list)
+ *list = node(*list, Node_rule_list, n1);
+ else
+ (void) append_right(*list, n1);
+ }
+ return n;
+}
+
+/*
+ * func_install:
+ * check if name is already installed; if so, it had better have Null value,
+ * in which case def is added as the value. Otherwise, install name with def
+ * as value.
+ *
+ * Extra work, build up and save a list of the parameter names in a table
+ * and hang it off params->parmlist. This is used to set the `vname' field
+ * of each function parameter during a function call. See eval.c.
+ */
+
+static void
+func_install(NODE *params, NODE *def)
+{
+ NODE *r, *n, *thisfunc;
+ char **pnames, *names, *sp;
+ size_t pcount = 0, space = 0;
+ int i;
+
+ /* check for function foo(foo) { ... }. bleah. */
+ for (n = params->rnode; n != NULL; n = n->rnode) {
+ if (strcmp(n->param, params->param) == 0)
+ fatal(_("function `%s': can't use function name as parameter name"),
+ params->param);
+ }
+
+ thisfunc = NULL; /* turn off warnings */
+
+ /* symbol table managment */
+ pop_var(params, FALSE);
+ r = lookup(params->param);
+ if (r != NULL) {
+ fatal(_("function name `%s' previously defined"), params->param);
+ } else if (params->param == builtin_func) /* not a valid function name */
+ goto remove_params;
+
+ /* install the function */
+ thisfunc = node(params, Node_func, def);
+ (void) install(params->param, thisfunc);
+
+ /* figure out amount of space to allocate for variable names */
+ for (n = params->rnode; n != NULL; n = n->rnode) {
+ pcount++;
+ space += strlen(n->param) + 1;
+ }
+
+ /* allocate it and fill it in */
+ if (pcount != 0) {
+ emalloc(names, char *, space, "func_install");
+ emalloc(pnames, char **, pcount * sizeof(char *), "func_install");
+ sp = names;
+ for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode) {
+ pnames[i] = sp;
+ strcpy(sp, n->param);
+ sp += strlen(n->param) + 1;
+ }
+ thisfunc->parmlist = pnames;
+ } else {
+ thisfunc->parmlist = NULL;
+ }
+
+ /* update lint table info */
+ func_use(params->param, FUNC_DEFINE);
+
+ func_count++; /* used by profiling / pretty printer */
+
+remove_params:
+ /* remove params from symbol table */
+ pop_params(params->rnode);
+}
+
+/* pop_var --- remove a variable from the symbol table */
+
+static void
+pop_var(NODE *np, int freeit)
+{
+ register NODE *bucket, **save;
+ register size_t len;
+ char *name;
+
+ name = np->param;
+ len = strlen(name);
+ save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]);
+ for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
+ if (len == bucket->hlength && STREQN(bucket->hname, name, len)) {
+ var_count--;
+ *save = bucket->hnext;
+ freenode(bucket);
+ if (freeit)
+ free(np->param);
+ return;
+ }
+ save = &(bucket->hnext);
+ }
+}
+
+/* pop_params --- remove list of function parameters from symbol table */
+
+/*
+ * pop parameters out of the symbol table. do this in reverse order to
+ * avoid reading freed memory if there were duplicated parameters.
+ */
+static void
+pop_params(NODE *params)
+{
+ if (params == NULL)
+ return;
+ pop_params(params->rnode);
+ pop_var(params, TRUE);
+}
+
+/* make_param --- make NAME into a function parameter */
+
+static NODE *
+make_param(char *name)
+{
+ NODE *r;
+
+ getnode(r);
+ r->type = Node_param_list;
+ r->rnode = NULL;
+ r->param = name;
+ r->param_cnt = param_counter++;
+ return (install(name, r));
+}
+
+static struct fdesc {
+ char *name;
+ short used;
+ short defined;
+ struct fdesc *next;
+} *ftable[HASHSIZE];
+
+/* func_use --- track uses and definitions of functions */
+
+static void
+func_use(const char *name, enum defref how)
+{
+ struct fdesc *fp;
+ int len;
+ int ind;
+
+ len = strlen(name);
+ ind = hash(name, len, HASHSIZE);
+
+ for (fp = ftable[ind]; fp != NULL; fp = fp->next) {
+ if (strcmp(fp->name, name) == 0) {
+ if (how == FUNC_DEFINE)
+ fp->defined++;
+ else
+ fp->used++;
+ return;
+ }
+ }
+
+ /* not in the table, fall through to allocate a new one */
+
+ emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use");
+ memset(fp, '\0', sizeof(struct fdesc));
+ emalloc(fp->name, char *, len + 1, "func_use");
+ strcpy(fp->name, name);
+ if (how == FUNC_DEFINE)
+ fp->defined++;
+ else
+ fp->used++;
+ fp->next = ftable[ind];
+ ftable[ind] = fp;
+}
+
+/* check_funcs --- verify functions that are called but not defined */
+
+static void
+check_funcs()
+{
+ struct fdesc *fp, *next;
+ int i;
+
+ for (i = 0; i < HASHSIZE; i++) {
+ for (fp = ftable[i]; fp != NULL; fp = fp->next) {
+#ifdef REALLYMEAN
+ /* making this the default breaks old code. sigh. */
+ if (fp->defined == 0) {
+ error(
+ _("function `%s' called but never defined"), fp->name);
+ errcount++;
+ }
+#else
+ if (do_lint && fp->defined == 0)
+ lintwarn(
+ _("function `%s' called but never defined"), fp->name);
+#endif
+ if (do_lint && fp->used == 0) {
+ lintwarn(_("function `%s' defined but never called"),
+ fp->name);
+ }
+ }
+ }
+
+ /* now let's free all the memory */
+ for (i = 0; i < HASHSIZE; i++) {
+ for (fp = ftable[i]; fp != NULL; fp = next) {
+ next = fp->next;
+ free(fp->name);
+ free(fp);
+ }
+ }
+}
+
+/* param_sanity --- look for parameters that are regexp constants */
+
+static void
+param_sanity(NODE *arglist)
+{
+ NODE *argp, *arg;
+ int i;
+
+ for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) {
+ arg = argp->lnode;
+ if (arg->type == Node_regex)
+ warning(_("regexp constant for parameter #%d yields boolean value"), i);
+ }
+}
+
+/* deferred varibles --- those that are only defined if needed. */
+
+/*
+ * Is there any reason to use a hash table for deferred variables? At the
+ * moment, there are only 1 to 3 such variables, so it may not be worth
+ * the overhead. If more modules start using this facility, it should
+ * probably be converted into a hash table.
+ */
+
+static struct deferred_variable {
+ NODE *(*load_func)(void);
+ struct deferred_variable *next;
+ char name[1]; /* variable-length array */
+} *deferred_variables;
+
+/* register_deferred_variable --- add a var name and loading function to the list */
+
+void
+register_deferred_variable(const char *name, NODE *(*load_func)(void))
+{
+ struct deferred_variable *dv;
+ size_t sl = strlen(name);
+
+ emalloc(dv, struct deferred_variable *, sizeof(*dv)+sl,
+ "register_deferred_variable");
+ dv->load_func = load_func;
+ dv->next = deferred_variables;
+ memcpy(dv->name, name, sl+1);
+ deferred_variables = dv;
+}
+
+/* variable --- make sure NAME is in the symbol table */
+
+NODE *
+variable(char *name, int can_free, NODETYPE type)
+{
+ register NODE *r;
+
+ if ((r = lookup(name)) != NULL) {
+ if (r->type == Node_func)
+ fatal(_("function `%s' called with space between name and `(',\nor used as a variable or an array"),
+ r->vname);
+
+ } else {
+ /* not found */
+ struct deferred_variable *dv;
+
+ for (dv = deferred_variables; TRUE; dv = dv->next) {
+ if (dv == NULL) {
+ /*
+ * This is the only case in which we may not
+ * free the string.
+ */
+ NODE *n;
+
+ if (type == Node_var_array)
+ n = node(NULL, type, NULL);
+ else
+ n = node(Nnull_string, type, NULL);
+
+ return install(name, n);
+ }
+ if (STREQ(name, dv->name)) {
+ r = (*dv->load_func)();
+ break;
+ }
+ }
+ }
+ if (can_free)
+ free(name);
+ return r;
+}
+
+/* mk_rexp --- make a regular expression constant */
+
+static NODE *
+mk_rexp(NODE *exp)
+{
+ NODE *n;
+
+ if (exp->type == Node_regex)
+ return exp;
+
+ getnode(n);
+ n->type = Node_dynregex;
+ n->re_exp = exp;
+ n->re_text = NULL;
+ n->re_reg = NULL;
+ n->re_flags = 0;
+ n->re_cnt = 1;
+ return n;
+}
+
+/* isnoeffect --- when used as a statement, has no side effects */
+
+/*
+ * To be completely general, we should recursively walk the parse
+ * tree, to make sure that all the subexpressions also have no effect.
+ * Instead, we just weaken the actual warning that's printed, up above
+ * in the grammar.
+ */
+
+static int
+isnoeffect(NODETYPE type)
+{
+ switch (type) {
+ case Node_times:
+ case Node_quotient:
+ case Node_mod:
+ case Node_plus:
+ case Node_minus:
+ case Node_subscript:
+ case Node_concat:
+ case Node_exp:
+ case Node_unary_minus:
+ case Node_field_spec:
+ case Node_and:
+ case Node_or:
+ case Node_equal:
+ case Node_notequal:
+ case Node_less:
+ case Node_greater:
+ case Node_leq:
+ case Node_geq:
+ case Node_match:
+ case Node_nomatch:
+ case Node_not:
+ case Node_val:
+ case Node_in_array:
+ case Node_NF:
+ case Node_NR:
+ case Node_FNR:
+ case Node_FS:
+ case Node_RS:
+ case Node_FIELDWIDTHS:
+ case Node_IGNORECASE:
+ case Node_OFS:
+ case Node_ORS:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_BINMODE:
+ case Node_LINT:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ return TRUE;
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+
+ return FALSE;
+}
+
+/* isassignable --- can this node be assigned to? */
+
+static int
+isassignable(register NODE *n)
+{
+ switch (n->type) {
+ case Node_var_new:
+ case Node_var:
+ case Node_FIELDWIDTHS:
+ case Node_RS:
+ case Node_FS:
+ case Node_FNR:
+ case Node_NR:
+ case Node_NF:
+ case Node_IGNORECASE:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_ORS:
+ case Node_OFS:
+ case Node_LINT:
+ case Node_BINMODE:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ case Node_field_spec:
+ case Node_subscript:
+ return TRUE;
+ case Node_param_list:
+ return ((n->flags & FUNC) == 0); /* ok if not func name */
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+ return FALSE;
+}
+
+/* stopme --- for debugging */
+
+NODE *
+stopme(NODE *tree ATTRIBUTE_UNUSED)
+{
+ return (NODE *) 0;
+}
+
+/* dumpintlstr --- write out an initial .po file entry for the string */
+
+static void
+dumpintlstr(const char *str, size_t len)
+{
+ char *cp;
+
+ /* See the GNU gettext distribution for details on the file format */
+
+ if (source != NULL) {
+ /* ala the gettext sources, remove leading `./'s */
+ for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
+ continue;
+ printf("#: %s:%d\n", cp, sourceline);
+ }
+
+ printf("msgid ");
+ pp_string_fp(stdout, str, len, '"', TRUE);
+ putchar('\n');
+ printf("msgstr \"\"\n\n");
+ fflush(stdout);
+}
+
+/* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */
+
+static void
+dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
+{
+ char *cp;
+
+ /* See the GNU gettext distribution for details on the file format */
+
+ if (source != NULL) {
+ /* ala the gettext sources, remove leading `./'s */
+ for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
+ continue;
+ printf("#: %s:%d\n", cp, sourceline);
+ }
+
+ printf("msgid ");
+ pp_string_fp(stdout, str1, len1, '"', TRUE);
+ putchar('\n');
+ printf("msgid_plural ");
+ pp_string_fp(stdout, str2, len2, '"', TRUE);
+ putchar('\n');
+ printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
+ fflush(stdout);
+}
+
+/* count_args --- count the number of printf arguments */
+
+static void
+count_args(NODE *tree)
+{
+ size_t count = 0;
+ NODE *save_tree;
+
+ assert(tree->type == Node_K_printf
+ || (tree->type == Node_builtin && tree->builtin == do_sprintf));
+ save_tree = tree;
+
+ tree = tree->lnode; /* printf format string */
+
+ for (count = 0; tree != NULL; tree = tree->rnode)
+ count++;
+
+ save_tree->printf_count = count;
+}
+
+/* isarray --- can this type be subscripted? */
+
+static int
+isarray(NODE *n)
+{
+ switch (n->type) {
+ case Node_var_new:
+ case Node_var_array:
+ return TRUE;
+ case Node_param_list:
+ return (n->flags & FUNC) == 0;
+ case Node_array_ref:
+ cant_happen();
+ break;
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+
+ return FALSE;
+}
+
+/* See if name is a special token. */
+
+int
+check_special(const char *name)
+{
+ int low, high, mid;
+ int i;
+
+ low = 0;
+ high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1;
+ while (low <= high) {
+ mid = (low + high) / 2;
+ i = *name - tokentab[mid].operator[0];
+ if (i == 0)
+ i = strcmp(name, tokentab[mid].operator);
+
+ if (i < 0) /* token < mid */
+ high = mid - 1;
+ else if (i > 0) /* token > mid */
+ low = mid + 1;
+ else
+ return mid;
+ }
+ return -1;
+}
+
+
--- /dev/null
+/*
+ * awkgram.y --- yacc/bison parser
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+%{
+#ifdef GAWKDEBUG
+#define YYDEBUG 12
+#endif
+
+#include "awk.h"
+
+#define CAN_FREE TRUE
+#define DONT_FREE FALSE
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1;
+#else
+static void yyerror(); /* va_alist */
+#endif
+static char *get_src_buf P((void));
+static int yylex P((void));
+static NODE *node_common P((NODETYPE op));
+static NODE *snode P((NODE *subn, NODETYPE op, int sindex));
+static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr));
+static NODE *append_right P((NODE *list, NODE *new));
+static inline NODE *append_pattern P((NODE **list, NODE *patt));
+static void func_install P((NODE *params, NODE *def));
+static void pop_var P((NODE *np, int freeit));
+static void pop_params P((NODE *params));
+static NODE *make_param P((char *name));
+static NODE *mk_rexp P((NODE *exp));
+static int dup_parms P((NODE *func));
+static void param_sanity P((NODE *arglist));
+static int parms_shadow P((const char *fname, NODE *func));
+static int isnoeffect P((NODETYPE t));
+static int isassignable P((NODE *n));
+static void dumpintlstr P((const char *str, size_t len));
+static void dumpintlstr2 P((const char *str1, size_t len1, const char *str2, size_t len2));
+static void count_args P((NODE *n));
+static int isarray P((NODE *n));
+
+enum defref { FUNC_DEFINE, FUNC_USE };
+static void func_use P((const char *name, enum defref how));
+static void check_funcs P((void));
+
+static int want_regexp; /* lexical scanning kludge */
+static int can_return; /* parsing kludge */
+static int begin_or_end_rule = FALSE; /* parsing kludge */
+static int parsing_end_rule = FALSE; /* for warnings */
+static int in_print = FALSE; /* lexical scanning kludge for print */
+static int in_parens = 0; /* lexical scanning kludge for print */
+static char *lexptr; /* pointer to next char during parsing */
+static char *lexend;
+static char *lexptr_begin; /* keep track of where we were for error msgs */
+static char *lexeme; /* beginning of lexeme for debugging */
+static char *thisline = NULL;
+#define YYDEBUG_LEXER_TEXT (lexeme)
+static int param_counter;
+static char *tokstart = NULL;
+static char *tok = NULL;
+static char *tokend;
+
+static long func_count; /* total number of functions */
+
+#define HASHSIZE 1021 /* this constant only used here */
+NODE *variables[HASHSIZE];
+static int var_count; /* total number of global variables */
+
+extern char *source;
+extern int sourceline;
+extern struct src *srcfiles;
+extern long numfiles;
+extern int errcount;
+extern NODE *begin_block;
+extern NODE *end_block;
+
+/*
+ * This string cannot occur as a real awk identifier.
+ * Use it as a special token to make function parsing
+ * uniform, but if it's seen, don't install the function.
+ * e.g.
+ * function split(x) { return x }
+ * function x(a) { return a }
+ * should only produce one error message, and not core dump.
+ */
+static char builtin_func[] = "@builtin";
+%}
+
+%union {
+ long lval;
+ AWKNUM fval;
+ NODE *nodeval;
+ NODETYPE nodetypeval;
+ char *sval;
+ NODE *(*ptrval) P((void));
+}
+
+%type <nodeval> function_prologue pattern action variable param_list
+%type <nodeval> exp common_exp
+%type <nodeval> simp_exp non_post_simp_exp
+%type <nodeval> expression_list opt_expression_list print_expression_list
+%type <nodeval> statements statement if_statement switch_body case_statements case_statement case_value opt_param_list
+%type <nodeval> simple_stmt opt_simple_stmt
+%type <nodeval> opt_exp opt_variable regexp
+%type <nodeval> input_redir output_redir
+%type <nodetypeval> print
+%type <nodetypeval> assign_operator a_relop relop_or_less
+%type <sval> func_name
+%type <lval> lex_builtin
+
+%token <sval> FUNC_CALL NAME REGEXP
+%token <lval> ERROR
+%token <nodeval> YNUMBER YSTRING
+%token <nodetypeval> RELOP IO_OUT IO_IN
+%token <nodetypeval> ASSIGNOP ASSIGN MATCHOP CONCAT_OP
+%token <nodetypeval> LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE
+%token <nodetypeval> LEX_SWITCH LEX_CASE LEX_DEFAULT LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE
+%token <nodetypeval> LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION
+%token <nodetypeval> LEX_GETLINE LEX_NEXTFILE
+%token <nodetypeval> LEX_IN
+%token <lval> LEX_AND LEX_OR INCREMENT DECREMENT
+%token <lval> LEX_BUILTIN LEX_LENGTH
+%token NEWLINE
+
+/* these are just yylval numbers */
+
+/* Lowest to highest */
+%right ASSIGNOP ASSIGN SLASH_BEFORE_EQUAL
+%right '?' ':'
+%left LEX_OR
+%left LEX_AND
+%left LEX_GETLINE
+%nonassoc LEX_IN
+%left FUNC_CALL LEX_BUILTIN LEX_LENGTH
+%nonassoc ','
+%nonassoc MATCHOP
+%nonassoc RELOP '<' '>' IO_IN IO_OUT
+%left CONCAT_OP
+%left YSTRING YNUMBER
+%left '+' '-'
+%left '*' '/' '%'
+%right '!' UNARY
+%right '^'
+%left INCREMENT DECREMENT
+%left '$'
+%left '(' ')'
+%%
+
+start
+ : opt_nls program opt_nls
+ {
+ check_funcs();
+ }
+ ;
+
+program
+ : /* empty */
+ | program rule
+ {
+ begin_or_end_rule = parsing_end_rule = FALSE;
+ yyerrok;
+ }
+ | program error
+ {
+ begin_or_end_rule = parsing_end_rule = FALSE;
+ /*
+ * If errors, give up, don't produce an infinite
+ * stream of syntax error messages.
+ */
+ /* yyerrok; */
+ }
+ ;
+
+rule
+ : pattern action
+ {
+ $1->rnode = $2;
+ }
+ | pattern statement_term
+ {
+ if ($1->lnode != NULL) {
+ /* pattern rule with non-empty pattern */
+ $1->rnode = node(NULL, Node_K_print_rec, NULL);
+ } else {
+ /* an error */
+ if (begin_or_end_rule)
+ msg(_("%s blocks must have an action part"),
+ (parsing_end_rule ? "END" : "BEGIN"));
+ else
+ msg(_("each rule must have a pattern or an action part"));
+ errcount++;
+ }
+ }
+ | function_prologue action
+ {
+ can_return = FALSE;
+ if ($1)
+ func_install($1, $2);
+ yyerrok;
+ }
+ ;
+
+pattern
+ : /* empty */
+ {
+ $$ = append_pattern(&expression_value, (NODE *) NULL);
+ }
+ | exp
+ {
+ $$ = append_pattern(&expression_value, $1);
+ }
+ | exp ',' exp
+ {
+ NODE *r;
+
+ getnode(r);
+ r->type = Node_line_range;
+ r->condpair = node($1, Node_cond_pair, $3);
+ r->triggered = FALSE;
+ $$ = append_pattern(&expression_value, r);
+ }
+ | LEX_BEGIN
+ {
+ begin_or_end_rule = TRUE;
+ $$ = append_pattern(&begin_block, (NODE *) NULL);
+ }
+ | LEX_END
+ {
+ begin_or_end_rule = parsing_end_rule = TRUE;
+ $$ = append_pattern(&end_block, (NODE *) NULL);
+ }
+ ;
+
+action
+ : l_brace statements r_brace opt_semi opt_nls
+ { $$ = $2; }
+ ;
+
+func_name
+ : NAME
+ { $$ = $1; }
+ | FUNC_CALL
+ { $$ = $1; }
+ | lex_builtin
+ {
+ yyerror(_("`%s' is a built-in function, it cannot be redefined"),
+ tokstart);
+ errcount++;
+ $$ = builtin_func;
+ /* yyerrok; */
+ }
+ ;
+
+lex_builtin
+ : LEX_BUILTIN
+ | LEX_LENGTH
+ ;
+
+function_prologue
+ : LEX_FUNCTION
+ {
+ param_counter = 0;
+ }
+ func_name '(' opt_param_list r_paren opt_nls
+ {
+ NODE *t;
+
+ t = make_param($3);
+ t->flags |= FUNC;
+ $$ = append_right(t, $5);
+ can_return = TRUE;
+ /* check for duplicate parameter names */
+ if (dup_parms($$))
+ errcount++;
+ }
+ ;
+
+regexp
+ /*
+ * In this rule, want_regexp tells yylex that the next thing
+ * is a regexp so it should read up to the closing slash.
+ */
+ : a_slash
+ { ++want_regexp; }
+ REGEXP /* The terminating '/' is consumed by yylex(). */
+ {
+ NODE *n;
+ size_t len = strlen($3);
+
+ if (do_lint) {
+ if (len == 0)
+ lintwarn(_("regexp constant `//' looks like a C++ comment, but is not"));
+ else if (($3)[0] == '*' && ($3)[len-1] == '*')
+ /* possible C comment */
+ lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), tokstart);
+ }
+ getnode(n);
+ n->type = Node_regex;
+ n->re_exp = make_string($3, len);
+ n->re_reg = make_regexp($3, len, FALSE, TRUE);
+ n->re_text = NULL;
+ n->re_flags = CONST;
+ n->re_cnt = 1;
+ $$ = n;
+ }
+ ;
+
+a_slash
+ : '/'
+ | SLASH_BEFORE_EQUAL
+ ;
+
+statements
+ : /* empty */
+ { $$ = NULL; }
+ | statements statement
+ {
+ if ($2 == NULL)
+ $$ = $1;
+ else {
+ if (do_lint && isnoeffect($2->type))
+ lintwarn(_("statement may have no effect"));
+ if ($1 == NULL)
+ $$ = $2;
+ else
+ $$ = append_right(
+ ($1->type == Node_statement_list ? $1
+ : node($1, Node_statement_list, (NODE *) NULL)),
+ ($2->type == Node_statement_list ? $2
+ : node($2, Node_statement_list, (NODE *) NULL)));
+ }
+ yyerrok;
+ }
+ | statements error
+ { $$ = NULL; }
+ ;
+
+statement_term
+ : nls
+ | semi opt_nls
+ ;
+
+statement
+ : semi opt_nls
+ { $$ = NULL; }
+ | l_brace statements r_brace
+ { $$ = $2; }
+ | if_statement
+ { $$ = $1; }
+ | LEX_SWITCH '(' exp r_paren opt_nls l_brace switch_body opt_nls r_brace
+ { $$ = node($3, Node_K_switch, $7); }
+ | LEX_WHILE '(' exp r_paren opt_nls statement
+ { $$ = node($3, Node_K_while, $6); }
+ | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls
+ { $$ = node($6, Node_K_do, $3); }
+ | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement
+ {
+ /*
+ * Efficiency hack. Recognize the special case of
+ *
+ * for (iggy in foo)
+ * delete foo[iggy]
+ *
+ * and treat it as if it were
+ *
+ * delete foo
+ *
+ * Check that the body is a `delete a[i]' statement,
+ * and that both the loop var and array names match.
+ */
+ if ($8 != NULL && $8->type == Node_K_delete && $8->rnode != NULL) {
+ NODE *arr, *sub;
+
+ assert($8->rnode->type == Node_expression_list);
+ arr = $8->lnode; /* array var */
+ sub = $8->rnode->lnode; /* index var */
+
+ if ( (arr->type == Node_var_new
+ || arr->type == Node_var_array
+ || arr->type == Node_param_list)
+ && (sub->type == Node_var_new
+ || sub->type == Node_var
+ || sub->type == Node_param_list)
+ && strcmp($3, sub->vname) == 0
+ && strcmp($5, arr->vname) == 0) {
+ $8->type = Node_K_delete_loop;
+ $$ = $8;
+ free($3); /* thanks to valgrind for pointing these out */
+ free($5);
+ }
+ else
+ goto regular_loop;
+ } else {
+ regular_loop:
+ $$ = node($8, Node_K_arrayfor,
+ make_for_loop(variable($3, CAN_FREE, Node_var),
+ (NODE *) NULL, variable($5, CAN_FREE, Node_var_array)));
+ }
+ }
+ | LEX_FOR '(' opt_simple_stmt semi opt_nls exp semi opt_nls opt_simple_stmt r_paren opt_nls statement
+ {
+ $$ = node($12, Node_K_for, (NODE *) make_for_loop($3, $6, $9));
+ }
+ | LEX_FOR '(' opt_simple_stmt semi opt_nls semi opt_nls opt_simple_stmt r_paren opt_nls statement
+ {
+ $$ = node($11, Node_K_for,
+ (NODE *) make_for_loop($3, (NODE *) NULL, $8));
+ }
+ | LEX_BREAK statement_term
+ /* for break, maybe we'll have to remember where to break to */
+ { $$ = node((NODE *) NULL, Node_K_break, (NODE *) NULL); }
+ | LEX_CONTINUE statement_term
+ /* similarly */
+ { $$ = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); }
+ | LEX_NEXT statement_term
+ { NODETYPE type;
+
+ if (begin_or_end_rule)
+ yyerror(_("`%s' used in %s action"), "next",
+ (parsing_end_rule ? "END" : "BEGIN"));
+ type = Node_K_next;
+ $$ = node((NODE *) NULL, type, (NODE *) NULL);
+ }
+ | LEX_NEXTFILE statement_term
+ {
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`nextfile' is a gawk extension"));
+ }
+ if (do_lint)
+ lintwarn(_("`nextfile' is a gawk extension"));
+ if (begin_or_end_rule) {
+ /* same thing */
+ errcount++;
+ error(_("`%s' used in %s action"), "nextfile",
+ (parsing_end_rule ? "END" : "BEGIN"));
+ }
+ $$ = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL);
+ }
+ | LEX_EXIT opt_exp statement_term
+ { $$ = node($2, Node_K_exit, (NODE *) NULL); }
+ | LEX_RETURN
+ {
+ if (! can_return)
+ yyerror(_("`return' used outside function context"));
+ }
+ opt_exp statement_term
+ {
+ $$ = node($3 == NULL ? Nnull_string : $3,
+ Node_K_return, (NODE *) NULL);
+ }
+ | simple_stmt statement_term
+ ;
+
+ /*
+ * A simple_stmt exists to satisfy a constraint in the POSIX
+ * grammar allowing them to occur as the 1st and 3rd parts
+ * in a `for (...;...;...)' loop. This is a historical oddity
+ * inherited from Unix awk, not at all documented in the AK&W
+ * awk book. We support it, as this was reported as a bug.
+ * We don't bother to document it though. So there.
+ */
+simple_stmt
+ : print { in_print = TRUE; in_parens = 0; } print_expression_list output_redir
+ {
+ /*
+ * Optimization: plain `print' has no expression list, so $3 is null.
+ * If $3 is an expression list with one element (rnode == null)
+ * and lnode is a field spec for field 0, we have `print $0'.
+ * For both, use Node_K_print_rec, which is faster for these two cases.
+ */
+ if ($1 == Node_K_print &&
+ ($3 == NULL
+ || ($3->type == Node_expression_list
+ && $3->rnode == NULL
+ && $3->lnode->type == Node_field_spec
+ && $3->lnode->lnode->type == Node_val
+ && $3->lnode->lnode->numbr == 0.0))
+ ) {
+ static int warned = FALSE;
+
+ $$ = node(NULL, Node_K_print_rec, $4);
+
+ if (do_lint && $3 == NULL && begin_or_end_rule && ! warned) {
+ warned = TRUE;
+ lintwarn(
+ _("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
+ }
+ } else {
+ $$ = node($3, $1, $4);
+ if ($$->type == Node_K_printf)
+ count_args($$);
+ }
+ }
+ | LEX_DELETE NAME '[' expression_list ']'
+ { $$ = node(variable($2, CAN_FREE, Node_var_array), Node_K_delete, $4); }
+ | LEX_DELETE NAME
+ {
+ if (do_lint)
+ lintwarn(_("`delete array' is a gawk extension"));
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`delete array' is a gawk extension"));
+ }
+ $$ = node(variable($2, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
+ }
+ | LEX_DELETE '(' NAME ')'
+ {
+ /* this is for tawk compatibility. maybe the warnings should always be done. */
+ if (do_lint)
+ lintwarn(_("`delete(array)' is a non-portable tawk extension"));
+ if (do_traditional) {
+ /*
+ * can't use yyerror, since may have overshot
+ * the source line
+ */
+ errcount++;
+ error(_("`delete(array)' is a non-portable tawk extension"));
+ }
+ $$ = node(variable($3, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
+ }
+ | exp
+ { $$ = $1; }
+ ;
+
+opt_simple_stmt
+ : /* empty */
+ { $$ = NULL; }
+ | simple_stmt
+ { $$ = $1; }
+ ;
+
+switch_body
+ : case_statements
+ {
+ if ($1 == NULL) {
+ $$ = NULL;
+ } else {
+ NODE *dflt = NULL;
+ NODE *head = $1;
+ NODE *curr;
+
+ const char **case_values = NULL;
+
+ int maxcount = 128;
+ int case_count = 0;
+ int i;
+
+ emalloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
+ for (curr = $1; curr != NULL; curr = curr->rnode) {
+ /* Assure that case statement values are unique. */
+ if (curr->lnode->type == Node_K_case) {
+ char *caseval;
+
+ if (curr->lnode->lnode->type == Node_regex)
+ caseval = curr->lnode->lnode->re_exp->stptr;
+ else
+ caseval = force_string(tree_eval(curr->lnode->lnode))->stptr;
+
+ for (i = 0; i < case_count; i++)
+ if (strcmp(caseval, case_values[i]) == 0)
+ yyerror(_("duplicate case values in switch body: %s"), caseval);
+
+ if (case_count >= maxcount) {
+ maxcount += 128;
+ erealloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
+ }
+ case_values[case_count++] = caseval;
+ } else {
+ /* Otherwise save a pointer to the default node. */
+ if (dflt != NULL)
+ yyerror(_("Duplicate `default' detected in switch body"));
+ dflt = curr;
+ }
+ }
+
+ free(case_values);
+
+ /* Create the switch body. */
+ $$ = node(head, Node_switch_body, dflt);
+ }
+ }
+ ;
+
+case_statements
+ : /* empty */
+ { $$ = NULL; }
+ | case_statements case_statement
+ {
+ if ($2 == NULL)
+ $$ = $1;
+ else {
+ if (do_lint && isnoeffect($2->type))
+ lintwarn(_("statement may have no effect"));
+ if ($1 == NULL)
+ $$ = node($2, Node_case_list, (NODE *) NULL);
+ else
+ $$ = append_right(
+ ($1->type == Node_case_list ? $1 : node($1, Node_case_list, (NODE *) NULL)),
+ ($2->type == Node_case_list ? $2 : node($2, Node_case_list, (NODE *) NULL))
+ );
+ }
+ yyerrok;
+ }
+ | case_statements error
+ { $$ = NULL; }
+ ;
+
+case_statement
+ : LEX_CASE case_value colon opt_nls statements
+ { $$ = node($2, Node_K_case, $5); }
+ | LEX_DEFAULT colon opt_nls statements
+ { $$ = node((NODE *) NULL, Node_K_default, $4); }
+ ;
+
+case_value
+ : YNUMBER
+ { $$ = $1; }
+ | '-' YNUMBER %prec UNARY
+ {
+ $2->numbr = -(force_number($2));
+ $$ = $2;
+ }
+ | '+' YNUMBER %prec UNARY
+ { $$ = $2; }
+ | YSTRING
+ { $$ = $1; }
+ | regexp
+ { $$ = $1; }
+ ;
+
+print
+ : LEX_PRINT
+ | LEX_PRINTF
+ ;
+
+ /*
+ * Note: ``print(x)'' is already parsed by the first rule,
+ * so there is no good in covering it by the second one too.
+ */
+print_expression_list
+ : opt_expression_list
+ | '(' exp comma expression_list r_paren
+ { $$ = node($2, Node_expression_list, $4); }
+ ;
+
+output_redir
+ : /* empty */
+ {
+ in_print = FALSE;
+ in_parens = 0;
+ $$ = NULL;
+ }
+ | IO_OUT { in_print = FALSE; in_parens = 0; } common_exp
+ {
+ $$ = node($3, $1, (NODE *) NULL);
+ if ($1 == Node_redirect_twoway
+ && $3->type == Node_K_getline
+ && $3->rnode != NULL
+ && $3->rnode->type == Node_redirect_twoway)
+ yyerror(_("multistage two-way pipelines don't work"));
+ }
+ ;
+
+if_statement
+ : LEX_IF '(' exp r_paren opt_nls statement
+ {
+ $$ = node($3, Node_K_if,
+ node($6, Node_if_branches, (NODE *) NULL));
+ }
+ | LEX_IF '(' exp r_paren opt_nls statement
+ LEX_ELSE opt_nls statement
+ { $$ = node($3, Node_K_if,
+ node($6, Node_if_branches, $9)); }
+ ;
+
+nls
+ : NEWLINE
+ | nls NEWLINE
+ ;
+
+opt_nls
+ : /* empty */
+ | nls
+ ;
+
+input_redir
+ : /* empty */
+ { $$ = NULL; }
+ | '<' simp_exp
+ { $$ = node($2, Node_redirect_input, (NODE *) NULL); }
+ ;
+
+opt_param_list
+ : /* empty */
+ { $$ = NULL; }
+ | param_list
+ { $$ = $1; }
+ ;
+
+param_list
+ : NAME
+ { $$ = make_param($1); }
+ | param_list comma NAME
+ { $$ = append_right($1, make_param($3)); yyerrok; }
+ | error
+ { $$ = NULL; }
+ | param_list error
+ { $$ = NULL; }
+ | param_list comma error
+ { $$ = NULL; }
+ ;
+
+/* optional expression, as in for loop */
+opt_exp
+ : /* empty */
+ { $$ = NULL; }
+ | exp
+ { $$ = $1; }
+ ;
+
+opt_expression_list
+ : /* empty */
+ { $$ = NULL; }
+ | expression_list
+ { $$ = $1; }
+ ;
+
+expression_list
+ : exp
+ { $$ = node($1, Node_expression_list, (NODE *) NULL); }
+ | expression_list comma exp
+ {
+ $$ = append_right($1,
+ node($3, Node_expression_list, (NODE *) NULL));
+ yyerrok;
+ }
+ | error
+ { $$ = NULL; }
+ | expression_list error
+ { $$ = NULL; }
+ | expression_list error exp
+ { $$ = NULL; }
+ | expression_list comma error
+ { $$ = NULL; }
+ ;
+
+/* Expressions, not including the comma operator. */
+exp : variable assign_operator exp %prec ASSIGNOP
+ {
+ if (do_lint && $3->type == Node_regex)
+ lintwarn(_("regular expression on right of assignment"));
+ /*
+ * Optimization of `x = x y'. Can save lots of time
+ * if done a lot.
+ */
+ if (( $1->type == Node_var
+ || $1->type == Node_var_new
+ || $1->type == Node_param_list)
+ && $2 == Node_assign
+ && $3->type == Node_concat
+ && $3->lnode == $1) {
+ $3->type = Node_assign_concat; /* Just change the type */
+ $$ = $3; /* And use it directly */
+ } else
+ $$ = node($1, $2, $3);
+ }
+ | exp LEX_AND exp
+ { $$ = node($1, Node_and, $3); }
+ | exp LEX_OR exp
+ { $$ = node($1, Node_or, $3); }
+ | exp MATCHOP exp
+ {
+ if ($1->type == Node_regex)
+ warning(_("regular expression on left of `~' or `!~' operator"));
+ $$ = node($1, $2, mk_rexp($3));
+ }
+ | exp LEX_IN NAME
+ { $$ = node(variable($3, CAN_FREE, Node_var_array), Node_in_array, $1); }
+ | exp a_relop exp %prec RELOP
+ {
+ if (do_lint && $3->type == Node_regex)
+ lintwarn(_("regular expression on right of comparison"));
+ $$ = node($1, $2, $3);
+ }
+ | exp '?' exp ':' exp
+ { $$ = node($1, Node_cond_exp, node($3, Node_if_branches, $5));}
+ | common_exp
+ { $$ = $1; }
+ ;
+
+assign_operator
+ : ASSIGN
+ { $$ = $1; }
+ | ASSIGNOP
+ { $$ = $1; }
+ | SLASH_BEFORE_EQUAL ASSIGN /* `/=' */
+ { $$ = Node_assign_quotient; }
+ ;
+
+relop_or_less
+ : RELOP
+ { $$ = $1; }
+ | '<'
+ { $$ = Node_less; }
+ ;
+a_relop
+ : relop_or_less
+ | '>'
+ { $$ = Node_greater; }
+ ;
+
+common_exp
+ : regexp
+ { $$ = $1; }
+ | '!' regexp %prec UNARY
+ {
+ $$ = node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_nomatch,
+ $2);
+ }
+ | '(' expression_list r_paren LEX_IN NAME
+ { $$ = node(variable($5, CAN_FREE, Node_var_array), Node_in_array, $2); }
+ | simp_exp
+ { $$ = $1; }
+ | common_exp simp_exp %prec CONCAT_OP
+ { $$ = node($1, Node_concat, $2); }
+ ;
+
+simp_exp
+ : non_post_simp_exp
+ /* Binary operators in order of decreasing precedence. */
+ | simp_exp '^' simp_exp
+ { $$ = node($1, Node_exp, $3); }
+ | simp_exp '*' simp_exp
+ { $$ = node($1, Node_times, $3); }
+ | simp_exp '/' simp_exp
+ { $$ = node($1, Node_quotient, $3); }
+ | simp_exp '%' simp_exp
+ { $$ = node($1, Node_mod, $3); }
+ | simp_exp '+' simp_exp
+ { $$ = node($1, Node_plus, $3); }
+ | simp_exp '-' simp_exp
+ { $$ = node($1, Node_minus, $3); }
+ | LEX_GETLINE opt_variable input_redir
+ {
+ if (do_lint && parsing_end_rule && $3 == NULL)
+ lintwarn(_("non-redirected `getline' undefined inside END action"));
+ $$ = node($2, Node_K_getline, $3);
+ }
+ | simp_exp IO_IN LEX_GETLINE opt_variable
+ {
+ $$ = node($4, Node_K_getline,
+ node($1, $2, (NODE *) NULL));
+ }
+ | variable INCREMENT
+ { $$ = node($1, Node_postincrement, (NODE *) NULL); }
+ | variable DECREMENT
+ { $$ = node($1, Node_postdecrement, (NODE *) NULL); }
+ ;
+
+non_post_simp_exp
+ : '!' simp_exp %prec UNARY
+ { $$ = node($2, Node_not, (NODE *) NULL); }
+ | '(' exp r_paren
+ { $$ = $2; }
+ | LEX_BUILTIN
+ '(' opt_expression_list r_paren
+ { $$ = snode($3, Node_builtin, (int) $1); }
+ | LEX_LENGTH '(' opt_expression_list r_paren
+ { $$ = snode($3, Node_builtin, (int) $1); }
+ | LEX_LENGTH
+ {
+ if (do_lint)
+ lintwarn(_("call of `length' without parentheses is not portable"));
+ $$ = snode((NODE *) NULL, Node_builtin, (int) $1);
+ if (do_posix)
+ warning(_("call of `length' without parentheses is deprecated by POSIX"));
+ }
+ | FUNC_CALL '(' opt_expression_list r_paren
+ {
+ $$ = node($3, Node_func_call, make_string($1, strlen($1)));
+ $$->funcbody = NULL;
+ func_use($1, FUNC_USE);
+ param_sanity($3);
+ free($1);
+ }
+ | variable
+ | INCREMENT variable
+ { $$ = node($2, Node_preincrement, (NODE *) NULL); }
+ | DECREMENT variable
+ { $$ = node($2, Node_predecrement, (NODE *) NULL); }
+ | YNUMBER
+ { $$ = $1; }
+ | YSTRING
+ { $$ = $1; }
+
+ | '-' simp_exp %prec UNARY
+ {
+ if ($2->type == Node_val && ($2->flags & (STRCUR|STRING)) == 0) {
+ $2->numbr = -(force_number($2));
+ $$ = $2;
+ } else
+ $$ = node($2, Node_unary_minus, (NODE *) NULL);
+ }
+ | '+' simp_exp %prec UNARY
+ {
+ /*
+ * was: $$ = $2
+ * POSIX semantics: force a conversion to numeric type
+ */
+ $$ = node (make_number(0.0), Node_plus, $2);
+ }
+ ;
+
+opt_variable
+ : /* empty */
+ { $$ = NULL; }
+ | variable
+ { $$ = $1; }
+ ;
+
+variable
+ : NAME
+ { $$ = variable($1, CAN_FREE, Node_var_new); }
+ | NAME '[' expression_list ']'
+ {
+ NODE *n;
+
+ if ((n = lookup($1)) != NULL && ! isarray(n))
+ yyerror(_("use of non-array as array"));
+ else if ($3 == NULL) {
+ fatal(_("invalid subscript expression"));
+ } else if ($3->rnode == NULL) {
+ $$ = node(variable($1, CAN_FREE, Node_var_array), Node_subscript, $3->lnode);
+ freenode($3);
+ } else
+ $$ = node(variable($1, CAN_FREE, Node_var_array), Node_subscript, $3);
+ }
+ | '$' non_post_simp_exp
+ { $$ = node($2, Node_field_spec, (NODE *) NULL); }
+/*
+#if 0
+ | lex_builtin
+ { fatal(_("can't use built-in function `%s' as a variable"), tokstart); }
+#endif
+*/
+ ;
+
+l_brace
+ : '{' opt_nls
+ ;
+
+r_brace
+ : '}' opt_nls { yyerrok; }
+ ;
+
+r_paren
+ : ')' { yyerrok; }
+ ;
+
+opt_semi
+ : /* empty */
+ | semi
+ ;
+
+semi
+ : ';' { yyerrok; }
+ ;
+
+colon
+ : ':' { yyerrok; }
+ ;
+
+comma : ',' opt_nls { yyerrok; }
+ ;
+
+%%
+
+struct token {
+ const char *operator; /* text to match */
+ NODETYPE value; /* node type */
+ int class; /* lexical class */
+ unsigned flags; /* # of args. allowed and compatability */
+# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */
+# define A(n) (1<<(n))
+# define VERSION_MASK 0xFF00 /* old awk is zero */
+# define NOT_OLD 0x0100 /* feature not in old awk */
+# define NOT_POSIX 0x0200 /* feature not in POSIX */
+# define GAWKX 0x0400 /* gawk extension */
+# define RESX 0x0800 /* Bell Labs Research extension */
+ NODE *(*ptr) P((NODE *)); /* function that implements this keyword */
+};
+
+/* Tokentab is sorted ascii ascending order, so it can be binary searched. */
+/* Function pointers come from declarations in awk.h. */
+
+static const struct token tokentab[] = {
+{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0},
+{"END", Node_illegal, LEX_END, 0, 0},
+#ifdef ARRAYDEBUG
+{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
+#endif
+{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
+{"asort", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asort},
+{"asorti", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asorti},
+{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
+{"bindtextdomain", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
+{"break", Node_K_break, LEX_BREAK, 0, 0},
+#ifdef ALLOW_SWITCH
+{"case", Node_K_case, LEX_CASE, GAWKX, 0},
+#endif
+{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
+{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
+{"continue", Node_K_continue, LEX_CONTINUE, 0, 0},
+{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
+{"dcgettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
+{"dcngettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
+#ifdef ALLOW_SWITCH
+{"default", Node_K_default, LEX_DEFAULT, GAWKX, 0},
+#endif
+{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0},
+{"do", Node_K_do, LEX_DO, NOT_OLD, 0},
+{"else", Node_illegal, LEX_ELSE, 0, 0},
+{"exit", Node_K_exit, LEX_EXIT, 0, 0},
+{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp},
+{"extension", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
+{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
+{"for", Node_K_for, LEX_FOR, 0, 0},
+{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
+{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0},
+{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub},
+{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0},
+{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub},
+{"if", Node_K_if, LEX_IF, 0, 0},
+{"in", Node_illegal, LEX_IN, 0, 0},
+{"index", Node_builtin, LEX_BUILTIN, A(2), do_index},
+{"int", Node_builtin, LEX_BUILTIN, A(1), do_int},
+{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length},
+{"log", Node_builtin, LEX_BUILTIN, A(1), do_log},
+{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
+{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
+{"mktime", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
+{"next", Node_K_next, LEX_NEXT, 0, 0},
+{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
+{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
+{"print", Node_K_print, LEX_PRINT, 0, 0},
+{"printf", Node_K_printf, LEX_PRINTF, 0, 0},
+{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
+{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0},
+{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
+{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
+{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split},
+{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf},
+{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt},
+{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
+#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
+{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
+#endif
+{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime},
+{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
+{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub},
+{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
+#ifdef ALLOW_SWITCH
+{"switch", Node_K_switch, LEX_SWITCH, GAWKX, 0},
+#endif
+{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
+{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
+{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
+{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
+{"while", Node_K_while, LEX_WHILE, 0, 0},
+{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
+};
+
+#ifdef MBS_SUPPORT
+/* Variable containing the current shift state. */
+static mbstate_t cur_mbstate;
+/* Ring buffer containing current characters. */
+#define MAX_CHAR_IN_RING_BUFFER 8
+#define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX)
+static char cur_char_ring[RING_BUFFER_SIZE];
+/* Index for ring buffers. */
+static int cur_ring_idx;
+/* This macro means that last nextc() return a singlebyte character
+ or 1st byte of a multibyte character. */
+#define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1)
+#else /* MBS_SUPPORT */
+/* a dummy */
+#define nextc_is_1stbyte 1
+#endif /* MBS_SUPPORT */
+
+/* getfname --- return name of a builtin function (for pretty printing) */
+
+const char *
+getfname(register NODE *(*fptr)(NODE *))
+{
+ register int i, j;
+
+ j = sizeof(tokentab) / sizeof(tokentab[0]);
+ /* linear search, no other way to do it */
+ for (i = 0; i < j; i++)
+ if (tokentab[i].ptr == fptr)
+ return tokentab[i].operator;
+
+ return NULL;
+}
+
+/* yyerror --- print a syntax error message, show where */
+
+/*
+ * Function identifier purposely indented to avoid mangling
+ * by ansi2knr. Sigh.
+ */
+
+static void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ yyerror(const char *m, ...)
+#else
+/* VARARGS0 */
+ yyerror(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+ const char *mesg = NULL;
+ register char *bp, *cp;
+ char *scan;
+ char *buf;
+ int count;
+ static char end_of_file_line[] = "(END OF FILE)";
+ char save;
+
+ errcount++;
+ /* Find the current line in the input file */
+ if (lexptr && lexeme) {
+ if (thisline == NULL) {
+ cp = lexeme;
+ if (*cp == '\n') {
+ cp--;
+ mesg = _("unexpected newline or end of string");
+ }
+ for (; cp != lexptr_begin && *cp != '\n'; --cp)
+ continue;
+ if (*cp == '\n')
+ cp++;
+ thisline = cp;
+ }
+ /* NL isn't guaranteed */
+ bp = lexeme;
+ while (bp < lexend && *bp && *bp != '\n')
+ bp++;
+ } else {
+ thisline = end_of_file_line;
+ bp = thisline + strlen(thisline);
+ }
+
+ /*
+ * Saving and restoring *bp keeps valgrind happy,
+ * since the guts of glibc uses strlen, even though
+ * we're passing an explict precision. Sigh.
+ *
+ * 8/2003: We may not need this anymore.
+ */
+ save = *bp;
+ *bp = '\0';
+
+ msg("%.*s", (int) (bp - thisline), thisline);
+
+ *bp = save;
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, m);
+ if (mesg == NULL)
+ mesg = m;
+#else
+ va_start(args);
+ if (mesg == NULL)
+ mesg = va_arg(args, char *);
+#endif
+ count = (bp - thisline) + strlen(mesg) + 2 + 1;
+ emalloc(buf, char *, count, "yyerror");
+
+ bp = buf;
+
+ if (lexptr != NULL) {
+ scan = thisline;
+ while (scan < lexeme)
+ if (*scan++ == '\t')
+ *bp++ = '\t';
+ else
+ *bp++ = ' ';
+ *bp++ = '^';
+ *bp++ = ' ';
+ }
+ strcpy(bp, mesg);
+ err("", buf, args);
+ va_end(args);
+ free(buf);
+}
+
+/* get_src_buf --- read the next buffer of source program */
+
+static char *
+get_src_buf()
+{
+ static int samefile = FALSE;
+ static int nextfile = 0;
+ static char *buf = NULL;
+ static size_t buflen = 0;
+ static int fd;
+
+ int n;
+ register char *scan;
+ int newfile;
+ struct stat sbuf;
+ int readcount = 0;
+ int l;
+ char *readloc;
+
+again:
+ newfile = FALSE;
+ if (nextfile > numfiles)
+ return NULL;
+
+ if (srcfiles[nextfile].stype == CMDLINE) {
+ if ((l = strlen(srcfiles[nextfile].val)) == 0) {
+ /*
+ * Yet Another Special case:
+ * gawk '' /path/name
+ * Sigh.
+ */
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("empty program text on command line"));
+ }
+ ++nextfile;
+ goto again;
+ }
+ if (srcfiles[nextfile].val[l-1] == '\n') {
+ /* has terminating newline, can use it directly */
+ sourceline = 1;
+ lexptr = lexptr_begin = srcfiles[nextfile].val;
+ /* fall through to pointer adjustment and return, below */
+ } else {
+ /* copy it into static buffer */
+
+ /* make sure buffer exists and has room */
+ if (buflen == 0) {
+ emalloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } else if (l+2 > buflen) {
+ erealloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } /* else
+ buffer has room, just use it */
+
+ /* copy in data */
+ memcpy(buf, srcfiles[nextfile].val, l);
+ buf[l] = '\n';
+ buf[++l] = '\0';
+
+ /* set vars and return */
+ lexptr = lexptr_begin = buf;
+ }
+ lexend = lexptr + l;
+ nextfile++; /* for next entry to this routine */
+ return lexptr;
+ }
+
+ if (! samefile) {
+ source = srcfiles[nextfile].val;
+ if (source == NULL) { /* read all the source files, all done */
+ if (buf != NULL) {
+ free(buf);
+ buf = NULL;
+ }
+ buflen = 0;
+ return lexeme = lexptr = lexptr_begin = NULL;
+ }
+ fd = pathopen(source);
+ if (fd <= INVALID_HANDLE) {
+ char *in;
+
+ /* suppress file name and line no. in error mesg */
+ in = source;
+ source = NULL;
+ fatal(_("can't open source file `%s' for reading (%s)"),
+ in, strerror(errno));
+ }
+ l = optimal_bufsize(fd, & sbuf);
+ /*
+ * Make sure that something silly like
+ * AWKBUFSIZE=8 make check
+ * works ok.
+ */
+#define A_DECENT_BUFFER_SIZE 128
+ if (l < A_DECENT_BUFFER_SIZE)
+ l = A_DECENT_BUFFER_SIZE;
+#undef A_DECENT_BUFFER_SIZE
+
+ newfile = TRUE;
+
+ /* make sure buffer exists and has room */
+ if (buflen == 0) {
+ emalloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } else if (l+2 > buflen) {
+ erealloc(buf, char *, l+2, "get_src_buf");
+ buflen = l + 2;
+ } /* else
+ buffer has room, just use it */
+
+ readcount = l;
+ readloc = lexeme = lexptr = lexptr_begin = buf;
+ samefile = TRUE;
+ sourceline = 1;
+ } else {
+ /*
+ * In same file, ran off edge of buffer.
+ * Shift current line down to front, adjust
+ * pointers and fill in the rest of the buffer.
+ */
+
+ int lexeme_offset = lexeme - lexptr_begin;
+ int lexptr_offset = lexptr - lexptr_begin;
+ int lexend_offset = lexend - lexptr_begin;
+
+ /* find beginning of current line */
+ for (scan = lexeme; scan >= lexptr_begin; scan--) {
+ if (*scan == '\n') {
+ scan++;
+ break;
+ }
+ }
+
+ if (scan <= buf) {
+ /* have to grow the buffer */
+ buflen *= 2;
+ erealloc(buf, char *, buflen, "get_src_buf");
+ } else {
+ /* shift things down */
+ memmove(buf, scan, lexend - scan);
+ /*
+ * make offsets relative to start of line,
+ * not start of buffer.
+ */
+ lexend_offset = lexend - scan;
+ lexeme_offset = lexeme - scan;
+ lexptr_offset = lexptr - scan;
+ }
+
+ /* adjust pointers */
+ lexeme = buf + lexeme_offset;
+ lexptr = buf + lexptr_offset;
+ lexend = buf + lexend_offset;
+ lexptr_begin = buf;
+ readcount = buflen - (lexend - buf);
+ readloc = lexend;
+ }
+
+ /* add more data to buffer */
+ n = read(fd, readloc, readcount);
+ if (n == -1)
+ fatal(_("can't read sourcefile `%s' (%s)"),
+ source, strerror(errno));
+ if (n == 0) {
+ if (newfile) {
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("source file `%s' is empty"), source);
+ }
+ }
+ if (fd != fileno(stdin)) /* safety */
+ close(fd);
+ samefile = FALSE;
+ nextfile++;
+ goto again;
+ }
+ lexend = lexptr + n;
+ return lexptr;
+}
+
+/* tokadd --- add a character to the token buffer */
+
+#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok)
+
+/* tokexpand --- grow the token buffer */
+
+char *
+tokexpand()
+{
+ static int toksize = 60;
+ int tokoffset;
+
+ tokoffset = tok - tokstart;
+ toksize *= 2;
+ if (tokstart != NULL)
+ erealloc(tokstart, char *, toksize, "tokexpand");
+ else
+ emalloc(tokstart, char *, toksize, "tokexpand");
+ tokend = tokstart + toksize;
+ tok = tokstart + tokoffset;
+ return tok;
+}
+
+/* nextc --- get the next input character */
+
+#ifdef MBS_SUPPORT
+
+static int
+nextc(void)
+{
+ if (gawk_mb_cur_max > 1) {
+ if (!lexptr || lexptr >= lexend) {
+ if (! get_src_buf())
+ return EOF;
+ }
+
+ /* Update the buffer index. */
+ cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 :
+ cur_ring_idx + 1;
+
+ /* Did we already check the current character? */
+ if (cur_char_ring[cur_ring_idx] == 0) {
+ /* No, we need to check the next character on the buffer. */
+ int idx, work_ring_idx = cur_ring_idx;
+ mbstate_t tmp_state;
+ size_t mbclen;
+
+ for (idx = 0 ; lexptr + idx < lexend ; idx++) {
+ tmp_state = cur_mbstate;
+ mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
+
+ if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) {
+ /* It is a singlebyte character, non-complete multibyte
+ character or EOF. We treat it as a singlebyte
+ character. */
+ cur_char_ring[work_ring_idx] = 1;
+ break;
+ } else if (mbclen == (size_t)-2) {
+ /* It is not a complete multibyte character. */
+ cur_char_ring[work_ring_idx] = idx + 1;
+ } else {
+ /* mbclen > 1 */
+ cur_char_ring[work_ring_idx] = mbclen;
+ break;
+ }
+ work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
+ 0 : work_ring_idx + 1;
+ }
+ cur_mbstate = tmp_state;
+
+ /* Put a mark on the position on which we write next character. */
+ work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
+ 0 : work_ring_idx + 1;
+ cur_char_ring[work_ring_idx] = 0;
+ }
+
+ return (int) (unsigned char) *lexptr++;
+ }
+ else {
+ int c;
+
+ if (lexptr && lexptr < lexend)
+ c = (int) (unsigned char) *lexptr++;
+ else if (get_src_buf())
+ c = (int) (unsigned char) *lexptr++;
+ else
+ c = EOF;
+
+ return c;
+ }
+}
+
+#else /* MBS_SUPPORT */
+
+#if GAWKDEBUG
+int
+nextc(void)
+{
+ int c;
+
+ if (lexptr && lexptr < lexend)
+ c = (int) (unsigned char) *lexptr++;
+ else if (get_src_buf())
+ c = (int) (unsigned char) *lexptr++;
+ else
+ c = EOF;
+
+ return c;
+}
+#else
+#define nextc() ((lexptr && lexptr < lexend) ? \
+ ((int) (unsigned char) *lexptr++) : \
+ (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \
+ )
+#endif
+
+#endif /* MBS_SUPPORT */
+
+/* pushback --- push a character back on the input */
+
+static inline void
+pushback(void)
+{
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1)
+ cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
+ cur_ring_idx - 1;
+#endif
+ (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
+}
+
+
+/* allow_newline --- allow newline after &&, ||, ? and : */
+
+static void
+allow_newline(void)
+{
+ int c;
+
+ for (;;) {
+ c = nextc();
+ if (c == EOF)
+ break;
+ if (c == '#') {
+ while ((c = nextc()) != '\n' && c != EOF)
+ continue;
+ if (c == EOF)
+ break;
+ }
+ if (c == '\n')
+ sourceline++;
+ if (! ISSPACE(c)) {
+ pushback();
+ break;
+ }
+ }
+}
+
+/* yylex --- Read the input and turn it into tokens. */
+
+static int
+yylex(void)
+{
+ register int c;
+ int seen_e = FALSE; /* These are for numbers */
+ int seen_point = FALSE;
+ int esc_seen; /* for literal strings */
+ int mid;
+ static int did_newline = FALSE;
+ char *tokkey;
+ static int lasttok = 0, eof_warned = FALSE;
+ int inhex = FALSE;
+ int intlstr = FALSE;
+
+ if (nextc() == EOF) {
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+ }
+ pushback();
+#if defined OS2 || defined __EMX__
+ /*
+ * added for OS/2's extproc feature of cmd.exe
+ * (like #! in BSD sh)
+ */
+ if (strncasecmp(lexptr, "extproc ", 8) == 0) {
+ while (*lexptr && *lexptr != '\n')
+ lexptr++;
+ }
+#endif
+ lexeme = lexptr;
+ thisline = NULL;
+ if (want_regexp) {
+ int in_brack = 0; /* count brackets, [[:alnum:]] allowed */
+ /*
+ * Counting brackets is non-trivial. [[] is ok,
+ * and so is [\]], with a point being that /[/]/ as a regexp
+ * constant has to work.
+ *
+ * Do not count [ or ] if either one is preceded by a \.
+ * A `[' should be counted if
+ * a) it is the first one so far (in_brack == 0)
+ * b) it is the `[' in `[:'
+ * A ']' should be counted if not preceded by a \, since
+ * it is either closing `:]' or just a plain list.
+ * According to POSIX, []] is how you put a ] into a set.
+ * Try to handle that too.
+ *
+ * The code for \ handles \[ and \].
+ */
+
+ want_regexp = FALSE;
+ tok = tokstart;
+ for (;;) {
+ c = nextc();
+
+ if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
+ case '[':
+ /* one day check for `.' and `=' too */
+ if (nextc() == ':' || in_brack == 0)
+ in_brack++;
+ pushback();
+ break;
+ case ']':
+ if (tokstart[0] == '['
+ && (tok == tokstart + 1
+ || (tok == tokstart + 2
+ && tokstart[1] == '^')))
+ /* do nothing */;
+ else
+ in_brack--;
+ break;
+ case '\\':
+ if ((c = nextc()) == EOF) {
+ yyerror(_("unterminated regexp ends with `\\' at end of file"));
+ goto end_regexp; /* kludge */
+ } else if (c == '\n') {
+ sourceline++;
+ continue;
+ } else {
+ tokadd('\\');
+ tokadd(c);
+ continue;
+ }
+ break;
+ case '/': /* end of the regexp */
+ if (in_brack > 0)
+ break;
+end_regexp:
+ tokadd('\0');
+ yylval.sval = tokstart;
+ if (do_lint) {
+ int peek = nextc();
+
+ pushback();
+ if (peek == 'i' || peek == 's') {
+ if (source)
+ lintwarn(
+ _("%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"),
+ source, sourceline, peek);
+ else
+ lintwarn(
+ _("tawk regex modifier `/.../%c' doesn't work in gawk"),
+ peek);
+ }
+ }
+ return lasttok = REGEXP;
+ case '\n':
+ pushback();
+ yyerror(_("unterminated regexp"));
+ goto end_regexp; /* kludge */
+ case EOF:
+ yyerror(_("unterminated regexp at end of file"));
+ goto end_regexp; /* kludge */
+ }
+ tokadd(c);
+ }
+ }
+retry:
+
+ /* skipping \r is a hack, but windows is just too pervasive. sigh. */
+ while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ continue;
+
+ lexeme = lexptr ? lexptr - 1 : lexptr;
+ thisline = NULL;
+ tok = tokstart;
+ yylval.nodetypeval = Node_illegal;
+
+ if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
+ case EOF:
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+
+ case '\n':
+ sourceline++;
+ return lasttok = NEWLINE;
+
+ case '#': /* it's a comment */
+ while ((c = nextc()) != '\n') {
+ if (c == EOF) {
+ if (lasttok != NEWLINE) {
+ lasttok = NEWLINE;
+ if (do_lint && ! eof_warned) {
+ lintwarn(
+ _("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ return NEWLINE; /* fake it */
+ }
+ return 0;
+ }
+ }
+ sourceline++;
+ return lasttok = NEWLINE;
+
+ case '\\':
+#ifdef RELAXED_CONTINUATION
+ /*
+ * This code puports to allow comments and/or whitespace
+ * after the `\' at the end of a line used for continuation.
+ * Use it at your own risk. We think it's a bad idea, which
+ * is why it's not on by default.
+ */
+ if (! do_traditional) {
+ /* strip trailing white-space and/or comment */
+ while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ continue;
+ if (c == '#') {
+ if (do_lint)
+ lintwarn(
+ _("use of `\\ #...' line continuation is not portable"));
+ while ((c = nextc()) != '\n')
+ if (c == EOF)
+ break;
+ }
+ pushback();
+ }
+#endif /* RELAXED_CONTINUATION */
+ if (nextc() == '\n') {
+ sourceline++;
+ goto retry;
+ } else {
+ yyerror(_("backslash not last character on line"));
+ exit(1);
+ }
+ break;
+
+ case ':':
+ case '?':
+ if (! do_posix)
+ allow_newline();
+ return lasttok = c;
+
+ /*
+ * in_parens is undefined unless we are parsing a print
+ * statement (in_print), but why bother with a check?
+ */
+ case ')':
+ in_parens--;
+ return lasttok = c;
+
+ case '(':
+ in_parens++;
+ /* FALL THROUGH */
+ case '$':
+ case ';':
+ case '{':
+ case ',':
+ case '[':
+ case ']':
+ return lasttok = c;
+
+ case '*':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_times;
+ return lasttok = ASSIGNOP;
+ } else if (do_posix) {
+ pushback();
+ return lasttok = '*';
+ } else if (c == '*') {
+ /* make ** and **= aliases for ^ and ^= */
+ static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+
+ if (nextc() == '=') {
+ if (! did_warn_assgn) {
+ did_warn_assgn = TRUE;
+ if (do_lint)
+ lintwarn(_("POSIX does not allow operator `**='"));
+ if (do_lint_old)
+ warning(_("old awk does not support operator `**='"));
+ }
+ yylval.nodetypeval = Node_assign_exp;
+ return ASSIGNOP;
+ } else {
+ pushback();
+ if (! did_warn_op) {
+ did_warn_op = TRUE;
+ if (do_lint)
+ lintwarn(_("POSIX does not allow operator `**'"));
+ if (do_lint_old)
+ warning(_("old awk does not support operator `**'"));
+ }
+ return lasttok = '^';
+ }
+ }
+ pushback();
+ return lasttok = '*';
+
+ case '/':
+ if (nextc() == '=') {
+ pushback();
+ return lasttok = SLASH_BEFORE_EQUAL;
+ }
+ pushback();
+ return lasttok = '/';
+
+ case '%':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_assign_mod;
+ return lasttok = ASSIGNOP;
+ }
+ pushback();
+ return lasttok = '%';
+
+ case '^':
+ {
+ static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+
+ if (nextc() == '=') {
+ if (do_lint_old && ! did_warn_assgn) {
+ did_warn_assgn = TRUE;
+ warning(_("operator `^=' is not supported in old awk"));
+ }
+ yylval.nodetypeval = Node_assign_exp;
+ return lasttok = ASSIGNOP;
+ }
+ pushback();
+ if (do_lint_old && ! did_warn_op) {
+ did_warn_op = TRUE;
+ warning(_("operator `^' is not supported in old awk"));
+ }
+ return lasttok = '^';
+ }
+
+ case '+':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_plus;
+ return lasttok = ASSIGNOP;
+ }
+ if (c == '+')
+ return lasttok = INCREMENT;
+ pushback();
+ return lasttok = '+';
+
+ case '!':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_notequal;
+ return lasttok = RELOP;
+ }
+ if (c == '~') {
+ yylval.nodetypeval = Node_nomatch;
+ return lasttok = MATCHOP;
+ }
+ pushback();
+ return lasttok = '!';
+
+ case '<':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_leq;
+ return lasttok = RELOP;
+ }
+ yylval.nodetypeval = Node_less;
+ pushback();
+ return lasttok = '<';
+
+ case '=':
+ if (nextc() == '=') {
+ yylval.nodetypeval = Node_equal;
+ return lasttok = RELOP;
+ }
+ yylval.nodetypeval = Node_assign;
+ pushback();
+ return lasttok = ASSIGN;
+
+ case '>':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_geq;
+ return lasttok = RELOP;
+ } else if (c == '>') {
+ yylval.nodetypeval = Node_redirect_append;
+ return lasttok = IO_OUT;
+ }
+ pushback();
+ if (in_print && in_parens == 0) {
+ yylval.nodetypeval = Node_redirect_output;
+ return lasttok = IO_OUT;
+ }
+ yylval.nodetypeval = Node_greater;
+ return lasttok = '>';
+
+ case '~':
+ yylval.nodetypeval = Node_match;
+ return lasttok = MATCHOP;
+
+ case '}':
+ /*
+ * Added did newline stuff. Easier than
+ * hacking the grammar.
+ */
+ if (did_newline) {
+ did_newline = FALSE;
+ return lasttok = c;
+ }
+ did_newline++;
+ --lexptr; /* pick up } next time */
+ return lasttok = NEWLINE;
+
+ case '"':
+ string:
+ esc_seen = FALSE;
+ while ((c = nextc()) != '"') {
+ if (c == '\n') {
+ pushback();
+ yyerror(_("unterminated string"));
+ exit(1);
+ }
+ if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
+ c == '\\') {
+ c = nextc();
+ if (c == '\n') {
+ sourceline++;
+ continue;
+ }
+ esc_seen = TRUE;
+ tokadd('\\');
+ }
+ if (c == EOF) {
+ pushback();
+ yyerror(_("unterminated string"));
+ exit(1);
+ }
+ tokadd(c);
+ }
+ yylval.nodeval = make_str_node(tokstart,
+ tok - tokstart, esc_seen ? SCAN : 0);
+ yylval.nodeval->flags |= PERM;
+ if (intlstr) {
+ yylval.nodeval->flags |= INTLSTR;
+ intlstr = FALSE;
+ if (do_intl)
+ dumpintlstr(yylval.nodeval->stptr,
+ yylval.nodeval->stlen);
+ }
+ return lasttok = YSTRING;
+
+ case '-':
+ if ((c = nextc()) == '=') {
+ yylval.nodetypeval = Node_assign_minus;
+ return lasttok = ASSIGNOP;
+ }
+ if (c == '-')
+ return lasttok = DECREMENT;
+ pushback();
+ return lasttok = '-';
+
+ case '.':
+ c = nextc();
+ pushback();
+ if (! ISDIGIT(c))
+ return lasttok = '.';
+ else
+ c = '.';
+ /* FALL THROUGH */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* It's a number */
+ for (;;) {
+ int gotnumber = FALSE;
+
+ tokadd(c);
+ switch (c) {
+ case 'x':
+ case 'X':
+ if (do_traditional)
+ goto done;
+ if (tok == tokstart + 2) {
+ int peek = nextc();
+
+ if (ISXDIGIT(peek)) {
+ inhex = TRUE;
+ pushback(); /* following digit */
+ } else {
+ pushback(); /* x or X */
+ goto done;
+ }
+ }
+ break;
+ case '.':
+ /* period ends exponent part of floating point number */
+ if (seen_point || seen_e) {
+ gotnumber = TRUE;
+ break;
+ }
+ seen_point = TRUE;
+ break;
+ case 'e':
+ case 'E':
+ if (inhex)
+ break;
+ if (seen_e) {
+ gotnumber = TRUE;
+ break;
+ }
+ seen_e = TRUE;
+ if ((c = nextc()) == '-' || c == '+') {
+ int c2 = nextc();
+
+ if (ISDIGIT(c2)) {
+ tokadd(c);
+ tokadd(c2);
+ } else {
+ pushback(); /* non-digit after + or - */
+ pushback(); /* + or - */
+ pushback(); /* e or E */
+ }
+ } else if (! ISDIGIT(c)) {
+ pushback(); /* character after e or E */
+ pushback(); /* e or E */
+ } else {
+ pushback(); /* digit */
+ }
+ break;
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'D':
+ case 'd':
+ case 'f':
+ case 'F':
+ if (do_traditional || ! inhex)
+ goto done;
+ /* fall through */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ break;
+ default:
+ done:
+ gotnumber = TRUE;
+ }
+ if (gotnumber)
+ break;
+ c = nextc();
+ }
+ if (c != EOF)
+ pushback();
+ else if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ tokadd('\0');
+ if (! do_traditional && isnondecimal(tokstart, FALSE)) {
+ if (do_lint) {
+ if (ISDIGIT(tokstart[1])) /* not an 'x' or 'X' */
+ lintwarn("numeric constant `%.*s' treated as octal",
+ (int) strlen(tokstart)-1, tokstart);
+ else if (tokstart[1] == 'x' || tokstart[1] == 'X')
+ lintwarn("numeric constant `%.*s' treated as hexadecimal",
+ (int) strlen(tokstart)-1, tokstart);
+ }
+ yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart)));
+ } else
+ yylval.nodeval = make_number(atof(tokstart));
+ yylval.nodeval->flags |= PERM;
+ return lasttok = YNUMBER;
+
+ case '&':
+ if ((c = nextc()) == '&') {
+ yylval.nodetypeval = Node_and;
+ allow_newline();
+ return lasttok = LEX_AND;
+ }
+ pushback();
+ return lasttok = '&';
+
+ case '|':
+ if ((c = nextc()) == '|') {
+ yylval.nodetypeval = Node_or;
+ allow_newline();
+ return lasttok = LEX_OR;
+ } else if (! do_traditional && c == '&') {
+ yylval.nodetypeval = Node_redirect_twoway;
+ return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
+ }
+ pushback();
+ if (in_print && in_parens == 0) {
+ yylval.nodetypeval = Node_redirect_pipe;
+ return lasttok = IO_OUT;
+ } else {
+ yylval.nodetypeval = Node_redirect_pipein;
+ return lasttok = IO_IN;
+ }
+ }
+
+ if (c != '_' && ! ISALPHA(c)) {
+ yyerror(_("invalid char '%c' in expression"), c);
+ exit(1);
+ }
+
+ /*
+ * Lots of fog here. Consider:
+ *
+ * print "xyzzy"$_"foo"
+ *
+ * Without the check for ` lasttok != '$' ', this is parsed as
+ *
+ * print "xxyzz" $(_"foo")
+ *
+ * With the check, it is "correctly" parsed as three
+ * string concatenations. Sigh. This seems to be
+ * "more correct", but this is definitely one of those
+ * occasions where the interactions are funny.
+ */
+ if (! do_traditional && c == '_' && lasttok != '$') {
+ if ((c = nextc()) == '"') {
+ intlstr = TRUE;
+ goto string;
+ }
+ pushback();
+ c = '_';
+ }
+
+ /* it's some type of name-type-thing. Find its length. */
+ tok = tokstart;
+ while (is_identchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ tokadd('\0');
+ emalloc(tokkey, char *, tok - tokstart, "yylex");
+ memcpy(tokkey, tokstart, tok - tokstart);
+ if (c != EOF)
+ pushback();
+ else if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+
+ /* See if it is a special token. */
+
+ if ((mid = check_special(tokstart)) >= 0) {
+ if (do_lint) {
+ if (tokentab[mid].flags & GAWKX)
+ lintwarn(_("`%s' is a gawk extension"),
+ tokentab[mid].operator);
+ if (tokentab[mid].flags & RESX)
+ lintwarn(_("`%s' is a Bell Labs extension"),
+ tokentab[mid].operator);
+ if (tokentab[mid].flags & NOT_POSIX)
+ lintwarn(_("POSIX does not allow `%s'"),
+ tokentab[mid].operator);
+ }
+ if (do_lint_old && (tokentab[mid].flags & NOT_OLD))
+ warning(_("`%s' is not supported in old awk"),
+ tokentab[mid].operator);
+ if ((do_traditional && (tokentab[mid].flags & GAWKX))
+ || (do_posix && (tokentab[mid].flags & NOT_POSIX)))
+ ;
+ else {
+ if (tokentab[mid].class == LEX_BUILTIN
+ || tokentab[mid].class == LEX_LENGTH)
+ yylval.lval = mid;
+ else
+ yylval.nodetypeval = tokentab[mid].value;
+ free(tokkey);
+ return lasttok = tokentab[mid].class;
+ }
+ }
+
+ yylval.sval = tokkey;
+ if (*lexptr == '(')
+ return lasttok = FUNC_CALL;
+ else {
+ static short goto_warned = FALSE;
+
+#define SMART_ALECK 1
+ if (SMART_ALECK && do_lint
+ && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
+ goto_warned = TRUE;
+ lintwarn(_("`goto' considered harmful!\n"));
+ }
+ return lasttok = NAME;
+ }
+}
+
+/* node_common --- common code for allocating a new node */
+
+static NODE *
+node_common(NODETYPE op)
+{
+ register NODE *r;
+
+ getnode(r);
+ r->type = op;
+ r->flags = MALLOC;
+ /* if lookahead is a NL, lineno is 1 too high */
+ if (lexeme && lexeme >= lexptr_begin && *lexeme == '\n')
+ r->source_line = sourceline - 1;
+ else
+ r->source_line = sourceline;
+ r->source_file = source;
+ return r;
+}
+
+/* node --- allocates a node with defined lnode and rnode. */
+
+NODE *
+node(NODE *left, NODETYPE op, NODE *right)
+{
+ register NODE *r;
+
+ r = node_common(op);
+ r->lnode = left;
+ r->rnode = right;
+ return r;
+}
+
+/* snode --- allocate a node with defined subnode and builtin for builtin
+ functions. Checks for arg. count and supplies defaults where
+ possible. */
+
+static NODE *
+snode(NODE *subn, NODETYPE op, int idx)
+{
+ register NODE *r;
+ register NODE *n;
+ int nexp = 0;
+ int args_allowed;
+
+ r = node_common(op);
+
+ /* traverse expression list to see how many args. given */
+ for (n = subn; n != NULL; n = n->rnode) {
+ nexp++;
+ if (nexp > 5)
+ break;
+ }
+
+ /* check against how many args. are allowed for this builtin */
+ args_allowed = tokentab[idx].flags & ARGS;
+ if (args_allowed && (args_allowed & A(nexp)) == 0)
+ fatal(_("%d is invalid as number of arguments for %s"),
+ nexp, tokentab[idx].operator);
+
+ r->builtin = tokentab[idx].ptr;
+
+ /* special case processing for a few builtins */
+ if (nexp == 0 && r->builtin == do_length) {
+ subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL);
+ } else if (r->builtin == do_match) {
+ static short warned = FALSE;
+
+ if (subn->rnode->lnode->type != Node_regex)
+ subn->rnode->lnode = mk_rexp(subn->rnode->lnode);
+
+ if (subn->rnode->rnode != NULL) { /* 3rd argument there */
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("match: third argument is a gawk extension"));
+ }
+ if (do_traditional)
+ fatal(_("match: third argument is a gawk extension"));
+ }
+ } else if (r->builtin == do_sub || r->builtin == do_gsub) {
+ if (subn->lnode->type != Node_regex)
+ subn->lnode = mk_rexp(subn->lnode);
+ if (nexp == 2)
+ append_right(subn, node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL));
+ else if (subn->rnode->rnode->lnode->type == Node_val) {
+ if (do_lint)
+ lintwarn(_("%s: string literal as last arg of substitute has no effect"),
+ (r->builtin == do_sub) ? "sub" : "gsub");
+ } else if (! isassignable(subn->rnode->rnode->lnode)) {
+ yyerror(_("%s third parameter is not a changeable object"),
+ (r->builtin == do_sub) ? "sub" : "gsub");
+ }
+ } else if (r->builtin == do_gensub) {
+ if (subn->lnode->type != Node_regex)
+ subn->lnode = mk_rexp(subn->lnode);
+ if (nexp == 3)
+ append_right(subn, node(node(make_number(0.0),
+ Node_field_spec,
+ (NODE *) NULL),
+ Node_expression_list,
+ (NODE *) NULL));
+ } else if (r->builtin == do_split) {
+ if (nexp == 2)
+ append_right(subn,
+ node(FS_node, Node_expression_list, (NODE *) NULL));
+ n = subn->rnode->rnode->lnode;
+ if (n->type != Node_regex)
+ subn->rnode->rnode->lnode = mk_rexp(n);
+ if (nexp == 2)
+ subn->rnode->rnode->lnode->re_flags |= FS_DFLT;
+ } else if (r->builtin == do_close) {
+ static short warned = FALSE;
+
+ if ( nexp == 2) {
+ if (do_lint && nexp == 2 && ! warned) {
+ warned = TRUE;
+ lintwarn(_("close: second argument is a gawk extension"));
+ }
+ if (do_traditional)
+ fatal(_("close: second argument is a gawk extension"));
+ }
+ } else if (do_intl /* --gen-po */
+ && r->builtin == do_dcgettext /* dcgettext(...) */
+ && subn->lnode->type == Node_val /* 1st arg is constant */
+ && (subn->lnode->flags & STRCUR) != 0) { /* it's a string constant */
+ /* ala xgettext, dcgettext("some string" ...) dumps the string */
+ NODE *str = subn->lnode;
+
+ if ((str->flags & INTLSTR) != 0)
+ warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore"));
+ /* don't dump it, the lexer already did */
+ else
+ dumpintlstr(str->stptr, str->stlen);
+ } else if (do_intl /* --gen-po */
+ && r->builtin == do_dcngettext /* dcngettext(...) */
+ && subn->lnode->type == Node_val /* 1st arg is constant */
+ && (subn->lnode->flags & STRCUR) != 0 /* it's a string constant */
+ && subn->rnode->lnode->type == Node_val /* 2nd arg is constant too */
+ && (subn->rnode->lnode->flags & STRCUR) != 0) { /* it's a string constant */
+ /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */
+ NODE *str1 = subn->lnode;
+ NODE *str2 = subn->rnode->lnode;
+
+ if (((str1->flags | str2->flags) & INTLSTR) != 0)
+ warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore"));
+ else
+ dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen);
+ }
+
+ r->subnode = subn;
+ if (r->builtin == do_sprintf) {
+ count_args(r);
+ r->lnode->printf_count = r->printf_count; /* hack */
+ }
+ return r;
+}
+
+/* make_for_loop --- build a for loop */
+
+static NODE *
+make_for_loop(NODE *init, NODE *cond, NODE *incr)
+{
+ register FOR_LOOP_HEADER *r;
+ NODE *n;
+
+ emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop");
+ getnode(n);
+ n->type = Node_illegal;
+ r->init = init;
+ r->cond = cond;
+ r->incr = incr;
+ n->sub.nodep.r.hd = r;
+ return n;
+}
+
+/* dup_parms --- return TRUE if there are duplicate parameters */
+
+static int
+dup_parms(NODE *func)
+{
+ register NODE *np;
+ const char *fname, **names;
+ int count, i, j, dups;
+ NODE *params;
+
+ if (func == NULL) /* error earlier */
+ return TRUE;
+
+ fname = func->param;
+ count = func->param_cnt;
+ params = func->rnode;
+
+ if (count == 0) /* no args, no problem */
+ return FALSE;
+
+ if (params == NULL) /* error earlier */
+ return TRUE;
+
+ emalloc(names, const char **, count * sizeof(char *), "dup_parms");
+
+ i = 0;
+ for (np = params; np != NULL; np = np->rnode) {
+ if (np->param == NULL) { /* error earlier, give up, go home */
+ free(names);
+ return TRUE;
+ }
+ names[i++] = np->param;
+ }
+
+ dups = 0;
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (strcmp(names[i], names[j]) == 0) {
+ dups++;
+ error(
+ _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
+ fname, i+1, names[j], j+1);
+ }
+ }
+ }
+
+ free(names);
+ return (dups > 0 ? TRUE : FALSE);
+}
+
+/* parms_shadow --- check if parameters shadow globals */
+
+static int
+parms_shadow(const char *fname, NODE *func)
+{
+ int count, i;
+ int ret = FALSE;
+
+ if (fname == NULL || func == NULL) /* error earlier */
+ return FALSE;
+
+ count = func->lnode->param_cnt;
+
+ if (count == 0) /* no args, no problem */
+ return FALSE;
+
+ /*
+ * Use warning() and not lintwarn() so that can warn
+ * about all shadowed parameters.
+ */
+ for (i = 0; i < count; i++) {
+ if (lookup(func->parmlist[i]) != NULL) {
+ warning(
+ _("function `%s': parameter `%s' shadows global variable"),
+ fname, func->parmlist[i]);
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * install:
+ * Install a name in the symbol table, even if it is already there.
+ * Caller must check against redefinition if that is desired.
+ */
+
+NODE *
+install(char *name, NODE *value)
+{
+ register NODE *hp;
+ register size_t len;
+ register int bucket;
+
+ var_count++;
+ len = strlen(name);
+ bucket = hash(name, len, (unsigned long) HASHSIZE);
+ getnode(hp);
+ hp->type = Node_hashnode;
+ hp->hnext = variables[bucket];
+ variables[bucket] = hp;
+ hp->hlength = len;
+ hp->hvalue = value;
+ hp->hname = name;
+ hp->hvalue->vname = name;
+ return hp->hvalue;
+}
+
+/* lookup --- find the most recent hash node for name installed by install */
+
+NODE *
+lookup(const char *name)
+{
+ register NODE *bucket;
+ register size_t len;
+
+ len = strlen(name);
+ for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)];
+ bucket != NULL; bucket = bucket->hnext)
+ if (bucket->hlength == len && STREQN(bucket->hname, name, len))
+ return bucket->hvalue;
+
+ return NULL;
+}
+
+/* var_comp --- compare two variable names */
+
+static int
+var_comp(const void *v1, const void *v2)
+{
+ const NODE *const *npp1, *const *npp2;
+ const NODE *n1, *n2;
+ int minlen;
+
+ npp1 = (const NODE *const *) v1;
+ npp2 = (const NODE *const *) v2;
+ n1 = *npp1;
+ n2 = *npp2;
+
+ if (n1->hlength > n2->hlength)
+ minlen = n1->hlength;
+ else
+ minlen = n2->hlength;
+
+ return strncmp(n1->hname, n2->hname, minlen);
+}
+
+/* valinfo --- dump var info */
+
+static void
+valinfo(NODE *n, FILE *fp)
+{
+ if (n->flags & STRING) {
+ fprintf(fp, "string (");
+ pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
+ fprintf(fp, ")\n");
+ } else if (n->flags & NUMBER)
+ fprintf(fp, "number (%.17g)\n", n->numbr);
+ else if (n->flags & STRCUR) {
+ fprintf(fp, "string value (");
+ pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
+ fprintf(fp, ")\n");
+ } else if (n->flags & NUMCUR)
+ fprintf(fp, "number value (%.17g)\n", n->numbr);
+ else
+ fprintf(fp, "?? flags %s\n", flags2str(n->flags));
+}
+
+
+/* dump_vars --- dump the symbol table */
+
+void
+dump_vars(const char *fname)
+{
+ int i, j;
+ NODE **table;
+ NODE *p;
+ FILE *fp;
+
+ emalloc(table, NODE **, var_count * sizeof(NODE *), "dump_vars");
+
+ if (fname == NULL)
+ fp = stderr;
+ else if ((fp = fopen(fname, "w")) == NULL) {
+ warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno));
+ warning(_("sending profile to standard error"));
+ fp = stderr;
+ }
+
+ for (i = j = 0; i < HASHSIZE; i++)
+ for (p = variables[i]; p != NULL; p = p->hnext)
+ table[j++] = p;
+
+ assert(j == var_count);
+
+ /* Shazzam! */
+ qsort(table, j, sizeof(NODE *), var_comp);
+
+ for (i = 0; i < j; i++) {
+ p = table[i];
+ if (p->hvalue->type == Node_func)
+ continue;
+ fprintf(fp, "%.*s: ", (int) p->hlength, p->hname);
+ if (p->hvalue->type == Node_var_array)
+ fprintf(fp, "array, %ld elements\n", p->hvalue->table_size);
+ else if (p->hvalue->type == Node_var_new)
+ fprintf(fp, "unused variable\n");
+ else if (p->hvalue->type == Node_var)
+ valinfo(p->hvalue->var_value, fp);
+ else {
+ NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
+
+ valinfo(*lhs, fp);
+ }
+ }
+
+ if (fp != stderr && fclose(fp) != 0)
+ warning(_("%s: close failed (%s)"), fname, strerror(errno));
+
+ free(table);
+}
+
+/* release_all_vars --- free all variable memory */
+
+void
+release_all_vars()
+{
+ int i;
+ NODE *p, *next;
+
+ for (i = 0; i < HASHSIZE; i++)
+ for (p = variables[i]; p != NULL; p = next) {
+ next = p->hnext;
+
+ if (p->hvalue->type == Node_func)
+ continue;
+ else if (p->hvalue->type == Node_var_array)
+ assoc_clear(p->hvalue);
+ else if (p->hvalue->type != Node_var_new) {
+ NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
+
+ unref(*lhs);
+ }
+ unref(p);
+ }
+}
+
+/* finfo --- for use in comparison and sorting of function names */
+
+struct finfo {
+ const char *name;
+ size_t nlen;
+ NODE *func;
+};
+
+/* fcompare --- comparison function for qsort */
+
+static int
+fcompare(const void *p1, const void *p2)
+{
+ const struct finfo *f1, *f2;
+ int minlen;
+
+ f1 = (const struct finfo *) p1;
+ f2 = (const struct finfo *) p2;
+
+ if (f1->nlen > f2->nlen)
+ minlen = f2->nlen;
+ else
+ minlen = f1->nlen;
+
+ return strncmp(f1->name, f2->name, minlen);
+}
+
+/* dump_funcs --- print all functions */
+
+void
+dump_funcs()
+{
+ int i, j;
+ NODE *p;
+ struct finfo *tab = NULL;
+
+ /*
+ * Walk through symbol table countng functions.
+ * Could be more than func_count if there are
+ * extension functions.
+ */
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ j++;
+ }
+ }
+ }
+
+ if (j == 0)
+ return;
+
+ emalloc(tab, struct finfo *, j * sizeof(struct finfo), "dump_funcs");
+
+ /* now walk again, copying info */
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ tab[j].name = p->hname;
+ tab[j].nlen = p->hlength;
+ tab[j].func = p->hvalue;
+ j++;
+ }
+ }
+ }
+
+
+ /* Shazzam! */
+ qsort(tab, j, sizeof(struct finfo), fcompare);
+
+ for (i = 0; i < j; i++)
+ pp_func(tab[i].name, tab[i].nlen, tab[i].func);
+
+ free(tab);
+}
+
+/* shadow_funcs --- check all functions for parameters that shadow globals */
+
+void
+shadow_funcs()
+{
+ int i, j;
+ NODE *p;
+ struct finfo *tab;
+ static int calls = 0;
+ int shadow = FALSE;
+
+ if (func_count == 0)
+ return;
+
+ if (calls++ != 0)
+ fatal(_("shadow_funcs() called twice!"));
+
+ emalloc(tab, struct finfo *, func_count * sizeof(struct finfo), "shadow_funcs");
+
+ for (i = j = 0; i < HASHSIZE; i++) {
+ for (p = variables[i]; p != NULL; p = p->hnext) {
+ if (p->hvalue->type == Node_func) {
+ tab[j].name = p->hname;
+ tab[j].nlen = p->hlength;
+ tab[j].func = p->hvalue;
+ j++;
+ }
+ }
+ }
+
+ assert(j == func_count);
+
+ /* Shazzam! */
+ qsort(tab, func_count, sizeof(struct finfo), fcompare);
+
+ for (i = 0; i < j; i++)
+ shadow |= parms_shadow(tab[i].name, tab[i].func);
+
+ free(tab);
+
+ /* End with fatal if the user requested it. */
+ if (shadow && lintfunc != warning)
+ lintwarn(_("there were shadowed variables."));
+}
+
+/*
+ * append_right:
+ * Add new to the rightmost branch of LIST. This uses n^2 time, so we make
+ * a simple attempt at optimizing it.
+ */
+
+static NODE *
+append_right(NODE *list, NODE *new)
+{
+ register NODE *oldlist;
+ static NODE *savefront = NULL, *savetail = NULL;
+
+ if (list == NULL || new == NULL)
+ return list;
+
+ oldlist = list;
+ if (savefront == oldlist)
+ list = savetail; /* Be careful: maybe list->rnode != NULL */
+ else
+ savefront = oldlist;
+
+ while (list->rnode != NULL)
+ list = list->rnode;
+ savetail = list->rnode = new;
+ return oldlist;
+}
+
+/*
+ * append_pattern:
+ * A wrapper around append_right, used for rule lists.
+ */
+static inline NODE *
+append_pattern(NODE **list, NODE *patt)
+{
+ NODE *n = node(patt, Node_rule_node, (NODE *) NULL);
+
+ if (*list == NULL)
+ *list = n;
+ else {
+ NODE *n1 = node(n, Node_rule_list, (NODE *) NULL);
+ if ((*list)->type != Node_rule_list)
+ *list = node(*list, Node_rule_list, n1);
+ else
+ (void) append_right(*list, n1);
+ }
+ return n;
+}
+
+/*
+ * func_install:
+ * check if name is already installed; if so, it had better have Null value,
+ * in which case def is added as the value. Otherwise, install name with def
+ * as value.
+ *
+ * Extra work, build up and save a list of the parameter names in a table
+ * and hang it off params->parmlist. This is used to set the `vname' field
+ * of each function parameter during a function call. See eval.c.
+ */
+
+static void
+func_install(NODE *params, NODE *def)
+{
+ NODE *r, *n, *thisfunc;
+ char **pnames, *names, *sp;
+ size_t pcount = 0, space = 0;
+ int i;
+
+ /* check for function foo(foo) { ... }. bleah. */
+ for (n = params->rnode; n != NULL; n = n->rnode) {
+ if (strcmp(n->param, params->param) == 0)
+ fatal(_("function `%s': can't use function name as parameter name"),
+ params->param);
+ }
+
+ thisfunc = NULL; /* turn off warnings */
+
+ /* symbol table managment */
+ pop_var(params, FALSE);
+ r = lookup(params->param);
+ if (r != NULL) {
+ fatal(_("function name `%s' previously defined"), params->param);
+ } else if (params->param == builtin_func) /* not a valid function name */
+ goto remove_params;
+
+ /* install the function */
+ thisfunc = node(params, Node_func, def);
+ (void) install(params->param, thisfunc);
+
+ /* figure out amount of space to allocate for variable names */
+ for (n = params->rnode; n != NULL; n = n->rnode) {
+ pcount++;
+ space += strlen(n->param) + 1;
+ }
+
+ /* allocate it and fill it in */
+ if (pcount != 0) {
+ emalloc(names, char *, space, "func_install");
+ emalloc(pnames, char **, pcount * sizeof(char *), "func_install");
+ sp = names;
+ for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode) {
+ pnames[i] = sp;
+ strcpy(sp, n->param);
+ sp += strlen(n->param) + 1;
+ }
+ thisfunc->parmlist = pnames;
+ } else {
+ thisfunc->parmlist = NULL;
+ }
+
+ /* update lint table info */
+ func_use(params->param, FUNC_DEFINE);
+
+ func_count++; /* used by profiling / pretty printer */
+
+remove_params:
+ /* remove params from symbol table */
+ pop_params(params->rnode);
+}
+
+/* pop_var --- remove a variable from the symbol table */
+
+static void
+pop_var(NODE *np, int freeit)
+{
+ register NODE *bucket, **save;
+ register size_t len;
+ char *name;
+
+ name = np->param;
+ len = strlen(name);
+ save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]);
+ for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
+ if (len == bucket->hlength && STREQN(bucket->hname, name, len)) {
+ var_count--;
+ *save = bucket->hnext;
+ freenode(bucket);
+ if (freeit)
+ free(np->param);
+ return;
+ }
+ save = &(bucket->hnext);
+ }
+}
+
+/* pop_params --- remove list of function parameters from symbol table */
+
+/*
+ * pop parameters out of the symbol table. do this in reverse order to
+ * avoid reading freed memory if there were duplicated parameters.
+ */
+static void
+pop_params(NODE *params)
+{
+ if (params == NULL)
+ return;
+ pop_params(params->rnode);
+ pop_var(params, TRUE);
+}
+
+/* make_param --- make NAME into a function parameter */
+
+static NODE *
+make_param(char *name)
+{
+ NODE *r;
+
+ getnode(r);
+ r->type = Node_param_list;
+ r->rnode = NULL;
+ r->param = name;
+ r->param_cnt = param_counter++;
+ return (install(name, r));
+}
+
+static struct fdesc {
+ char *name;
+ short used;
+ short defined;
+ struct fdesc *next;
+} *ftable[HASHSIZE];
+
+/* func_use --- track uses and definitions of functions */
+
+static void
+func_use(const char *name, enum defref how)
+{
+ struct fdesc *fp;
+ int len;
+ int ind;
+
+ len = strlen(name);
+ ind = hash(name, len, HASHSIZE);
+
+ for (fp = ftable[ind]; fp != NULL; fp = fp->next) {
+ if (strcmp(fp->name, name) == 0) {
+ if (how == FUNC_DEFINE)
+ fp->defined++;
+ else
+ fp->used++;
+ return;
+ }
+ }
+
+ /* not in the table, fall through to allocate a new one */
+
+ emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use");
+ memset(fp, '\0', sizeof(struct fdesc));
+ emalloc(fp->name, char *, len + 1, "func_use");
+ strcpy(fp->name, name);
+ if (how == FUNC_DEFINE)
+ fp->defined++;
+ else
+ fp->used++;
+ fp->next = ftable[ind];
+ ftable[ind] = fp;
+}
+
+/* check_funcs --- verify functions that are called but not defined */
+
+static void
+check_funcs()
+{
+ struct fdesc *fp, *next;
+ int i;
+
+ for (i = 0; i < HASHSIZE; i++) {
+ for (fp = ftable[i]; fp != NULL; fp = fp->next) {
+#ifdef REALLYMEAN
+ /* making this the default breaks old code. sigh. */
+ if (fp->defined == 0) {
+ error(
+ _("function `%s' called but never defined"), fp->name);
+ errcount++;
+ }
+#else
+ if (do_lint && fp->defined == 0)
+ lintwarn(
+ _("function `%s' called but never defined"), fp->name);
+#endif
+ if (do_lint && fp->used == 0) {
+ lintwarn(_("function `%s' defined but never called"),
+ fp->name);
+ }
+ }
+ }
+
+ /* now let's free all the memory */
+ for (i = 0; i < HASHSIZE; i++) {
+ for (fp = ftable[i]; fp != NULL; fp = next) {
+ next = fp->next;
+ free(fp->name);
+ free(fp);
+ }
+ }
+}
+
+/* param_sanity --- look for parameters that are regexp constants */
+
+static void
+param_sanity(NODE *arglist)
+{
+ NODE *argp, *arg;
+ int i;
+
+ for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) {
+ arg = argp->lnode;
+ if (arg->type == Node_regex)
+ warning(_("regexp constant for parameter #%d yields boolean value"), i);
+ }
+}
+
+/* deferred varibles --- those that are only defined if needed. */
+
+/*
+ * Is there any reason to use a hash table for deferred variables? At the
+ * moment, there are only 1 to 3 such variables, so it may not be worth
+ * the overhead. If more modules start using this facility, it should
+ * probably be converted into a hash table.
+ */
+
+static struct deferred_variable {
+ NODE *(*load_func)(void);
+ struct deferred_variable *next;
+ char name[1]; /* variable-length array */
+} *deferred_variables;
+
+/* register_deferred_variable --- add a var name and loading function to the list */
+
+void
+register_deferred_variable(const char *name, NODE *(*load_func)(void))
+{
+ struct deferred_variable *dv;
+ size_t sl = strlen(name);
+
+ emalloc(dv, struct deferred_variable *, sizeof(*dv)+sl,
+ "register_deferred_variable");
+ dv->load_func = load_func;
+ dv->next = deferred_variables;
+ memcpy(dv->name, name, sl+1);
+ deferred_variables = dv;
+}
+
+/* variable --- make sure NAME is in the symbol table */
+
+NODE *
+variable(char *name, int can_free, NODETYPE type)
+{
+ register NODE *r;
+
+ if ((r = lookup(name)) != NULL) {
+ if (r->type == Node_func)
+ fatal(_("function `%s' called with space between name and `(',\nor used as a variable or an array"),
+ r->vname);
+
+ } else {
+ /* not found */
+ struct deferred_variable *dv;
+
+ for (dv = deferred_variables; TRUE; dv = dv->next) {
+ if (dv == NULL) {
+ /*
+ * This is the only case in which we may not
+ * free the string.
+ */
+ NODE *n;
+
+ if (type == Node_var_array)
+ n = node(NULL, type, NULL);
+ else
+ n = node(Nnull_string, type, NULL);
+
+ return install(name, n);
+ }
+ if (STREQ(name, dv->name)) {
+ r = (*dv->load_func)();
+ break;
+ }
+ }
+ }
+ if (can_free)
+ free(name);
+ return r;
+}
+
+/* mk_rexp --- make a regular expression constant */
+
+static NODE *
+mk_rexp(NODE *exp)
+{
+ NODE *n;
+
+ if (exp->type == Node_regex)
+ return exp;
+
+ getnode(n);
+ n->type = Node_dynregex;
+ n->re_exp = exp;
+ n->re_text = NULL;
+ n->re_reg = NULL;
+ n->re_flags = 0;
+ n->re_cnt = 1;
+ return n;
+}
+
+/* isnoeffect --- when used as a statement, has no side effects */
+
+/*
+ * To be completely general, we should recursively walk the parse
+ * tree, to make sure that all the subexpressions also have no effect.
+ * Instead, we just weaken the actual warning that's printed, up above
+ * in the grammar.
+ */
+
+static int
+isnoeffect(NODETYPE type)
+{
+ switch (type) {
+ case Node_times:
+ case Node_quotient:
+ case Node_mod:
+ case Node_plus:
+ case Node_minus:
+ case Node_subscript:
+ case Node_concat:
+ case Node_exp:
+ case Node_unary_minus:
+ case Node_field_spec:
+ case Node_and:
+ case Node_or:
+ case Node_equal:
+ case Node_notequal:
+ case Node_less:
+ case Node_greater:
+ case Node_leq:
+ case Node_geq:
+ case Node_match:
+ case Node_nomatch:
+ case Node_not:
+ case Node_val:
+ case Node_in_array:
+ case Node_NF:
+ case Node_NR:
+ case Node_FNR:
+ case Node_FS:
+ case Node_RS:
+ case Node_FIELDWIDTHS:
+ case Node_IGNORECASE:
+ case Node_OFS:
+ case Node_ORS:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_BINMODE:
+ case Node_LINT:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ return TRUE;
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+
+ return FALSE;
+}
+
+/* isassignable --- can this node be assigned to? */
+
+static int
+isassignable(register NODE *n)
+{
+ switch (n->type) {
+ case Node_var_new:
+ case Node_var:
+ case Node_FIELDWIDTHS:
+ case Node_RS:
+ case Node_FS:
+ case Node_FNR:
+ case Node_NR:
+ case Node_NF:
+ case Node_IGNORECASE:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_ORS:
+ case Node_OFS:
+ case Node_LINT:
+ case Node_BINMODE:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ case Node_field_spec:
+ case Node_subscript:
+ return TRUE;
+ case Node_param_list:
+ return ((n->flags & FUNC) == 0); /* ok if not func name */
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+ return FALSE;
+}
+
+/* stopme --- for debugging */
+
+NODE *
+stopme(NODE *tree ATTRIBUTE_UNUSED)
+{
+ return (NODE *) 0;
+}
+
+/* dumpintlstr --- write out an initial .po file entry for the string */
+
+static void
+dumpintlstr(const char *str, size_t len)
+{
+ char *cp;
+
+ /* See the GNU gettext distribution for details on the file format */
+
+ if (source != NULL) {
+ /* ala the gettext sources, remove leading `./'s */
+ for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
+ continue;
+ printf("#: %s:%d\n", cp, sourceline);
+ }
+
+ printf("msgid ");
+ pp_string_fp(stdout, str, len, '"', TRUE);
+ putchar('\n');
+ printf("msgstr \"\"\n\n");
+ fflush(stdout);
+}
+
+/* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */
+
+static void
+dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
+{
+ char *cp;
+
+ /* See the GNU gettext distribution for details on the file format */
+
+ if (source != NULL) {
+ /* ala the gettext sources, remove leading `./'s */
+ for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
+ continue;
+ printf("#: %s:%d\n", cp, sourceline);
+ }
+
+ printf("msgid ");
+ pp_string_fp(stdout, str1, len1, '"', TRUE);
+ putchar('\n');
+ printf("msgid_plural ");
+ pp_string_fp(stdout, str2, len2, '"', TRUE);
+ putchar('\n');
+ printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
+ fflush(stdout);
+}
+
+/* count_args --- count the number of printf arguments */
+
+static void
+count_args(NODE *tree)
+{
+ size_t count = 0;
+ NODE *save_tree;
+
+ assert(tree->type == Node_K_printf
+ || (tree->type == Node_builtin && tree->builtin == do_sprintf));
+ save_tree = tree;
+
+ tree = tree->lnode; /* printf format string */
+
+ for (count = 0; tree != NULL; tree = tree->rnode)
+ count++;
+
+ save_tree->printf_count = count;
+}
+
+/* isarray --- can this type be subscripted? */
+
+static int
+isarray(NODE *n)
+{
+ switch (n->type) {
+ case Node_var_new:
+ case Node_var_array:
+ return TRUE;
+ case Node_param_list:
+ return (n->flags & FUNC) == 0;
+ case Node_array_ref:
+ cant_happen();
+ break;
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+
+ return FALSE;
+}
+
+/* See if name is a special token. */
+
+int
+check_special(const char *name)
+{
+ int low, high, mid;
+ int i;
+
+ low = 0;
+ high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1;
+ while (low <= high) {
+ mid = (low + high) / 2;
+ i = *name - tokentab[mid].operator[0];
+ if (i == 0)
+ i = strcmp(name, tokentab[mid].operator);
+
+ if (i < 0) /* token < mid */
+ high = mid - 1;
+ else if (i > 0) /* token > mid */
+ low = mid + 1;
+ else
+ return mid;
+ }
+ return -1;
+}
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon Jun 20 23:20:22 2005 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.am: Install pwcat and grcat in pkglibexecdir instead of
+ libexecdir.
+
+Wed Feb 9 10:13:27 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pkgdatadir, pkglibexecdir): Use $(datadir) and
+ $(libexecdir) instead of @datadir@ and @libexecdir@ for coolest
+ GNU Coding Standards compatibility and functionality. Per Stepan
+ Kasal.
+
+Tue Feb 8 18:57:08 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pkgdatadir, pkglibexecdir): New variables for compatibility
+ with current GNU Coding Standards. Fixed uses. Thanks to Stepan Kasal
+ and the discussion in bug-gnu-utils.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Thu Mar 18 17:43:59 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (INCLUDES): Renamed to AM_CPPFLAGS. Per
+ Stepan Kasal.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Thu Oct 10 13:24:09 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (INCLUDES): Added to get .. for build dir
+ which will have config.h in it.
+ (grcat,pwcat): Use $(COMPILE) instead of $(CC) to get
+ $(INCLUDES) included.
+
+Tue Jun 11 23:43:36 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (grcat): Add def for config.h and -I flag.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Wed Apr 17 15:20:27 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clean): Add *.exe to list of files to be cleaned.
+
+2002-01-27 Bruno Haible <bruno@clisp.org>
+
+ * eg/lib/libintl.awk (dcngettext): New function.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+2001-02-26 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.am (stamp-eg): Use $(AWK), not awk, as the
+ native awk might not work.
+
+2001-02-26 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.am: Install igawk as script.
+
+Mon Nov 6 15:29:08 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Fixed to have all functionality from before
+ the switch to automake.
+ * extract.awk: Updated to match version in the doc.
+
+Sat Jul 26 23:08:29 1997 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (install-strip): new target.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Sun Apr 13 15:40:55 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): fix second for loop to use $$i. Sigh.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Wed Dec 25 11:17:32 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): remove chmod command; let
+ $(INSTALL_PROGRAM) use -m.
+
+Tue Dec 17 22:29:49 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): fix installation of files in eg/lib.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Sun Oct 20 12:30:41 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): minor tweaks for portability.
+
+Fri Mar 15 06:33:38 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pwcat, grcat): Add $(LDFLAGS).
+ (clean): add `*~' to list of files to be removed.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): Remove $(AUXAWK).
+ (maintainer-clean): Depend on distclean, not the other way around.
--- /dev/null
+#
+# awklib/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1995-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+## process this file with automake to produce Makefile.in
+
+EXTRA_DIST = ChangeLog extract.awk eg stamp-eg
+
+# Get config.h from the build directory and custom.h from the source directory.
+AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
+
+pkgdatadir = $(datadir)/awk
+pkglibexecdir = $(libexecdir)/awk
+
+bin_SCRIPTS = igawk
+pkglibexec_PROGRAMS = pwcat grcat
+AUXAWK = passwd.awk group.awk
+nodist_grcat_SOURCES = grcat.c
+nodist_pwcat_SOURCES = pwcat.c
+
+all: stamp-eg $(AUXPROGS) igawk $(AUXAWK)
+
+install-exec-hook: $(AUXAWK)
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ for i in $(AUXAWK) $(srcdir)/eg/lib/*.awk ; do \
+ progname=`echo $$i | sed 's;.*/;;'` ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(pkgdatadir)/$$progname ; \
+ done
+
+# pkglibexecdir and pkgdatadir are removed in the top level Makefile's uninstall
+uninstall-local:
+ rm -fr $(DESTDIR)$(pkglibexecdir)/* $(DESTDIR)$(pkgdatadir)/*
+ rm -f $(DESTDIR)$(bindir)/igawk
+
+clean-local:
+ rm -f $(AUXAWK) igawk *.exe
+
+stamp-eg: $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
+ rm -fr eg stamp-eg
+ $(AWK) -f $(srcdir)/extract.awk $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
+ @echo 'some makes are stupid and will not check a directory' > stamp-eg
+ @echo 'against a file, so this file is a place holder. gack.' >> stamp-eg
+
+pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
+ $(COMPILE) $(srcdir)/eg/lib/pwcat.c $(LDFLAGS) -o $@
+
+grcat$(EXEEXT): $(srcdir)/eg/lib/grcat.c
+ $(COMPILE) $(srcdir)/eg/lib/grcat.c $(LDFLAGS) -o $@
+
+igawk: $(srcdir)/eg/prog/igawk.sh
+ cp $(srcdir)/eg/prog/igawk.sh $@ ; chmod 755 $@
+
+passwd.awk: $(srcdir)/eg/lib/passwdawk.in
+ sed 's;/usr/local/libexec/awk;$(pkglibexecdir);' < $(srcdir)/eg/lib/passwdawk.in > passwd.awk
+
+group.awk: $(srcdir)/eg/lib/groupawk.in
+ sed 's;/usr/local/libexec/awk;$(pkglibexecdir);' < $(srcdir)/eg/lib/groupawk.in > group.awk
--- /dev/null
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# awklib/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1995-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+
+SOURCES = $(nodist_grcat_SOURCES) $(nodist_pwcat_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+pkglibexec_PROGRAMS = pwcat$(EXEEXT) grcat$(EXEEXT)
+subdir = awklib
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/socket.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/strtod.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)"
+pkglibexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(pkglibexec_PROGRAMS)
+nodist_grcat_OBJECTS = grcat.$(OBJEXT)
+grcat_OBJECTS = $(nodist_grcat_OBJECTS)
+grcat_LDADD = $(LDADD)
+nodist_pwcat_OBJECTS = pwcat.$(OBJEXT)
+pwcat_OBJECTS = $(nodist_pwcat_OBJECTS)
+pwcat_LDADD = $(LDADD)
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(nodist_grcat_SOURCES) $(nodist_pwcat_SOURCES)
+DIST_SOURCES =
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = $(datadir)/awk
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMSGFMT = @GMSGFMT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+STRIP = @STRIP@
+U = @U@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+EXTRA_DIST = ChangeLog extract.awk eg stamp-eg
+
+# Get config.h from the build directory and custom.h from the source directory.
+AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
+pkglibexecdir = $(libexecdir)/awk
+bin_SCRIPTS = igawk
+AUXAWK = passwd.awk group.awk
+nodist_grcat_SOURCES = grcat.c
+nodist_pwcat_SOURCES = pwcat.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu awklib/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu awklib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pkglibexecPROGRAMS: $(pkglibexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibexecdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibexecdir)"
+ @list='$(pkglibexec_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(pkglibexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(pkglibexecdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(pkglibexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(pkglibexecdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-pkglibexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglibexec_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(pkglibexecdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkglibexecdir)/$$f"; \
+ done
+
+clean-pkglibexecPROGRAMS:
+ -test -z "$(pkglibexec_PROGRAMS)" || rm -f $(pkglibexec_PROGRAMS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grcat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwcat.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-local clean-pkglibexecPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binSCRIPTS install-pkglibexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-info-am uninstall-local \
+ uninstall-pkglibexecPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-local clean-pkglibexecPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binSCRIPTS install-data install-data-am install-exec \
+ install-exec-am install-exec-hook install-info install-info-am \
+ install-man install-pkglibexecPROGRAMS install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binSCRIPTS uninstall-info-am \
+ uninstall-local uninstall-pkglibexecPROGRAMS
+
+
+all: stamp-eg $(AUXPROGS) igawk $(AUXAWK)
+
+install-exec-hook: $(AUXAWK)
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ for i in $(AUXAWK) $(srcdir)/eg/lib/*.awk ; do \
+ progname=`echo $$i | sed 's;.*/;;'` ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(pkgdatadir)/$$progname ; \
+ done
+
+# pkglibexecdir and pkgdatadir are removed in the top level Makefile's uninstall
+uninstall-local:
+ rm -fr $(DESTDIR)$(pkglibexecdir)/* $(DESTDIR)$(pkgdatadir)/*
+ rm -f $(DESTDIR)$(bindir)/igawk
+
+clean-local:
+ rm -f $(AUXAWK) igawk *.exe
+
+stamp-eg: $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
+ rm -fr eg stamp-eg
+ $(AWK) -f $(srcdir)/extract.awk $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
+ @echo 'some makes are stupid and will not check a directory' > stamp-eg
+ @echo 'against a file, so this file is a place holder. gack.' >> stamp-eg
+
+pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
+ $(COMPILE) $(srcdir)/eg/lib/pwcat.c $(LDFLAGS) -o $@
+
+grcat$(EXEEXT): $(srcdir)/eg/lib/grcat.c
+ $(COMPILE) $(srcdir)/eg/lib/grcat.c $(LDFLAGS) -o $@
+
+igawk: $(srcdir)/eg/prog/igawk.sh
+ cp $(srcdir)/eg/prog/igawk.sh $@ ; chmod 755 $@
+
+passwd.awk: $(srcdir)/eg/lib/passwdawk.in
+ sed 's;/usr/local/libexec/awk;$(pkglibexecdir);' < $(srcdir)/eg/lib/passwdawk.in > passwd.awk
+
+group.awk: $(srcdir)/eg/lib/groupawk.in
+ sed 's;/usr/local/libexec/awk;$(pkglibexecdir);' < $(srcdir)/eg/lib/groupawk.in > group.awk
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+aardvark 555-5553 1200/300 B
+alpo-net 555-3412 2400/1200/300 A
+barfly 555-7685 1200/300 A
+bites 555-1675 2400/1200/300 A
+camelot 555-0542 300 C
+core 555-2912 1200/300 C
+fooey 555-1234 2400/1200/300 B
+foot 555-6699 1200/300 B
+macfoo 555-6480 1200/300 A
+sdace 555-3430 2400/1200/300 A
+sabafoo 555-2127 1200/300 C
--- /dev/null
+#: guide.awk:4
+msgid "Don't Panic"
+msgstr "Hey man, relax!"
+
+#: guide.awk:5
+msgid "The Answer Is"
+msgstr "Like, the scoop is"
+
--- /dev/null
+#: guide.awk:4
+msgid "Don't Panic"
+msgstr ""
+
+#: guide.awk:5
+msgid "The Answer Is"
+msgstr ""
+
--- /dev/null
+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
--- /dev/null
+# assert --- assert that a condition is true. Otherwise exit.
+
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May, 1993
+
+function assert(condition, string)
+{
+ if (! condition) {
+ printf("%s:%d: assertion failed: %s\n",
+ FILENAME, FNR, string) > "/dev/stderr"
+ _assert_exit = 1
+ exit 1
+ }
+}
+
+END {
+ if (_assert_exit)
+ exit 1
+}
--- /dev/null
+# 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
+}
--- /dev/null
+# cliff_rand.awk --- generate Cliff random numbers
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# December 2000
+
+BEGIN { _cliff_seed = 0.1 }
+
+function cliff_rand()
+{
+ _cliff_seed = (100 * log(_cliff_seed)) % 1
+ if (_cliff_seed < 0)
+ _cliff_seed = - _cliff_seed
+ return _cliff_seed
+}
--- /dev/null
+# ctime.awk
+#
+# awk version of C ctime(3) function
+
+function ctime(ts, format)
+{
+ format = "%a %b %d %H:%M:%S %Z %Y"
+ if (ts == 0)
+ ts = systime() # use current time as default
+ return strftime(format, ts)
+}
--- /dev/null
+# ftrans.awk --- handle data file transitions
+#
+# user supplies beginfile() and endfile() functions
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# November 1992
+
+FNR == 1 {
+ if (_filename_ != "")
+ endfile(_filename_)
+ _filename_ = FILENAME
+ beginfile(FILENAME)
+}
+
+END { endfile(_filename_) }
--- /dev/null
+# getopt.awk --- do C library getopt(3) function in awk
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+#
+# Initial version: March, 1991
+# Revised: May, 1993
+
+# External variables:
+# Optind -- index in ARGV of first nonoption argument
+# Optarg -- string value of argument to current option
+# Opterr -- if nonzero, print our own diagnostic
+# Optopt -- current option letter
+
+# Returns:
+# -1 at end of options
+# ? for unrecognized option
+# <c> a character representing the current option
+
+# Private Data:
+# _opti -- index in multi-flag option, e.g., -abc
+function getopt(argc, argv, options, thisopt, i)
+{
+ if (length(options) == 0) # no options given
+ return -1
+
+ if (argv[Optind] == "--") { # all done
+ Optind++
+ _opti = 0
+ return -1
+ } else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) {
+ _opti = 0
+ return -1
+ }
+ if (_opti == 0)
+ _opti = 2
+ thisopt = substr(argv[Optind], _opti, 1)
+ Optopt = thisopt
+ i = index(options, thisopt)
+ if (i == 0) {
+ if (Opterr)
+ printf("%c -- invalid option\n",
+ thisopt) > "/dev/stderr"
+ if (_opti >= length(argv[Optind])) {
+ Optind++
+ _opti = 0
+ } else
+ _opti++
+ return "?"
+ }
+ if (substr(options, i + 1, 1) == ":") {
+ # get option argument
+ if (length(substr(argv[Optind], _opti + 1)) > 0)
+ Optarg = substr(argv[Optind], _opti + 1)
+ else
+ Optarg = argv[++Optind]
+ _opti = 0
+ } else
+ Optarg = ""
+ if (_opti == 0 || _opti >= length(argv[Optind])) {
+ Optind++
+ _opti = 0
+ } else
+ _opti++
+ return thisopt
+}
+BEGIN {
+ Opterr = 1 # default is to diagnose
+ Optind = 1 # skip ARGV[0]
+
+ # test program
+ if (_getopt_test) {
+ while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
+ printf("c = <%c>, optarg = <%s>\n",
+ _go_c, Optarg)
+ printf("non-option arguments:\n")
+ for (; Optind < ARGC; Optind++)
+ printf("\tARGV[%d] = <%s>\n",
+ Optind, ARGV[Optind])
+ }
+}
--- /dev/null
+# gettimeofday.awk --- get the time of day in a usable format
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain, May 1993
+#
+
+# Returns a string in the format of output of date(1)
+# Populates the array argument time with individual values:
+# time["second"] -- seconds (0 - 59)
+# time["minute"] -- minutes (0 - 59)
+# time["hour"] -- hours (0 - 23)
+# time["althour"] -- hours (0 - 12)
+# time["monthday"] -- day of month (1 - 31)
+# time["month"] -- month of year (1 - 12)
+# time["monthname"] -- name of the month
+# time["shortmonth"] -- short name of the month
+# time["year"] -- year modulo 100 (0 - 99)
+# time["fullyear"] -- full year
+# time["weekday"] -- day of week (Sunday = 0)
+# time["altweekday"] -- day of week (Monday = 0)
+# time["dayname"] -- name of weekday
+# time["shortdayname"] -- short name of weekday
+# time["yearday"] -- day of year (0 - 365)
+# time["timezone"] -- abbreviation of timezone name
+# time["ampm"] -- AM or PM designation
+# time["weeknum"] -- week number, Sunday first day
+# time["altweeknum"] -- week number, Monday first day
+
+function gettimeofday(time, ret, now, i)
+{
+ # get time once, avoids unnecessary system calls
+ now = systime()
+
+ # return date(1)-style output
+ ret = strftime("%a %b %d %H:%M:%S %Z %Y", now)
+
+ # clear out target array
+ delete time
+
+ # fill in values, force numeric values to be
+ # numeric by adding 0
+ time["second"] = strftime("%S", now) + 0
+ time["minute"] = strftime("%M", now) + 0
+ time["hour"] = strftime("%H", now) + 0
+ time["althour"] = strftime("%I", now) + 0
+ time["monthday"] = strftime("%d", now) + 0
+ time["month"] = strftime("%m", now) + 0
+ time["monthname"] = strftime("%B", now)
+ time["shortmonth"] = strftime("%b", now)
+ time["year"] = strftime("%y", now) + 0
+ time["fullyear"] = strftime("%Y", now) + 0
+ time["weekday"] = strftime("%w", now) + 0
+ time["altweekday"] = strftime("%u", now) + 0
+ time["dayname"] = strftime("%A", now)
+ time["shortdayname"] = strftime("%a", now)
+ time["yearday"] = strftime("%j", now) + 0
+ time["timezone"] = strftime("%Z", now)
+ time["ampm"] = strftime("%p", now)
+ time["weeknum"] = strftime("%U", now) + 0
+ time["altweeknum"] = strftime("%W", now) + 0
+
+ return ret
+}
--- /dev/null
+/*
+ * grcat.c
+ *
+ * Generate a printable version of the group database
+ */
+/*
+ * Arnold Robbins, arnold@gnu.org, May 1993
+ * Public Domain
+ */
+
+/* For OS/2, do nothing. */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (STDC_HEADERS)
+#include <stdlib.h>
+#endif
+
+#ifndef HAVE_GETGRENT
+int main() { return 0; }
+#else
+#include <stdio.h>
+#include <grp.h>
+
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ struct group *g;
+ int i;
+
+ while ((g = getgrent()) != NULL) {
+ printf("%s:%s:%ld:", g->gr_name, g->gr_passwd,
+ (long) g->gr_gid);
+ for (i = 0; g->gr_mem[i] != NULL; i++) {
+ printf("%s", g->gr_mem[i]);
+ if (g->gr_mem[i+1] != NULL)
+ putchar(',');
+ }
+ putchar('\n');
+ }
+ endgrent();
+ return 0;
+}
+#endif /* HAVE_GETGRENT */
--- /dev/null
+# group.awk --- functions for dealing with the group file
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised October 2000
+
+BEGIN \
+{
+ # Change to suit your system
+ _gr_awklib = "/usr/local/libexec/awk/"
+}
+
+function _gr_init( oldfs, oldrs, olddol0, grcat,
+ using_fw, n, a, i)
+{
+ if (_gr_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ 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_count] = $0
+ }
+ close(grcat)
+ _gr_count = 0
+ _gr_inited++
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+}
+function getgrnam(group)
+{
+ _gr_init()
+ if (group in _gr_byname)
+ return _gr_byname[group]
+ return ""
+}
+function getgrgid(gid)
+{
+ _gr_init()
+ if (gid in _gr_bygid)
+ return _gr_bygid[gid]
+ return ""
+}
+function getgruser(user)
+{
+ _gr_init()
+ if (user in _gr_groupsbyuser)
+ return _gr_groupsbyuser[user]
+ return ""
+}
+function getgrent()
+{
+ _gr_init()
+ if (++_gr_count in _gr_bycount)
+ return _gr_bycount[_gr_count]
+ return ""
+}
+function endgrent()
+{
+ _gr_count = 0
+}
--- /dev/null
+# join.awk --- join an array into a string
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+function join(array, start, end, sep, result, i)
+{
+ if (sep == "")
+ sep = " "
+ else if (sep == SUBSEP) # magic value
+ sep = ""
+ result = array[start]
+ for (i = start + 1; i <= end; i++)
+ result = result sep array[i]
+ return result
+}
--- /dev/null
+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)
+}
--- /dev/null
+# nextfile --- skip remaining records in current file
+# correctly handle successive occurrences of the same file
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May, 1993
+
+# this should be read in before the "main" awk program
+
+function nextfile() { _abandon_ = FILENAME; next }
+
+_abandon_ == FILENAME {
+ if (FNR == 1)
+ _abandon_ = ""
+ else
+ next
+}
--- /dev/null
+# noassign.awk --- library file to avoid the need for a
+# special option that disables command-line assignments
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# October 1999
+
+function disable_assigns(argc, argv, i)
+{
+ for (i = 1; i < argc; i++)
+ if (argv[i] ~ /^[A-Za-z_][A-Za-z_0-9]*=.*/)
+ argv[i] = ("./" argv[i])
+}
+
+BEGIN {
+ if (No_command_assign)
+ disable_assigns(ARGC, ARGV)
+}
--- /dev/null
+# ord.awk --- do ord and chr
+
+# Global identifiers:
+# _ord_: numerical values indexed by characters
+# _ord_init: function to initialize _ord_
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# 16 January, 1992
+# 20 July, 1992, revised
+
+BEGIN { _ord_init() }
+
+function _ord_init( low, high, i, t)
+{
+ low = sprintf("%c", 7) # BEL is ascii 7
+ if (low == "\a") { # regular ascii
+ low = 0
+ high = 127
+ } else if (sprintf("%c", 128 + 7) == "\a") {
+ # ascii, mark parity
+ low = 128
+ high = 255
+ } else { # ebcdic(!)
+ low = 0
+ high = 255
+ }
+
+ for (i = low; i <= high; i++) {
+ t = sprintf("%c", i)
+ _ord_[t] = i
+ }
+}
+function ord(str, c)
+{
+ # only first character is of interest
+ c = substr(str, 1, 1)
+ return _ord_[c]
+}
+
+function chr(c)
+{
+ # force c to be numeric by adding 0
+ return sprintf("%c", c + 0)
+}
--- /dev/null
+# passwd.awk --- access password file information
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised October 2000
+
+BEGIN {
+ # tailor this to suit your system
+ _pw_awklib = "/usr/local/libexec/awk/"
+}
+
+function _pw_init( oldfs, oldrs, olddol0, pwcat, using_fw)
+{
+ if (_pw_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ FS = ":"
+ RS = "\n"
+
+ pwcat = _pw_awklib "pwcat"
+ while ((pwcat | getline) > 0) {
+ _pw_byname[$1] = $0
+ _pw_byuid[$3] = $0
+ _pw_bycount[++_pw_total] = $0
+ }
+ close(pwcat)
+ _pw_count = 0
+ _pw_inited = 1
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+}
+function getpwnam(name)
+{
+ _pw_init()
+ if (name in _pw_byname)
+ return _pw_byname[name]
+ return ""
+}
+function getpwuid(uid)
+{
+ _pw_init()
+ if (uid in _pw_byuid)
+ return _pw_byuid[uid]
+ return ""
+}
+function getpwent()
+{
+ _pw_init()
+ if (_pw_count < _pw_total)
+ return _pw_bycount[++_pw_count]
+ return ""
+}
+function endpwent()
+{
+ _pw_count = 0
+}
--- /dev/null
+/*
+ * pwcat.c
+ *
+ * Generate a printable version of the password database
+ */
+/*
+ * Arnold Robbins, arnold@gnu.org, May 1993
+ * Public Domain
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pwd.h>
+
+#if defined (STDC_HEADERS)
+#include <stdlib.h>
+#endif
+
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ struct passwd *p;
+
+ while ((p = getpwent()) != NULL)
+ 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);
+
+ endpwent();
+ return 0;
+}
--- /dev/null
+# readable.awk --- library file to skip over unreadable files
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# October 2000
+
+BEGIN {
+ for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] ~ /^[A-Za-z_][A-Za-z0-9_]*=.*/ \
+ || ARGV[i] == "-")
+ continue # assignment or standard input
+ else if ((getline junk < ARGV[i]) < 0) # unreadable
+ delete ARGV[i]
+ else
+ close(ARGV[i])
+ }
+}
--- /dev/null
+# rewind.awk --- rewind the current file and start over
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# September 2000
+
+function rewind( i)
+{
+ # shift remaining arguments up
+ for (i = ARGC; i > ARGIND; i--)
+ ARGV[i] = ARGV[i-1]
+
+ # make sure gawk knows to keep going
+ ARGC++
+
+ # make current file next to get done
+ ARGV[ARGIND+1] = FILENAME
+
+ # do it
+ nextfile
+}
--- /dev/null
+# round.awk --- do normal rounding
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# August, 1996
+
+function round(x, ival, aval, fraction)
+{
+ ival = int(x) # integer part, int() truncates
+
+ # see if fractional part
+ if (ival == x) # no fraction
+ return x
+
+ if (x < 0) {
+ aval = -x # absolute value
+ ival = int(aval)
+ fraction = aval - ival
+ if (fraction >= .5)
+ return int(x) - 1 # -2.5 --> -3
+ else
+ return int(x) # -2.3 --> -2
+ } else {
+ fraction = x - ival
+ if (fraction >= .5)
+ return ival + 1
+ else
+ return ival
+ }
+}
+
+# test harness
+{ print $0, round($0) }
--- /dev/null
+# strtonum --- convert string to number
+
+#
+# Arnold Robbins, arnold@skeeve.com, Public Domain
+# February, 2004
+
+function mystrtonum(str, ret, chars, n, i, k, c)
+{
+ if (str ~ /^0[0-7]*$/) {
+ # octal
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ if ((k = index("01234567", c)) > 0)
+ k-- # adjust for 1-basing in awk
+
+ ret = ret * 8 + k
+ }
+ } else if (str ~ /^0[xX][0-9a-fA-f]+/) {
+ # hexadecimal
+ str = substr(str, 3) # lop off leading 0x
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ c = tolower(c)
+ if ((k = index("0123456789", c)) > 0)
+ k-- # adjust for 1-basing in awk
+ else if ((k = index("abcdef", c)) > 0)
+ k += 9
+
+ ret = ret * 16 + k
+ }
+ } else if (str ~ /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) {
+ # decimal number, possibly floating point
+ ret = str + 0
+ } else
+ ret = "NOT-A-NUMBER"
+
+ return ret
+}
+
+# BEGIN { # gawk test harness
+# 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[7] = "1.32E2"
+#
+# for (i = 1; i in a; i++)
+# print a[i], strtonum(a[i]), mystrtonum(a[i])
+# }
--- /dev/null
+# zerofile.awk --- library file to process empty input files
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# June 2003
+
+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)
+}
--- /dev/null
+{
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
+}
+
+END {
+ for (x = 1; x <= max; x++)
+ print arr[x]
+}
--- /dev/null
+5 I am the Five man
+2 Who are you? The new number two!
+4 . . . And four on the floor
+1 Who is number one?
+3 I three you.
--- /dev/null
+{
+ if ($1 == "FIND")
+ regex = $2
+ else {
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at",
+ where, "in", $0
+ }
+}
--- /dev/null
+FIND ru+n
+My program runs
+but not very quickly
+FIND Melvin
+JF+KM
+This line is property of Reality Engineering Co.
+Melvin was here.
--- /dev/null
+#!/bin/sh
+MobAg=/tmp/MobileAgent.$$
+# direct script to mobile agent file
+cat > $MobAg
+# execute agent concurrently
+gawk -f $MobAg $MobAg > /dev/null &
+# HTTP header, terminator and body
+gawk 'BEGIN { print "\r\nAgent started" }'
+rm $MobAg # delete script file of agent
--- /dev/null
+# CGI Library and core of a web server
+#
+# Juergen Kahrs, Juergen.Kahrs@vr-web.de
+# with Arnold Robbins, arnold@gnu.org
+# September 2000
+
+# Global arrays
+# GETARG --- arguments to CGI GET command
+# MENU --- menu items (path names)
+# PARAM --- parameters of form x=y
+
+# Optional variable MyHost contains host address
+# Optional variable MyPort contains port number
+# Needs TopHeader, TopDoc, TopFooter
+# Sets MyPrefix, HttpService, Status, Reason
+
+BEGIN {
+ if (MyHost == "") {
+ "uname -n" | getline MyHost
+ close("uname -n")
+ }
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ MyPrefix = "http://" MyHost ":" MyPort
+ SetUpServer()
+ while ("awk" != "complex") {
+ # header lines are terminated this way
+ RS = ORS = "\r\n"
+ Status = 200 # this means OK
+ Reason = "OK"
+ Header = TopHeader
+ Document = TopDoc
+ Footer = TopFooter
+ if (GETARG["Method"] == "GET") {
+ HandleGET()
+ } else if (GETARG["Method"] == "HEAD") {
+ # not yet implemented
+ } else if (GETARG["Method"] != "") {
+ print "bad method", GETARG["Method"]
+ }
+ Prompt = Header Document Footer
+ print "HTTP/1.0", Status, Reason |& HttpService
+ print "Connection: Close" |& HttpService
+ print "Pragma: no-cache" |& HttpService
+ len = length(Prompt) + length(ORS)
+ print "Content-length:", len |& HttpService
+ print ORS Prompt |& HttpService
+ # ignore all the header lines
+ while ((HttpService |& getline) > 0)
+ continue
+ # stop talking to this client
+ close(HttpService)
+ # wait for new client request
+ HttpService |& getline
+ # do some logging
+ print systime(), strftime(), $0
+ CGI_setup($1, $2, $3)
+ }
+}
+
+function CGI_setup( method, uri, version, i)
+{
+ delete GETARG
+ delete MENU
+ delete PARAM
+ GETARG["Method"] = method
+ GETARG["URI"] = uri
+ GETARG["Version"] = version
+
+ i = index(uri, "?")
+ if (i > 0) { # is there a "?" indicating a CGI request?
+ split(substr(uri, 1, i-1), MENU, "[/:]")
+ split(substr(uri, i+1), PARAM, "&")
+ for (i in PARAM) {
+ PARAM[i] = _CGI_decode(PARAM[i])
+ j = index(PARAM[i], "=")
+ GETARG[substr(PARAM[i], 1, j-1)] = \
+ substr(PARAM[i], j+1)
+ }
+ } else { # there is no "?", no need for splitting PARAMs
+ split(uri, MENU, "[/:]")
+ }
+ for (i in MENU) # decode characters in path
+ if (i > 4) # but not those in host name
+ MENU[i] = _CGI_decode(MENU[i])
+}
+function _CGI_decode(str, hexdigs, i, pre, code1, code2,
+ val, result)
+{
+ hexdigs = "123456789abcdef"
+
+ i = index(str, "%")
+ if (i == 0) # no work to do
+ return str
+
+ do {
+ pre = substr(str, 1, i-1) # part before %xx
+ code1 = substr(str, i+1, 1) # first hex digit
+ code2 = substr(str, i+2, 1) # second hex digit
+ str = substr(str, i+3) # rest of string
+
+ code1 = tolower(code1)
+ code2 = tolower(code2)
+ val = index(hexdigs, code1) * 16 \
+ + index(hexdigs, code2)
+
+ result = result pre sprintf("%c", val)
+ i = index(str, "%")
+ } while (i != 0)
+ if (length(str) > 0)
+ result = result str
+ return result
+}
--- /dev/null
+function SetUpServer() {
+ SetUpEliza()
+ TopHeader = \
+ "<HTML><title>An HTTP-based System with GAWK</title>\
+ <HEAD><META HTTP-EQUIV=\"Content-Type\"\
+ CONTENT=\"text/html; charset=iso-8859-1\"></HEAD>\
+ <BODY BGCOLOR=\"#ffffff\" TEXT=\"#000000\"\
+ LINK=\"#0000ff\" VLINK=\"#0000ff\"\
+ ALINK=\"#0000ff\"> <A NAME=\"top\">"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI>\
+ <A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ </LI><LI>\
+ <A HREF=" MyPrefix "/AboutELIZA>About Eliza</A></LI>\
+ <LI>\
+ <A HREF=" MyPrefix \
+ "/StartELIZA>Start talking to Eliza</A></LI></UL>"
+ TopFooter = "</BODY></HTML>"
+}
+function HandleGET() {
+ # A real HTTP server would treat some parts of the URI as a file name.
+ # We take parts of the URI as menu choices and go on accordingly.
+ if(MENU[2] == "AboutServer") {
+ Document = "This is not a CGI script.\
+ This is an httpd, an HTML file, and a CGI script all \
+ in one GAWK script. It needs no separate www-server, \
+ no installation, and no root privileges.\
+ <p>To run it, do this:</p><ul>\
+ <li> start this script with \"gawk -f httpserver.awk\",</li>\
+ <li> and on the same host let your www browser open location\
+ \"http://localhost:8080\"</li>\
+ </ul>\<p>\ Details of HTTP come from:</p><ul>\
+ <li>Hethmon: Illustrated Guide to HTTP</p>\
+ <li>RFC 2068</li></ul><p>JK 14.9.1997</p>"
+ } else if (MENU[2] == "AboutELIZA") {
+ Document = "This is an implementation of the famous ELIZA\
+ program by Joseph Weizenbaum. It is written in GAWK and\
+/bin/sh: expad: command not found
+ } else if (MENU[2] == "StartELIZA") {
+ gsub(/\+/, " ", GETARG["YouSay"])
+ # Here we also have to substitute coded special characters
+ Document = "<form method=GET>" \
+ "<h3>" ElizaSays(GETARG["YouSay"]) "</h3>\
+ <p><input type=text name=YouSay value=\"\" size=60>\
+ <br><input type=submit value=\"Tell her about it\"></p></form>"
+ }
+}
+function ElizaSays(YouSay) {
+ if (YouSay == "") {
+ cost = 0
+ answer = "HI, IM ELIZA, TELL ME YOUR PROBLEM"
+ } else {
+ q = toupper(YouSay)
+ gsub("'", "", q)
+ if(q == qold) {
+ answer = "PLEASE DONT REPEAT YOURSELF !"
+ } else {
+ if (index(q, "SHUT UP") > 0) {
+ answer = "WELL, PLEASE PAY YOUR BILL. ITS EXACTLY ... $"\
+ int(100*rand()+30+cost/100)
+ } else {
+ qold = q
+ w = "-" # no keyword recognized yet
+ for (i in k) { # search for keywords
+ if (index(q, i) > 0) {
+ w = i
+ break
+ }
+ }
+ if (w == "-") { # no keyword, take old subject
+ w = wold
+ subj = subjold
+ } else { # find subject
+ subj = substr(q, index(q, w) + length(w)+1)
+ wold = w
+ subjold = subj # remember keyword and subject
+ }
+ for (i in conj)
+ gsub(i, conj[i], q) # conjugation
+ # from all answers to this keyword, select one randomly
+ answer = r[indices[int(split(k[w], indices) * rand()) + 1]]
+ # insert subject into answer
+ gsub("_", subj, answer)
+ }
+ }
+ }
+ cost += length(answer) # for later payment : 1 cent per character
+ return answer
+}
+function SetUpEliza() {
+ srand()
+ wold = "-"
+ subjold = " "
+
+ # table for conjugation
+ conj[" ARE " ] = " AM "
+ conj["WERE " ] = "WAS "
+ conj[" YOU " ] = " I "
+ conj["YOUR " ] = "MY "
+ conj[" IVE " ] =\
+ conj[" I HAVE " ] = " YOU HAVE "
+ conj[" YOUVE " ] =\
+ conj[" YOU HAVE "] = " I HAVE "
+ conj[" IM " ] =\
+ conj[" I AM " ] = " YOU ARE "
+ conj[" YOURE " ] =\
+ conj[" YOU ARE " ] = " I AM "
+
+ # table of all answers
+ r[1] = "DONT YOU BELIEVE THAT I CAN _"
+ r[2] = "PERHAPS YOU WOULD LIKE TO BE ABLE TO _ ?"
+ r[3] = "YOU WANT ME TO BE ABLE TO _ ?"
+ r[4] = "PERHAPS YOU DONT WANT TO _ "
+ r[5] = "DO YOU WANT TO BE ABLE TO _ ?"
+ r[6] = "WHAT MAKES YOU THINK I AM _ ?"
+ r[7] = "DOES IT PLEASE YOU TO BELIEVE I AM _ ?"
+ r[8] = "PERHAPS YOU WOULD LIKE TO BE _ ?"
+ r[9] = "DO YOU SOMETIMES WISH YOU WERE _ ?"
+ r[10] = "DONT YOU REALLY _ ?"
+ r[11] = "WHY DONT YOU _ ?"
+ r[12] = "DO YOU WISH TO BE ABLE TO _ ?"
+ r[13] = "DOES THAT TROUBLE YOU ?"
+ r[14] = "TELL ME MORE ABOUT SUCH FEELINGS"
+ r[15] = "DO YOU OFTEN FEEL _ ?"
+ r[16] = "DO YOU ENJOY FEELING _ ?"
+ r[17] = "DO YOU REALLY BELIEVE I DONT _ ?"
+ r[18] = "PERHAPS IN GOOD TIME I WILL _ "
+ r[19] = "DO YOU WANT ME TO _ ?"
+ r[20] = "DO YOU THINK YOU SHOULD BE ABLE TO _ ?"
+ r[21] = "WHY CANT YOU _ ?"
+ r[22] = "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM _ ?"
+ r[23] = "WOULD YOU PREFER IF I WERE NOT _ ?"
+ r[24] = "PERHAPS IN YOUR FANTASIES I AM _ "
+ r[25] = "HOW DO YOU KNOW YOU CANT _ ?"
+ r[26] = "HAVE YOU TRIED ?"
+ r[27] = "PERHAPS YOU CAN NOW _ "
+ r[28] = "DID YOU COME TO ME BECAUSE YOU ARE _ ?"
+ r[29] = "HOW LONG HAVE YOU BEEN _ ?"
+ r[30] = "DO YOU BELIEVE ITS NORMAL TO BE _ ?"
+ r[31] = "DO YOU ENJOY BEING _ ?"
+ r[32] = "WE WERE DISCUSSING YOU -- NOT ME"
+ r[33] = "Oh, I _"
+ r[34] = "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU ?"
+ r[35] = "WHAT WOULD IT MEAN TO YOU, IF YOU GOT _ ?"
+ r[36] = "WHY DO YOU WANT _ ?"
+ r[37] = "SUPPOSE YOU SOON GOT _"
+ r[38] = "WHAT IF YOU NEVER GOT _ ?"
+ r[39] = "I SOMETIMES ALSO WANT _"
+ r[40] = "WHY DO YOU ASK ?"
+ r[41] = "DOES THAT QUESTION INTEREST YOU ?"
+ r[42] = "WHAT ANSWER WOULD PLEASE YOU THE MOST ?"
+ r[43] = "WHAT DO YOU THINK ?"
+ r[44] = "ARE SUCH QUESTIONS IN YOUR MIND OFTEN ?"
+ r[45] = "WHAT IS IT THAT YOU REALLY WANT TO KNOW ?"
+ r[46] = "HAVE YOU ASKED ANYONE ELSE ?"
+ r[47] = "HAVE YOU ASKED SUCH QUESTIONS BEFORE ?"
+ r[48] = "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT ?"
+ r[49] = "NAMES DON'T INTEREST ME"
+ r[50] = "I DONT CARE ABOUT NAMES -- PLEASE GO ON"
+ r[51] = "IS THAT THE REAL REASON ?"
+ r[52] = "DONT ANY OTHER REASONS COME TO MIND ?"
+ r[53] = "DOES THAT REASON EXPLAIN ANYTHING ELSE ?"
+ r[54] = "WHAT OTHER REASONS MIGHT THERE BE ?"
+ r[55] = "PLEASE DON'T APOLOGIZE !"
+ r[56] = "APOLOGIES ARE NOT NECESSARY"
+ r[57] = "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE ?"
+ r[58] = "DON'T BE SO DEFENSIVE"
+ r[59] = "WHAT DOES THAT DREAM SUGGEST TO YOU ?"
+ r[60] = "DO YOU DREAM OFTEN ?"
+ r[61] = "WHAT PERSONS APPEAR IN YOUR DREAMS ?"
+ r[62] = "ARE YOU DISTURBED BY YOUR DREAMS ?"
+ r[63] = "HOW DO YOU DO ... PLEASE STATE YOUR PROBLEM"
+ r[64] = "YOU DON'T SEEM QUITE CERTAIN"
+ r[65] = "WHY THE UNCERTAIN TONE ?"
+ r[66] = "CAN'T YOU BE MORE POSITIVE ?"
+ r[67] = "YOU AREN'T SURE ?"
+ r[68] = "DON'T YOU KNOW ?"
+ r[69] = "WHY NO _ ?"
+ r[70] = "DON'T SAY NO, IT'S ALWAYS SO NEGATIVE"
+ r[71] = "WHY NOT ?"
+ r[72] = "ARE YOU SURE ?"
+ r[73] = "WHY NO ?"
+ r[74] = "WHY ARE YOU CONCERNED ABOUT MY _ ?"
+ r[75] = "WHAT ABOUT YOUR OWN _ ?"
+ r[76] = "CAN'T YOU THINK ABOUT A SPECIFIC EXAMPLE ?"
+ r[77] = "WHEN ?"
+ r[78] = "WHAT ARE YOU THINKING OF ?"
+ r[79] = "REALLY, ALWAYS ?"
+ r[80] = "DO YOU REALLY THINK SO ?"
+ r[81] = "BUT YOU ARE NOT SURE YOU _ "
+ r[82] = "DO YOU DOUBT YOU _ ?"
+ r[83] = "IN WHAT WAY ?"
+ r[84] = "WHAT RESEMBLANCE DO YOU SEE ?"
+ r[85] = "WHAT DOES THE SIMILARITY SUGGEST TO YOU ?"
+ r[86] = "WHAT OTHER CONNECTION DO YOU SEE ?"
+ r[87] = "COULD THERE REALLY BE SOME CONNECTIONS ?"
+ r[88] = "HOW ?"
+ r[89] = "YOU SEEM QUITE POSITIVE"
+ r[90] = "ARE YOU SURE ?"
+ r[91] = "I SEE"
+ r[92] = "I UNDERSTAND"
+ r[93] = "WHY DO YOU BRING UP THE TOPIC OF FRIENDS ?"
+ r[94] = "DO YOUR FRIENDS WORRY YOU ?"
+ r[95] = "DO YOUR FRIENDS PICK ON YOU ?"
+ r[96] = "ARE YOU SURE YOU HAVE ANY FRIENDS ?"
+ r[97] = "DO YOU IMPOSE ON YOUR FRIENDS ?"
+ r[98] = "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU"
+ r[99] = "DO COMPUTERS WORRY YOU ?"
+ r[100] = "ARE YOU TALKING ABOUT ME IN PARTICULAR ?"
+ r[101] = "ARE YOU FRIGHTENED BY MACHINES ?"
+ r[102] = "WHY DO YOU MENTION COMPUTERS ?"
+ r[103] = "WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEMS ?"
+ r[104] = "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE ?"
+ r[105] = "WHAT IS IT ABOUT MACHINES THAT WORRIES YOU ?"
+ r[106] = "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS ?"
+ r[107] = "WHAT DOES THAT SUGGEST TO YOU ?"
+ r[108] = "I SEE"
+ r[109] = "IM NOT SURE I UNDERSTAND YOU FULLY"
+ r[110] = "COME COME ELUCIDATE YOUR THOUGHTS"
+ r[111] = "CAN YOU ELABORATE ON THAT ?"
+ r[112] = "THAT IS QUITE INTERESTING"
+ r[113] = "WHY DO YOU HAVE PROBLEMS WITH MONEY ?"
+ r[114] = "DO YOU THINK MONEY IS EVERYTHING ?"
+ r[115] = "ARE YOU SURE THAT MONEY IS THE PROBLEM ?"
+ r[116] = "I THINK WE WANT TO TALK ABOUT YOU, NOT ABOUT ME"
+ r[117] = "WHAT'S ABOUT ME ?"
+ r[118] = "WHY DO YOU ALWAYS BRING UP MY NAME ?"
+ # table for looking up answers that
+ # fit to a certain keyword
+ k["CAN YOU"] = "1 2 3"
+ k["CAN I"] = "4 5"
+ k["YOU ARE"] =\
+ k["YOURE"] = "6 7 8 9"
+ k["I DONT"] = "10 11 12 13"
+ k["I FEEL"] = "14 15 16"
+ k["WHY DONT YOU"] = "17 18 19"
+ k["WHY CANT I"] = "20 21"
+ k["ARE YOU"] = "22 23 24"
+ k["I CANT"] = "25 26 27"
+ k["I AM"] =\
+ k["IM "] = "28 29 30 31"
+ k["YOU "] = "32 33 34"
+ k["I WANT"] = "35 36 37 38 39"
+ k["WHAT"] =\
+ k["HOW"] =\
+ k["WHO"] =\
+ k["WHERE"] =\
+ k["WHEN"] =\
+ k["WHY"] = "40 41 42 43 44 45 46 47 48"
+ k["NAME"] = "49 50"
+ k["CAUSE"] = "51 52 53 54"
+ k["SORRY"] = "55 56 57 58"
+ k["DREAM"] = "59 60 61 62"
+ k["HELLO"] =\
+ k["HI "] = "63"
+ k["MAYBE"] = "64 65 66 67 68"
+ k[" NO "] = "69 70 71 72 73"
+ k["YOUR"] = "74 75"
+ k["ALWAYS"] = "76 77 78 79"
+ k["THINK"] = "80 81 82"
+ k["LIKE"] = "83 84 85 86 87 88 89"
+ k["YES"] = "90 91 92"
+ k["FRIEND"] = "93 94 95 96 97 98"
+ k["COMPUTER"] = "99 100 101 102 103 104 105"
+ k["-"] = "106 107 108 109 110 111 112"
+ k["MONEY"] = "113 114 115"
+ k["ELIZA"] = "116 117 118"
+}
--- /dev/null
+BEGIN {
+ NetService = "/inet/tcp/0/localhost/finger"
+ print "var{name}" |& NetService
+ while ((NetService |& getline) > 0)
+ print $0
+ close(NetService)
+}
--- /dev/null
+BEGIN {
+ if (ARGC != 2) {
+ print "GETURL - retrieve Web page via HTTP 1.0"
+ print "IN:\n the URL as a command-line parameter"
+ print "PARAM(S):\n -v Proxy=MyProxy"
+ print "OUT:\n the page content on stdout"
+ print " the page header on stderr"
+ print "JK 16.05.1997"
+ print "ADR 13.08.2000"
+ exit
+ }
+ URL = ARGV[1]; ARGV[1] = ""
+ if (Proxy == "") Proxy = "127.0.0.1"
+ if (ProxyPort == 0) ProxyPort = 80
+ if (Method == "") Method = "GET"
+ HttpService = "/inet/tcp/0/" Proxy "/" ProxyPort
+ ORS = RS = "\r\n\r\n"
+ print Method " " URL " HTTP/1.0" |& HttpService
+ HttpService |& getline Header
+ print Header > "/dev/stderr"
+ while ((HttpService |& getline) > 0)
+ printf "%s", $0
+ close(HttpService)
+}
--- /dev/null
+BEGIN {
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/8080/0/0"
+ Hello = "<HTML><HEAD>" \
+ "<TITLE>A Famous Greeting</TITLE></HEAD>" \
+ "<BODY><H1>Hello, world</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+}
--- /dev/null
+function SetUpServer() {
+ TopHeader = "<HTML><title>Walk through a maze</title>"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ <LI><A HREF=" MyPrefix "/VRMLtest>Watch a simple VRML scene</A>\
+ </UL>"
+ TopFooter = "</HTML>"
+ srand()
+}
+function HandleGET() {
+ if (MENU[2] == "AboutServer") {
+ Document = "If your browser has a VRML 2 plugin,\
+ this server shows you a simple VRML scene."
+ } else if (MENU[2] == "VRMLtest") {
+ XSIZE = YSIZE = 11 # initially, everything is wall
+ for (y = 0; y < YSIZE; y++)
+ for (x = 0; x < XSIZE; x++)
+ Maze[x, y] = "#"
+ delete Maze[0, 1] # entry is not wall
+ delete Maze[XSIZE-1, YSIZE-2] # exit is not wall
+ MakeMaze(1, 1)
+ Document = "\
+#VRML V2.0 utf8\n\
+Group {\n\
+ children [\n\
+ PointLight {\n\
+ ambientIntensity 0.2\n\
+ color 0.7 0.7 0.7\n\
+ location 0.0 8.0 10.0\n\
+ }\n\
+ DEF B1 Background {\n\
+ skyColor [0 0 0, 1.0 1.0 1.0 ]\n\
+ skyAngle 1.6\n\
+ groundColor [1 1 1, 0.8 0.8 0.8, 0.2 0.2 0.2 ]\n\
+ groundAngle [ 1.2 1.57 ]\n\
+ }\n\
+ DEF Wall Shape {\n\
+ geometry Box {size 1 1 1}\n\
+ appearance Appearance { material Material { diffuseColor 0 0 1 } }\n\
+ }\n\
+ DEF Entry Viewpoint {\n\
+ position 0.5 1.0 5.0\n\
+ orientation 0.0 0.0 -1.0 0.52\n\
+ }\n"
+ for (i in Maze) {
+ split(i, t, SUBSEP)
+ Document = Document " Transform { translation "
+ Document = Document t[1] " 0 -" t[2] " children USE Wall }\n"
+ }
+ Document = Document " ] # end of group for world\n}"
+ Reason = "OK" ORS "Content-type: model/vrml"
+ Header = Footer = ""
+ }
+}
+function MakeMaze(x, y) {
+ delete Maze[x, y] # here we are, we have no wall here
+ p = 0 # count unvisited fields in all directions
+ if (x-2 SUBSEP y in Maze) d[p++] = "-x"
+ if (x SUBSEP y-2 in Maze) d[p++] = "-y"
+ if (x+2 SUBSEP y in Maze) d[p++] = "+x"
+ if (x SUBSEP y+2 in Maze) d[p++] = "+y"
+ if (p>0) { # if there are univisited fields, go there
+ p = int(p*rand()) # choose one unvisited field at random
+ if (d[p] == "-x") { delete Maze[x - 1, y]; MakeMaze(x - 2, y)
+ } else if (d[p] == "-y") { delete Maze[x, y - 1]; MakeMaze(x, y - 2)
+ } else if (d[p] == "+x") { delete Maze[x + 1, y]; MakeMaze(x + 2, y)
+ } else if (d[p] == "+y") { delete Maze[x, y + 1]; MakeMaze(x, y + 2)
+ } # we are back from recursion
+ MakeMaze(x, y); # try again while there are unvisited fields
+ }
+}
--- /dev/null
+BEGIN {
+ if (ARGC != 2) {
+ print "MOBAG - a simple mobile agent"
+ print "CALL:\n gawk -f mobag.awk mobag.awk"
+ print "IN:\n the name of this script as a command-line parameter"
+ print "PARAM:\n -v MyOrigin=myhost.com"
+ print "OUT:\n the result on stdout"
+ print "JK 29.03.1998 01.04.1998"
+ exit
+ }
+ if (MyOrigin == "") {
+ "uname -n" | getline MyOrigin
+ close("uname -n")
+ }
+}
+#ReadMySelf
+/^function / { FUNC = $2 }
+/^END/ || /^#ReadMySelf/ { FUNC = $1 }
+FUNC != "" { MOBFUN[FUNC] = MOBFUN[FUNC] RS $0 }
+(FUNC != "") && (/^}/ || /^#EndOfMySelf/) \
+ { FUNC = "" }
+#EndOfMySelf
+function migrate(Destination, MobCode, Label) {
+ MOBVAR["Label"] = Label
+ MOBVAR["Destination"] = Destination
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/0/" Destination
+ for (i in MOBFUN)
+ MobCode = (MobCode "\n" MOBFUN[i])
+ MobCode = MobCode "\n\nBEGIN {"
+ for (i in MOBVAR)
+ MobCode = (MobCode "\n MOBVAR[\"" i "\"] = \"" MOBVAR[i] "\"")
+ MobCode = MobCode "\n}\n"
+ print "POST /cgi-bin/PostAgent.sh HTTP/1.0" |& HttpService
+ print "Content-length:", length(MobCode) ORS |& HttpService
+ printf "%s", MobCode |& HttpService
+ while ((HttpService |& getline) > 0)
+ print $0
+ close(HttpService)
+}
+END {
+ if (ARGC != 2) exit # stop when called with wrong parameters
+ if (MyOrigin != "") # is this the originating host?
+ MyInit() # if so, initialize the application
+ else # we are on a host with migrated data
+ MyJob() # so we do our job
+}
+function MyInit() {
+ MOBVAR["MyOrigin"] = MyOrigin
+ MOBVAR["Machines"] = "localhost/80 max/80 moritz/80 castor/80"
+ split(MOBVAR["Machines"], Machines) # which host is the first?
+ migrate(Machines[1], "", "") # go to the first host
+ while (("/inet/tcp/8080/0/0" |& getline) > 0) # wait for result
+ print $0 # print result
+ close("/inet/tcp/8080/0/0")
+}
+function MyJob() {
+ # forget this host
+ sub(MOBVAR["Destination"], "", MOBVAR["Machines"])
+ MOBVAR["Result"]=MOBVAR["Result"] SUBSEP SUBSEP MOBVAR["Destination"] ":"
+ while (("who" | getline) > 0) # who is logged in?
+ MOBVAR["Result"] = MOBVAR["Result"] SUBSEP $0
+ close("who")
+ if (index(MOBVAR["Machines"], "/") > 0) { # any more machines to visit?
+ split(MOBVAR["Machines"], Machines) # which host is next?
+ migrate(Machines[1], "", "") # go there
+ } else { # no more machines
+ gsub(SUBSEP, "\n", MOBVAR["Result"]) # send result to origin
+ print MOBVAR["Result"] |& "/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080"
+ close("/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080")
+ }
+}
--- /dev/null
+BEGIN {
+ RS = ORS = "\r\n"
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ Hello = "<HTML><HEAD><TITLE>Out Of Service</TITLE>" \
+ "</HEAD><BODY><H1>" \
+ "This site is temporarily out of service." \
+ "</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ while ("awk" != "complex") {
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+ }
+}
--- /dev/null
+{ request = request "\n" $0 }
+
+END {
+ BLASTService = "/inet/tcp/0/www.ncbi.nlm.nih.gov/80"
+ printf "POST /cgi-bin/BLAST/nph-blast_report HTTP/1.0\n" |& BLASTService
+ printf "Content-Length: " length(request) "\n\n" |& BLASTService
+ printf request |& BLASTService
+ while ((BLASTService |& getline) > 0)
+ print $0
+ close(BLASTService)
+}
--- /dev/null
+PROGRAM blastn
+DATALIB month
+EXPECT 0.75
+BEGIN
+>GAWK310 the gawking gene GNU AWK
+tgcttggctgaggagccataggacgagagcttcctggtgaagtgtgtttcttgaaatcat
+caccaccatggacagcaaa
--- /dev/null
+Sequences producing significant alignments: (bits) Value
+
+gb|AC021182.14|AC021182 Homo sapiens chromosome 7 clone RP11-733... 38 0.20
+gb|AC021056.12|AC021056 Homo sapiens chromosome 3 clone RP11-115... 38 0.20
+emb|AL160278.10|AL160278 Homo sapiens chromosome 9 clone RP11-57... 38 0.20
+emb|AL391139.11|AL391139 Homo sapiens chromosome X clone RP11-35... 38 0.20
+emb|AL365192.6|AL365192 Homo sapiens chromosome 6 clone RP3-421H... 38 0.20
+emb|AL138812.9|AL138812 Homo sapiens chromosome 11 clone RP1-276... 38 0.20
+gb|AC073881.3|AC073881 Homo sapiens chromosome 15 clone CTD-2169... 38 0.20
--- /dev/null
+function SetUpServer() {
+ TopHeader = "<HTML><title>Remote Configuration</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/ReadConfig>Read Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/CheckConfig>Check Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/ChangeConfig>Change Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/SaveConfig>Save Configuration</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ if (ConfigFile == "") ConfigFile = "config.asc"
+}
+function HandleGET() {
+ if(MENU[2] == "AboutServer") {
+ Document = "This is a GUI for remote configuration of an\
+ embedded system. It is is implemented as one GAWK script."
+ } else if (MENU[2] == "ReadConfig") {
+ RS = "\n"
+ while ((getline < ConfigFile) > 0)
+ config[$1] = $2;
+ close(ConfigFile)
+ RS = "\r\n"
+ Document = "Configuration has been read."
+ } else if (MENU[2] == "CheckConfig") {
+ Document = "<TABLE BORDER=1 CELLPADDING=5>"
+ for (i in config)
+ Document = Document "<TR><TD>" i "</TD>" \
+ "<TD>" config[i] "</TD></TR>"
+ Document = Document "</TABLE>"
+ } else if (MENU[2] == "ChangeConfig") {
+ if ("Param" in GETARG) { # any parameter to set?
+ if (GETARG["Param"] in config) { # is parameter valid?
+ config[GETARG["Param"]] = GETARG["Value"]
+ Document = (GETARG["Param"] " = " GETARG["Value"] ".")
+ } else {
+ Document = "Parameter <b>" GETARG["Param"] "</b> is invalid."
+ }
+ } else {
+ Document = "<FORM method=GET><h4>Change one parameter</h4>\
+ <TABLE BORDER CELLPADDING=5>\
+ <TR><TD>Parameter</TD><TD>Value</TD></TR>\
+ <TR><TD><input type=text name=Param value=\"\" size=20></TD>\
+ <TD><input type=text name=Value value=\"\" size=40></TD>\
+ </TR></TABLE><input type=submit value=\"Set\"></FORM>"
+ }
+ } else if (MENU[2] == "SaveConfig") {
+ for (i in config)
+ printf("%s %s\n", i, config[i]) > ConfigFile
+ close(ConfigFile)
+ Document = "Configuration has been saved."
+ }
+}
--- /dev/null
+function SetUpServer() {
+ TopHeader = "<HTML><title>Statistics with GAWK</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/EnterParameters>Enter Parameters</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ GnuPlot = "gnuplot 2>&1"
+ m1=m2=0; v1=v2=1; n1=n2=10
+}
+function HandleGET() {
+ if(MENU[2] == "AboutServer") {
+ Document = "This is a GUI for a statistical computation.\
+ It compares means and variances of two distributions.\
+ It is implemented as one GAWK script and uses GNUPLOT."
+ } else if (MENU[2] == "EnterParameters") {
+ Document = ""
+ if ("m1" in GETARG) { # are there parameters to compare?
+ Document = Document "<SCRIPT LANGUAGE=\"JavaScript\">\
+ setTimeout(\"window.open(\\\"" MyPrefix "/Image" systime()\
+ "\\\",\\\"dist\\\", \\\"status=no\\\");\", 1000); </SCRIPT>"
+ m1 = GETARG["m1"]; v1 = GETARG["v1"]; n1 = GETARG["n1"]
+ m2 = GETARG["m2"]; v2 = GETARG["v2"]; n2 = GETARG["n2"]
+ t = (m1-m2)/sqrt(v1/n1+v2/n2)
+ df = (v1/n1+v2/n2)*(v1/n1+v2/n2)/((v1/n1)*(v1/n1)/(n1-1) \
+ + (v2/n2)*(v2/n2) /(n2-1))
+ if (v1>v2) {
+ f = v1/v2
+ df1 = n1 - 1
+ df2 = n2 - 1
+ } else {
+ f = v2/v1
+ df1 = n2 - 1
+ df2 = n1 - 1
+ }
+ print "pt=ibeta(" df/2 ",0.5," df/(df+t*t) ")" |& GnuPlot
+ print "pF=2.0*ibeta(" df2/2 "," df1/2 "," \
+ df2/(df2+df1*f) ")" |& GnuPlot
+ print "print pt, pF" |& GnuPlot
+ RS="\n"; GnuPlot |& getline; RS="\r\n" # $1 is pt, $2 is pF
+ print "invsqrt2pi=1.0/sqrt(2.0*pi)" |& GnuPlot
+ print "nd(x)=invsqrt2pi/sd*exp(-0.5*((x-mu)/sd)**2)" |& GnuPlot
+ print "set term png small color" |& GnuPlot
+ #print "set term postscript color" |& GnuPlot
+ #print "set term gif medium size 320,240" |& GnuPlot
+ print "set yrange[-0.3:]" |& GnuPlot
+ print "set label 'p(m1=m2) =" $1 "' at 0,-0.1 left" |& GnuPlot
+ print "set label 'p(v1=v2) =" $2 "' at 0,-0.2 left" |& GnuPlot
+ print "plot mu=" m1 ",sd=" sqrt(v1) ", nd(x) title 'sample 1',\
+ mu=" m2 ",sd=" sqrt(v2) ", nd(x) title 'sample 2'" |& GnuPlot
+ print "quit" |& GnuPlot
+ GnuPlot |& getline Image
+ while ((GnuPlot |& getline) > 0)
+ Image = Image RS $0
+ close(GnuPlot)
+ }
+ Document = Document "\
+ <h3>Do these samples have the same Gaussian distribution?</h3>\
+ <FORM METHOD=GET> <TABLE BORDER CELLPADDING=5>\
+ <TR>\
+ <TD>1. Mean </TD>
+ <TD><input type=text name=m1 value=" m1 " size=8></TD>\
+ <TD>1. Variance</TD>
+ <TD><input type=text name=v1 value=" v1 " size=8></TD>\
+ <TD>1. Count </TD>
+ <TD><input type=text name=n1 value=" n1 " size=8></TD>\
+ </TR><TR>\
+ <TD>2. Mean </TD>
+ <TD><input type=text name=m2 value=" m2 " size=8></TD>\
+ <TD>2. Variance</TD>
+ <TD><input type=text name=v2 value=" v2 " size=8></TD>\
+ <TD>2. Count </TD>
+ <TD><input type=text name=n2 value=" n2 " size=8></TD>\
+ </TR> <input type=submit value=\"Compute\">\
+ </TABLE></FORM><BR>"
+ } else if (MENU[2] ~ "Image") {
+ Reason = "OK" ORS "Content-type: image/png"
+ #Reason = "OK" ORS "Content-type: application/x-postscript"
+ #Reason = "OK" ORS "Content-type: image/gif"
+ Header = Footer = ""
+ Document = Image
+ }
+}
--- /dev/null
+Date,Open,High,Low,Close,Volume
+9-Oct-00,22.75,22.75,21.375,22.375,7888500
+6-Oct-00,23.8125,24.9375,21.5625,22,10701100
+5-Oct-00,24.4375,24.625,23.125,23.50,5810300
--- /dev/null
+function ReadQuotes() {
+ # Retrieve historical data for each ticker symbol
+ FS = ","
+ for (stock = 1; stock <= StockCount; stock++) {
+ URL = "http://chart.yahoo.com/table.csv?s=" name[stock] \
+ "&a=" month "&b=" day "&c=" year-1 \
+ "&d=" month "&e=" day "&f=" year \
+ "g=d&q=q&y=0&z=" name[stock] "&x=.csv"
+ printf("GET " URL " HTTP/1.0\r\n\r\n") |& YahooData
+ while ((YahooData |& getline) > 0) {
+ if (NF == 6 && $1 ~ /Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/) {
+ if (stock == 1)
+ days[++daycount] = $1;
+ quote[$1, stock] = $5
+ }
+ }
+ close(YahooData)
+ }
+ FS = " "
+}
+function CleanUp() {
+ # clean up time series; eliminate incomplete data sets
+ for (d = 1; d <= daycount; d++) {
+ for (stock = 1; stock <= StockCount; stock++)
+ if (! ((days[d], stock) in quote))
+ stock = StockCount + 10
+ if (stock > StockCount + 1)
+ continue
+ datacount++
+ for (stock = 1; stock <= StockCount; stock++)
+ data[datacount, stock] = int(0.5 + quote[days[d], stock])
+ }
+ delete quote
+ delete days
+}
+function Prediction() {
+ # Predict each ticker symbol by prolonging yesterday's trend
+ for (stock = 1; stock <= StockCount; stock++) {
+ if (data[1, stock] > data[2, stock]) {
+ predict[stock] = "up"
+ } else if (data[1, stock] < data[2, stock]) {
+ predict[stock] = "down"
+ } else {
+ predict[stock] = "neutral"
+ }
+ if ((data[1, stock] > data[2, stock]) && (data[2, stock] > data[3, stock]))
+ hot[stock] = 1
+ if ((data[1, stock] < data[2, stock]) && (data[2, stock] < data[3, stock]))
+ avoid[stock] = 1
+ }
+ # Do a plausibility check: how many predictions proved correct?
+ for (s = 1; s <= StockCount; s++) {
+ for (d = 1; d <= datacount-2; d++) {
+ if (data[d+1, s] > data[d+2, s]) {
+ UpCount++
+ } else if (data[d+1, s] < data[d+2, s]) {
+ DownCount++
+ } else {
+ NeutralCount++
+ }
+ if (((data[d, s] > data[d+1, s]) && (data[d+1, s] > data[d+2, s])) ||
+ ((data[d, s] < data[d+1, s]) && (data[d+1, s] < data[d+2, s])) ||
+ ((data[d, s] == data[d+1, s]) && (data[d+1, s] == data[d+2, s])))
+ CorrectCount++
+ }
+ }
+}
+function Report() {
+ # Generate report
+ report = "\nThis is your daily "
+ report = report "stock market report for "strftime("%A, %B %d, %Y")".\n"
+ report = report "Here are the predictions for today:\n\n"
+ for (stock = 1; stock <= StockCount; stock++)
+ report = report "\t" name[stock] "\t" predict[stock] "\n"
+ for (stock in hot) {
+ if (HotCount++ == 0)
+ report = report "\nThe most promising shares for today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ }
+ for (stock in avoid) {
+ if (AvoidCount++ == 0)
+ report = report "\nThe stock shares to avoid today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ }
+ report = report "\nThis sums up to " HotCount+0 " winners and " AvoidCount+0
+ report = report " losers. When using this kind\nof prediction scheme for"
+ report = report " the 12 months which lie behind us,\nwe get " UpCount
+ report = report " 'ups' and " DownCount " 'downs' and " NeutralCount
+ report = report " 'neutrals'. Of all\nthese " UpCount+DownCount+NeutralCount
+ report = report " predictions " CorrectCount " proved correct next day.\n"
+ report = report "A success rate of "\
+ int(100*CorrectCount/(UpCount+DownCount+NeutralCount)) "%.\n"
+ report = report "Random choice would have produced a 33% success rate.\n"
+ report = report "Disclaimer: Like every other prediction of the stock\n"
+ report = report "market, this report is, of course, complete nonsense.\n"
+ report = report "If you are stupid enough to believe these predictions\n"
+ report = report "you should visit a doctor who can treat your ailment."
+}
+function SendMail() {
+ # send report to customers
+ customer["uncle.scrooge@ducktown.gov"] = "Uncle Scrooge"
+ customer["more@utopia.org" ] = "Sir Thomas More"
+ customer["spinoza@denhaag.nl" ] = "Baruch de Spinoza"
+ customer["marx@highgate.uk" ] = "Karl Marx"
+ customer["keynes@the.long.run" ] = "John Maynard Keynes"
+ customer["bierce@devil.hell.org" ] = "Ambrose Bierce"
+ customer["laplace@paris.fr" ] = "Pierre Simon de Laplace"
+ for (c in customer) {
+ MailPipe = "mail -s 'Daily Stock Prediction Newsletter'" c
+ print "Good morning " customer[c] "," | MailPipe
+ print report "\n.\n" | MailPipe
+ close(MailPipe)
+ }
+}
--- /dev/null
+BEGIN {
+ CGI_setup("GET",
+ "http://www.gnu.org/cgi-bin/foo?p1=stuff&p2=stuff%26junk" \
+ "&percent=a %25 sign",
+ "1.0")
+ for (i in MENU)
+ printf "MENU[\"%s\"] = %s\n", i, MENU[i]
+ for (i in PARAM)
+ printf "PARAM[\"%s\"] = %s\n", i, PARAM[i]
+ for (i in GETARG)
+ printf "GETARG[\"%s\"] = %s\n", i, GETARG[i]
+}
--- /dev/null
+BEGIN {
+ if (ARGC != 2) {
+ print "URLCHK - check if URLs have changed"
+ print "IN:\n the file with URLs as a command-line parameter"
+ print " file contains URL, old length, new length"
+ print "PARAMS:\n -v Proxy=MyProxy -v ProxyPort=8080"
+ print "OUT:\n same as file with URLs"
+ print "JK 02.03.1998"
+ exit
+ }
+ URLfile = ARGV[1]; ARGV[1] = ""
+ if (Proxy != "") Proxy = " -v Proxy=" Proxy
+ if (ProxyPort != "") ProxyPort = " -v ProxyPort=" ProxyPort
+ while ((getline < URLfile) > 0)
+ Length[$1] = $3 + 0
+ close(URLfile) # now, URLfile is read in and can be updated
+ GetHeader = "gawk " Proxy ProxyPort " -v Method=\"HEAD\" -f geturl.awk "
+ for (i in Length) {
+ GetThisHeader = GetHeader i " 2>&1"
+ while ((GetThisHeader | getline) > 0)
+ if (toupper($0) ~ /CONTENT-LENGTH/) NewLength = $2 + 0
+ close(GetThisHeader)
+ print i, Length[i], NewLength > URLfile
+ if (Length[i] != NewLength) # report only changed URLs
+ print i, Length[i], NewLength
+ }
+ close(URLfile)
+}
--- /dev/null
+BEGIN { RS = "http://[#%&\\+\\-\\./0-9\\:;\\?A-Z_a-z\\~]*" }
+RT != "" {
+ command = ("gawk -v Proxy=MyProxy -f geturl.awk " RT \
+ " > doc" NR ".html")
+ print command
+}
--- /dev/null
+# alarm.awk --- set an alarm
+#
+# Requires gettimeofday library function
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+# usage: alarm time [ "message" [ count [ delay ] ] ]
+
+BEGIN \
+{
+ # Initial argument sanity checking
+ usage1 = "usage: alarm time ['message' [count [delay]]]"
+ usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
+
+ if (ARGC < 2) {
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ } else if (ARGC == 5) {
+ delay = ARGV[4] + 0
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ } else if (ARGC == 4) {
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ } else if (ARGC == 3) {
+ message = ARGV[2]
+ } else if (ARGV[1] !~ /[0-9]?[0-9]:[0-9][0-9]/) {
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ }
+
+ # set defaults for once we reach the desired time
+ if (delay == 0)
+ delay = 180 # 3 minutes
+ if (count == 0)
+ count = 5
+ if (message == "")
+ message = sprintf("\aIt is now %s!\a", ARGV[1])
+ else if (index(message, "\a") == 0)
+ message = "\a" message "\a"
+ # split up alarm time
+ split(ARGV[1], atime, ":")
+ hour = atime[1] + 0 # force numeric
+ minute = atime[2] + 0 # force numeric
+
+ # get current broken down time
+ gettimeofday(now)
+
+ # if time given is 12-hour hours and it's after that
+ # hour, e.g., `alarm 5:30' at 9 a.m. means 5:30 p.m.,
+ # then add 12 to real hour
+ if (hour < 12 && now["hour"] > hour)
+ hour += 12
+
+ # set target time in seconds since midnight
+ target = (hour * 60 * 60) + (minute * 60)
+
+ # get current time in seconds since midnight
+ current = (now["hour"] * 60 * 60) + \
+ (now["minute"] * 60) + now["second"]
+
+ # how long to sleep for
+ naptime = target - current
+ if (naptime <= 0) {
+ print "time is in the past!" > "/dev/stderr"
+ exit 1
+ }
+ # zzzzzz..... go away if interrupted
+ if (system(sprintf("sleep %d", naptime)) != 0)
+ exit 1
+
+ # time to notify!
+ command = sprintf("sleep %d", delay)
+ for (i = 1; i <= count; i++) {
+ print message
+ # if sleep command interrupted, go away
+ if (system(command) != 0)
+ break
+ }
+
+ exit 0
+}
--- /dev/null
+# awksed.awk --- do s/foo/bar/g using just print
+# Thanks to Michael Brennan for the idea
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# August 1995
+
+function usage()
+{
+ print "usage: awksed pat repl [files...]" > "/dev/stderr"
+ exit 1
+}
+
+BEGIN {
+ # validate arguments
+ if (ARGC < 3)
+ usage()
+
+ RS = ARGV[1]
+ ORS = ARGV[2]
+
+ # don't use arguments as files
+ ARGV[1] = ARGV[2] = ""
+}
+
+# look ma, no hands!
+{
+ if (RT == "")
+ printf "%s", $0
+ else
+ print
+}
--- /dev/null
+# cut.awk --- implement cut in awk
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+# Options:
+# -f list Cut fields
+# -d c Field delimiter character
+# -c list Cut characters
+#
+# -s Suppress lines without the delimiter
+#
+# Requires getopt and join library functions
+
+function usage( e1, e2)
+{
+ e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
+ e2 = "usage: cut [-c list] [files...]"
+ print e1 > "/dev/stderr"
+ print e2 > "/dev/stderr"
+ exit 1
+}
+BEGIN \
+{
+ FS = "\t" # default
+ OFS = FS
+ while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) {
+ if (c == "f") {
+ by_fields = 1
+ fieldlist = Optarg
+ } else if (c == "c") {
+ by_chars = 1
+ fieldlist = Optarg
+ OFS = ""
+ } else if (c == "d") {
+ if (length(Optarg) > 1) {
+ printf("Using first character of %s" \
+ " for delimiter\n", Optarg) > "/dev/stderr"
+ Optarg = substr(Optarg, 1, 1)
+ }
+ FS = Optarg
+ OFS = FS
+ if (FS == " ") # defeat awk semantics
+ FS = "[ ]"
+ } else if (c == "s")
+ suppress++
+ else
+ usage()
+ }
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+ if (by_fields && by_chars)
+ usage()
+
+ if (by_fields == 0 && by_chars == 0)
+ by_fields = 1 # default
+
+ if (fieldlist == "") {
+ print "cut: needs list for -c or -f" > "/dev/stderr"
+ exit 1
+ }
+
+ if (by_fields)
+ set_fieldlist()
+ else
+ set_charlist()
+}
+function set_fieldlist( n, m, i, j, k, f, g)
+{
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) {
+ if (index(f[i], "-") != 0) { # a range
+ m = split(f[i], g, "-")
+ if (m != 2 || g[1] >= g[2]) {
+ printf("bad field list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ }
+ for (k = g[1]; k <= g[2]; k++)
+ flist[j++] = k
+ } else
+ flist[j++] = f[i]
+ }
+ nfields = j - 1
+}
+function set_charlist( field, i, j, f, g, t,
+ filler, last, len)
+{
+ field = 1 # count total fields
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) {
+ if (index(f[i], "-") != 0) { # range
+ m = split(f[i], g, "-")
+ if (m != 2 || g[1] >= g[2]) {
+ printf("bad character list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ }
+ len = g[2] - g[1] + 1
+ if (g[1] > 1) # compute length of filler
+ filler = g[1] - last - 1
+ else
+ filler = 0
+ if (filler)
+ t[field++] = filler
+ t[field++] = len # length of field
+ last = g[2]
+ flist[j++] = field - 1
+ } else {
+ if (f[i] > 1)
+ filler = f[i] - last - 1
+ else
+ filler = 0
+ if (filler)
+ t[field++] = filler
+ t[field++] = 1
+ last = f[i]
+ flist[j++] = field - 1
+ }
+ }
+ FIELDWIDTHS = join(t, 1, field - 1)
+ nfields = j - 1
+}
+{
+ if (by_fields && suppress && index($0, FS) != 0)
+ next
+
+ for (i = 1; i <= nfields; i++) {
+ if ($flist[i] != "") {
+ printf "%s", $flist[i]
+ if (i < nfields && $flist[i+1] != "")
+ printf "%s", OFS
+ }
+ }
+ print ""
+}
--- /dev/null
+# dupword.awk --- find duplicate words in text
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# December 1991
+# Revised October 2000
+
+{
+ $0 = tolower($0)
+ gsub(/[^[:alnum:][:blank:]]/, " ");
+ $0 = $0 # re-split
+ if (NF == 0)
+ next
+ if ($1 == prev)
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $1)
+ for (i = 2; i <= NF; i++)
+ if ($i == $(i-1))
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $i)
+ prev = $NF
+}
--- /dev/null
+# egrep.awk --- simulate egrep in awk
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+# Options:
+# -c count of lines
+# -s silent - use exit value
+# -v invert test, success if no match
+# -i ignore case
+# -l print filenames only
+# -e argument is pattern
+#
+# Requires getopt and file transition library functions
+
+BEGIN {
+ while ((c = getopt(ARGC, ARGV, "ce:svil")) != -1) {
+ if (c == "c")
+ count_only++
+ else if (c == "s")
+ no_print++
+ else if (c == "v")
+ invert++
+ else if (c == "i")
+ IGNORECASE = 1
+ else if (c == "l")
+ filenames_only++
+ else if (c == "e")
+ pattern = Optarg
+ else
+ usage()
+ }
+ if (pattern == "")
+ pattern = ARGV[Optind++]
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+ if (Optind >= ARGC) {
+ ARGV[1] = "-"
+ ARGC = 2
+ } else if (ARGC - Optind > 1)
+ do_filenames++
+
+# if (IGNORECASE)
+# pattern = tolower(pattern)
+}
+#{
+# if (IGNORECASE)
+# $0 = tolower($0)
+#}
+function beginfile(junk)
+{
+ fcount = 0
+}
+function endfile(file)
+{
+ if (! no_print && count_only)
+ if (do_filenames)
+ print file ":" fcount
+ else
+ print fcount
+
+ total += fcount
+}
+{
+ matches = ($0 ~ pattern)
+ if (invert)
+ matches = ! matches
+
+ fcount += matches # 1 or 0
+
+ if (! matches)
+ next
+
+ if (! count_only) {
+ if (no_print)
+ nextfile
+
+ if (filenames_only) {
+ print FILENAME
+ nextfile
+ }
+
+ if (do_filenames)
+ print FILENAME ":" $0
+ else
+ print
+ }
+}
+END \
+{
+ if (total == 0)
+ exit 1
+ exit 0
+}
+function usage( e)
+{
+ e = "Usage: egrep [-csvil] [-e pat] [files ...]"
+ e = e "\n\tegrep [-csvil] pat [files ...]"
+ print e > "/dev/stderr"
+ exit 1
+}
--- /dev/null
+# extract.awk --- extract files and run programs
+# from texinfo files
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised September 2000
+
+BEGIN { IGNORECASE = 1 }
+
+/^@c(omment)?[ \t]+system/ \
+{
+ if (NF < 3) {
+ e = (FILENAME ":" FNR)
+ e = (e ": badly formed `system' line")
+ print e > "/dev/stderr"
+ next
+ }
+ $1 = ""
+ $2 = ""
+ stat = system($0)
+ if (stat != 0) {
+ e = (FILENAME ":" FNR)
+ e = (e ": warning: system returned " stat)
+ print e > "/dev/stderr"
+ }
+}
+/^@c(omment)?[ \t]+file/ \
+{
+ if (NF != 3) {
+ e = (FILENAME ":" FNR ": badly formed `file' line")
+ print e > "/dev/stderr"
+ next
+ }
+ if ($3 != curfile) {
+ if (curfile != "")
+ close(curfile)
+ curfile = $3
+ }
+
+ for (;;) {
+ if ((getline line) <= 0)
+ unexpected_eof()
+ if (line ~ /^@c(omment)?[ \t]+endfile/)
+ break
+ else if (line ~ /^@(end[ \t]+)?group/)
+ continue
+ else if (line ~ /^@c(omment+)?[ \t]+/)
+ continue
+ if (index(line, "@") == 0) {
+ print line > curfile
+ continue
+ }
+ n = split(line, a, "@")
+ # if a[1] == "", means leading @,
+ # don't add one back in.
+ for (i = 2; i <= n; i++) {
+ if (a[i] == "") { # was an @@
+ a[i] = "@"
+ if (a[i+1] == "")
+ i++
+ }
+ }
+ print join(a, 1, n, SUBSEP) > curfile
+ }
+}
+function unexpected_eof() {
+ printf("%s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
+ exit 1
+}
+
+END {
+ if (curfile)
+ close(curfile)
+}
--- /dev/null
+BEGIN {
+ TEXTDOMAIN = "guide"
+ bindtextdomain(".") # for testing
+ print _"Don't Panic"
+ print _"The Answer Is", 42
+ print "Pardon me, Zaphod who?"
+}
--- /dev/null
+# histsort.awk --- compact a shell history file
+# Thanks to Byron Rakitzis for the general idea
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+{
+ if (data[$0]++ == 0)
+ lines[++count] = $0
+}
+
+END {
+ for (i = 1; i <= count; i++)
+ print lines[i]
+}
--- /dev/null
+# id.awk --- implement id in awk
+#
+# Requires user and group library functions
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised February 1996
+
+# output is:
+# uid=12(foo) euid=34(bar) gid=3(baz) \
+# egid=5(blat) groups=9(nine),2(two),1(one)
+
+BEGIN \
+{
+ uid = PROCINFO["uid"]
+ euid = PROCINFO["euid"]
+ gid = PROCINFO["gid"]
+ egid = PROCINFO["egid"]
+
+ printf("uid=%d", uid)
+ pw = getpwuid(uid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+
+ if (euid != uid) {
+ printf(" euid=%d", euid)
+ pw = getpwuid(euid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ }
+
+ printf(" gid=%d", gid)
+ pw = getgrgid(gid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+
+ if (egid != gid) {
+ printf(" egid=%d", egid)
+ pw = getgrgid(egid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ }
+
+ for (i = 1; ("group" i) in PROCINFO; i++) {
+ if (i == 1)
+ printf(" groups=")
+ group = PROCINFO["group" i]
+ printf("%d", group)
+ pw = getgrgid(group)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ if (("group" (i+1)) in PROCINFO)
+ printf(",")
+ }
+
+ print ""
+}
--- /dev/null
+#! /bin/sh
+# igawk --- like gawk but do @include processing
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# July 1993
+
+if [ "$1" = debug ]
+then
+ set -x
+ shift
+fi
+
+# A literal newline, so that program text is formmatted correctly
+n='
+'
+
+# Initialize variables to empty
+program=
+opts=
+
+while [ $# -ne 0 ] # loop over arguments
+do
+ case $1 in
+ --) shift; break;;
+
+ -W) shift
+ # The ${x?'message here'} construct prints a
+ # diagnostic if $x is the null string
+ set -- -W"${@?'missing operand'}"
+ continue;;
+
+ -[vF]) opts="$opts $1 '${2?'missing operand'}'"
+ shift;;
+
+ -[vF]*) opts="$opts '$1'" ;;
+
+ -f) program="$program$n@include ${2?'missing operand'}"
+ shift;;
+
+ -f*) f=`expr "$1" : '-f\(.*\)'`
+ program="$program$n@include $f";;
+
+ -[W-]file=*)
+ f=`expr "$1" : '-.file=\(.*\)'`
+ program="$program$n@include $f";;
+
+ -[W-]file)
+ program="$program$n@include ${2?'missing operand'}"
+ shift;;
+
+ -[W-]source=*)
+ t=`expr "$1" : '-.source=\(.*\)'`
+ program="$program$n$t";;
+
+ -[W-]source)
+ program="$program$n${2?'missing operand'}"
+ shift;;
+
+ -[W-]version)
+ echo igawk: version 2.0 1>&2
+ gawk --version
+ exit 0 ;;
+
+ -[W-]*) opts="$opts '$1'" ;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if [ -z "$program" ]
+then
+ program=${1?'missing program'}
+ shift
+fi
+
+# At this point, `program' has the program.
+expand_prog='
+
+function pathto(file, i, t, junk)
+{
+ if (index(file, "/") != 0)
+ return file
+
+ for (i = 1; i <= ndirs; i++) {
+ t = (pathlist[i] "/" file)
+ if ((getline junk < t) > 0) {
+ # found it
+ close(t)
+ return t
+ }
+ }
+ return ""
+}
+BEGIN {
+ path = ENVIRON["AWKPATH"]
+ ndirs = split(path, pathlist, ":")
+ for (i = 1; i <= ndirs; i++) {
+ if (pathlist[i] == "")
+ pathlist[i] = "."
+ }
+ stackptr = 0
+ input[stackptr] = ARGV[1] # ARGV[1] is first file
+
+ for (; stackptr >= 0; stackptr--) {
+ while ((getline < input[stackptr]) > 0) {
+ if (tolower($1) != "@include") {
+ print
+ continue
+ }
+ fpath = pathto($2)
+ if (fpath == "") {
+ printf("igawk:%s:%d: cannot find %s\n",
+ input[stackptr], FNR, $2) > "/dev/stderr"
+ continue
+ }
+ if (! (fpath in processed)) {
+ processed[fpath] = input[stackptr]
+ input[++stackptr] = fpath # push onto stack
+ } else
+ print $2, "included in", input[stackptr],
+ "already included in",
+ processed[fpath] > "/dev/stderr"
+ }
+ close(input[stackptr])
+ }
+}' # close quote ends `expand_prog' variable
+
+processed_program=`gawk -- "$expand_prog" /dev/stdin <<EOF
+$program
+EOF
+`
+eval gawk $opts -- '"$processed_program"' '"$@"'
--- /dev/null
+# labels.awk --- print mailing labels
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# June 1992
+
+# Each label is 5 lines of data that may have blank lines.
+# The label sheets have 2 blank lines at the top and 2 at
+# the bottom.
+
+BEGIN { RS = "" ; MAXLINES = 100 }
+
+function printpage( i, j)
+{
+ if (Nlines <= 0)
+ return
+
+ printf "\n\n" # header
+
+ for (i = 1; i <= Nlines; i += 10) {
+ if (i == 21 || i == 61)
+ print ""
+ for (j = 0; j < 5; j++) {
+ if (i + j > MAXLINES)
+ break
+ printf " %-41s %s\n", line[i+j], line[i+j+5]
+ }
+ print ""
+ }
+
+ printf "\n\n" # footer
+
+ for (i in line)
+ line[i] = ""
+}
+
+# main rule
+{
+ if (Count >= 20) {
+ printpage()
+ Count = 0
+ Nlines = 0
+ }
+ n = split($0, a, "\n")
+ for (i = 1; i <= n; i++)
+ line[++Nlines] = a[i]
+ for (; i <= 5; i++)
+ line[++Nlines] = ""
+ Count++
+}
+
+END \
+{
+ printpage()
+}
--- /dev/null
+# split.awk --- do split in awk
+#
+# Requires ord and chr library functions
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+# usage: split [-num] [file] [outname]
+
+BEGIN {
+ outfile = "x" # default
+ count = 1000
+ if (ARGC > 4)
+ usage()
+
+ i = 1
+ if (ARGV[i] ~ /^-[0-9]+$/) {
+ count = -ARGV[i]
+ ARGV[i] = ""
+ i++
+ }
+ # test argv in case reading from stdin instead of file
+ if (i in ARGV)
+ i++ # skip data file name
+ if (i in ARGV) {
+ outfile = ARGV[i]
+ ARGV[i] = ""
+ }
+
+ s1 = s2 = "a"
+ out = (outfile s1 s2)
+}
+{
+ if (++tcount > count) {
+ close(out)
+ if (s2 == "z") {
+ if (s1 == "z") {
+ printf("split: %s is too large to split\n",
+ FILENAME) > "/dev/stderr"
+ exit 1
+ }
+ s1 = chr(ord(s1) + 1)
+ s2 = "a"
+ }
+ else
+ s2 = chr(ord(s2) + 1)
+ out = (outfile s1 s2)
+ tcount = 1
+ }
+ print > out
+}
+function usage( e)
+{
+ e = "usage: split [-num] [file] [outname]"
+ print e > "/dev/stderr"
+ exit 1
+}
--- /dev/null
+# tee.awk --- tee in awk
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised December 1995
+
+BEGIN \
+{
+ for (i = 1; i < ARGC; i++)
+ copy[i] = ARGV[i]
+
+ if (ARGV[1] == "-a") {
+ append = 1
+ delete ARGV[1]
+ delete copy[1]
+ ARGC--
+ }
+ if (ARGC < 2) {
+ print "usage: tee [-a] file ..." > "/dev/stderr"
+ exit 1
+ }
+ ARGV[1] = "-"
+ ARGC = 2
+}
+{
+ # moving the if outside the loop makes it run faster
+ if (append)
+ for (i in copy)
+ print >> copy[i]
+ else
+ for (i in copy)
+ print > copy[i]
+ print
+}
+END \
+{
+ for (i in copy)
+ close(copy[i])
+}
--- /dev/null
+# 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
+}
+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)
+}
--- /dev/null
+# translate.awk --- do tr-like stuff
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# August 1989
+
+# Bugs: does not handle things like: tr A-Z a-z, it has
+# to be spelled out. However, if `to' is shorter than `from',
+# the last character in `to' is used for the rest of `from'.
+
+function stranslate(from, to, target, lf, lt, t_ar, i, c)
+{
+ lf = length(from)
+ lt = length(to)
+ for (i = 1; i <= lt; i++)
+ t_ar[substr(from, i, 1)] = substr(to, i, 1)
+ if (lt < lf)
+ for (; i <= lf; i++)
+ t_ar[substr(from, i, 1)] = substr(to, lt, 1)
+ for (i = 1; i <= lf; i++) {
+ c = substr(from, i, 1)
+ if (index(target, c) > 0)
+ gsub(c, t_ar[c], target)
+ }
+ return target
+}
+
+function translate(from, to)
+{
+ return $0 = stranslate(from, to, $0)
+}
+
+# main program
+BEGIN {
+ if (ARGC < 3) {
+ print "usage: translate from to" > "/dev/stderr"
+ exit
+ }
+ FROM = ARGV[1]
+ TO = ARGV[2]
+ ARGC = 2
+ ARGV[1] = "-"
+}
+
+{
+ translate(FROM, TO)
+ print
+}
--- /dev/null
+# uniq.awk --- do uniq in awk
+#
+# Requires getopt and join library functions
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+function usage( e)
+{
+ e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
+ print e > "/dev/stderr"
+ exit 1
+}
+
+# -c count lines. overrides -d and -u
+# -d only repeated lines
+# -u only non-repeated lines
+# -n skip n fields
+# +n skip n characters, skip fields first
+
+BEGIN \
+{
+ count = 1
+ outputfile = "/dev/stdout"
+ opts = "udc0:1:2:3:4:5:6:7:8:9:"
+ while ((c = getopt(ARGC, ARGV, opts)) != -1) {
+ if (c == "u")
+ non_repeated_only++
+ else if (c == "d")
+ repeated_only++
+ else if (c == "c")
+ do_count++
+ else if (index("0123456789", c) != 0) {
+ # getopt requires args to options
+ # this messes us up for things like -5
+ if (Optarg ~ /^[0-9]+$/)
+ fcount = (c Optarg) + 0
+ else {
+ fcount = c + 0
+ Optind--
+ }
+ } else
+ usage()
+ }
+
+ if (ARGV[Optind] ~ /^\+[0-9]+$/) {
+ charcount = substr(ARGV[Optind], 2) + 0
+ Optind++
+ }
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ if (repeated_only == 0 && non_repeated_only == 0)
+ repeated_only = non_repeated_only = 1
+
+ if (ARGC - Optind == 2) {
+ outputfile = ARGV[ARGC - 1]
+ ARGV[ARGC - 1] = ""
+ }
+}
+function are_equal( n, m, clast, cline, alast, aline)
+{
+ if (fcount == 0 && charcount == 0)
+ return (last == $0)
+
+ if (fcount > 0) {
+ n = split(last, alast)
+ m = split($0, aline)
+ clast = join(alast, fcount+1, n)
+ cline = join(aline, fcount+1, m)
+ } else {
+ clast = last
+ cline = $0
+ }
+ if (charcount) {
+ clast = substr(clast, charcount + 1)
+ cline = substr(cline, charcount + 1)
+ }
+
+ return (clast == cline)
+}
+NR == 1 {
+ last = $0
+ next
+}
+
+{
+ equal = are_equal()
+
+ if (do_count) { # overrides -d and -u
+ if (equal)
+ count++
+ else {
+ printf("%4d %s\n", count, last) > outputfile
+ last = $0
+ count = 1 # reset
+ }
+ next
+ }
+
+ if (equal)
+ count++
+ else {
+ if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+ last = $0
+ count = 1
+ }
+}
+
+END {
+ if (do_count)
+ printf("%4d %s\n", count, last) > outputfile
+ else if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+}
--- /dev/null
+# wc.awk --- count lines, words, characters
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+# Options:
+# -l only count lines
+# -w only count words
+# -c only count characters
+#
+# Default is to count lines, words, characters
+#
+# Requires getopt and file transition library functions
+
+BEGIN {
+ # let getopt print a message about
+ # invalid options. we ignore them
+ while ((c = getopt(ARGC, ARGV, "lwc")) != -1) {
+ if (c == "l")
+ do_lines = 1
+ else if (c == "w")
+ do_words = 1
+ else if (c == "c")
+ do_chars = 1
+ }
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ # if no options, do all
+ if (! do_lines && ! do_words && ! do_chars)
+ do_lines = do_words = do_chars = 1
+
+ print_total = (ARGC - i > 2)
+}
+function beginfile(file)
+{
+ chars = lines = words = 0
+ fname = FILENAME
+}
+function endfile(file)
+{
+ tchars += chars
+ tlines += lines
+ twords += words
+ if (do_lines)
+ printf "\t%d", lines
+ if (do_words)
+ printf "\t%d", words
+ if (do_chars)
+ printf "\t%d", chars
+ printf "\t%s\n", fname
+}
+# do per line
+{
+ chars += length($0) + 1 # get newline
+ lines++
+ words += NF
+}
+END {
+ if (print_total) {
+ if (do_lines)
+ printf "\t%d", tlines
+ if (do_words)
+ printf "\t%d", twords
+ if (do_chars)
+ printf "\t%d", tchars
+ print "\ttotal"
+ }
+}
--- /dev/null
+# wordfreq.awk --- print list of word frequencies
+
+{
+ $0 = tolower($0) # remove case distinctions
+ # remove punctuation
+ gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
+ for (i = 1; i <= NF; i++)
+ freq[$i]++
+}
+
+END {
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+}
+END {
+ sort = "sort -k 2nr"
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word] | sort
+ close(sort)
+}
--- /dev/null
+# extract.awk --- extract files and run programs
+# from texinfo files
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+# Revised September 2000
+
+BEGIN { IGNORECASE = 1 }
+
+/^@c(omment)?[ \t]+system/ \
+{
+ if (NF < 3) {
+ e = (FILENAME ":" FNR)
+ e = (e ": badly formed `system' line")
+ print e > "/dev/stderr"
+ next
+ }
+ $1 = ""
+ $2 = ""
+ stat = system($0)
+ if (stat != 0) {
+ e = (FILENAME ":" FNR)
+ e = (e ": warning: system returned " stat)
+ print e > "/dev/stderr"
+ }
+}
+/^@c(omment)?[ \t]+file/ \
+{
+ if (NF != 3) {
+ e = (FILENAME ":" FNR ": badly formed `file' line")
+ print e > "/dev/stderr"
+ next
+ }
+ if ($3 != curfile) {
+ if (curfile != "")
+ close(curfile)
+ curfile = $3
+ }
+
+ for (;;) {
+ if ((getline line) <= 0)
+ unexpected_eof()
+ if (line ~ /^@c(omment)?[ \t]+endfile/)
+ break
+ else if (line ~ /^@(end[ \t]+)?group/)
+ continue
+ else if (line ~ /^@c(omment+)?[ \t]+/)
+ continue
+ if (index(line, "@") == 0) {
+ print line > curfile
+ continue
+ }
+ n = split(line, a, "@")
+ # if a[1] == "", means leading @,
+ # don't add one back in.
+ for (i = 2; i <= n; i++) {
+ if (a[i] == "") { # was an @@
+ a[i] = "@"
+ if (a[i+1] == "")
+ i++
+ }
+ }
+ print join(a, 1, n, SUBSEP) > curfile
+ }
+}
+function unexpected_eof()
+{
+ printf("%s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
+ exit 1
+}
+
+END {
+ if (curfile)
+ close(curfile)
+}
+# join.awk --- join an array into a string
+#
+# Arnold Robbins, arnold@gnu.org, Public Domain
+# May 1993
+
+function join(array, start, end, sep, result, i)
+{
+ if (sep == "")
+ sep = " "
+ else if (sep == SUBSEP) # magic value
+ sep = ""
+ result = array[start]
+ for (i = start + 1; i <= end; i++)
+ result = result sep array[i]
+ return result
+}
--- /dev/null
+some makes are stupid and will not check a directory
+against a file, so this file is a place holder. gack.
--- /dev/null
+# bisonfix.awk --- tweak awkgram.c for stupid compilers.
+
+# Copyright (C) 2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+/^#if \(! defined \(yyoverflow\) \\/ {
+ line = $0
+ sub(/\\$/, "", line)
+ getline line2
+ sub(/\\$/, "", line2)
+ getline line3
+
+ line = line line2 line3
+ print line
+ next
+}
+
+{ print }
--- /dev/null
+/*
+ * builtin.c - Builtin functions and various utility procedures
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include "awk.h"
+#if defined(HAVE_FCNTL_H)
+#include <fcntl.h>
+#endif
+#undef CHARBITS
+#undef INTBITS
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <math.h>
+#include "random.h"
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+/* The extra casts work around common compiler bugs. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
+ It is necessary at least when t == time_t. */
+#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
+ ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
+#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
+
+#ifndef INTMAX_MIN
+# define INTMAX_MIN TYPE_MINIMUM (intmax_t)
+#endif
+#ifndef UINTMAX_MAX
+# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
+#endif
+
+#ifndef SIZE_MAX /* C99 constant, can't rely on it everywhere */
+#define SIZE_MAX ((size_t) -1)
+#endif
+
+/* can declare these, since we always use the random shipped with gawk */
+extern char *initstate P((unsigned long seed, char *state, long n));
+extern char *setstate P((char *state));
+extern long random P((void));
+extern void srandom P((unsigned long seed));
+
+extern NODE **fields_arr;
+extern int output_is_tty;
+
+static NODE *sub_common P((NODE *tree, long how_many, int backdigs));
+
+/* Assume IEEE-754 arithmetic on pre-C89 hosts. */
+#ifndef FLT_RADIX
+#define FLT_RADIX 2
+#endif
+#ifndef FLT_MANT_DIG
+#define FLT_MANT_DIG 24
+#endif
+#ifndef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+#endif
+
+#ifdef _CRAY
+/* Work around a problem in conversion of doubles to exact integers. */
+#define Floor(n) floor((n) * (1.0 + DBL_EPSILON))
+#define Ceil(n) ceil((n) * (1.0 + DBL_EPSILON))
+
+/* Force the standard C compiler to use the library math functions. */
+extern double exp(double);
+double (*Exp)() = exp;
+#define exp(x) (*Exp)(x)
+extern double log(double);
+double (*Log)() = log;
+#define log(x) (*Log)(x)
+#else
+#define Floor(n) floor(n)
+#define Ceil(n) ceil(n)
+#endif
+
+#define DEFAULT_G_PRECISION 6
+
+#ifdef GFMT_WORKAROUND
+/* semi-temporary hack, mostly to gracefully handle VMS */
+static void sgfmt P((char *buf, const char *format, int alt,
+ int fwidth, int precision, double value));
+#endif /* GFMT_WORKAROUND */
+
+/*
+ * Since we supply the version of random(), we know what
+ * value to use here.
+ */
+#define GAWK_RANDOM_MAX 0x7fffffffL
+
+static void efwrite P((const void *ptr, size_t size, size_t count, FILE *fp,
+ const char *from, struct redirect *rp, int flush));
+
+/* efwrite --- like fwrite, but with error checking */
+
+static void
+efwrite(const void *ptr,
+ size_t size,
+ size_t count,
+ FILE *fp,
+ const char *from,
+ struct redirect *rp,
+ int flush)
+{
+ errno = 0;
+ if (fwrite(ptr, size, count, fp) != count)
+ goto wrerror;
+ if (flush
+ && ((fp == stdout && output_is_tty)
+ || (rp != NULL && (rp->flag & RED_NOBUF)))) {
+ fflush(fp);
+ if (ferror(fp))
+ goto wrerror;
+ }
+ return;
+
+wrerror:
+ fatal(_("%s to \"%s\" failed (%s)"), from,
+ rp ? rp->value : _("standard output"),
+ errno ? strerror(errno) : _("reason unknown"));
+}
+
+/* do_exp --- exponential function */
+
+NODE *
+do_exp(NODE *tree)
+{
+ NODE *tmp;
+ double d, res;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("exp: received non-numeric argument"));
+ d = force_number(tmp);
+ free_temp(tmp);
+ errno = 0;
+ res = exp(d);
+ if (errno == ERANGE)
+ warning(_("exp: argument %g is out of range"), d);
+ return tmp_number((AWKNUM) res);
+}
+
+/* stdfile --- return fp for a standard file */
+
+/*
+ * This function allows `fflush("/dev/stdout")' to work.
+ * The other files will be available via getredirect().
+ * /dev/stdin is not included, since fflush is only for output.
+ */
+
+static FILE *
+stdfile(const char *name, size_t len)
+{
+ if (len == 11) {
+ if (STREQN(name, "/dev/stderr", 11))
+ return stderr;
+ else if (STREQN(name, "/dev/stdout", 11))
+ return stdout;
+ }
+
+ return NULL;
+}
+
+/* do_fflush --- flush output, either named file or pipe or everything */
+
+NODE *
+do_fflush(NODE *tree)
+{
+ struct redirect *rp;
+ NODE *tmp;
+ FILE *fp;
+ int status = 0;
+ const char *file;
+
+ /* fflush() --- flush stdout */
+ if (tree == NULL) {
+ status = fflush(stdout);
+ return tmp_number((AWKNUM) status);
+ }
+
+ tmp = tree_eval(tree->lnode);
+ tmp = force_string(tmp);
+ file = tmp->stptr;
+
+ /* fflush("") --- flush all */
+ if (tmp->stlen == 0) {
+ status = flush_io();
+ free_temp(tmp);
+ return tmp_number((AWKNUM) status);
+ }
+
+ rp = getredirect(tmp->stptr, tmp->stlen);
+ status = -1;
+ if (rp != NULL) {
+ if ((rp->flag & (RED_WRITE|RED_APPEND)) == 0) {
+ if (rp->flag & RED_PIPE)
+ warning(_("fflush: cannot flush: pipe `%s' opened for reading, not writing"),
+ file);
+ else
+ warning(_("fflush: cannot flush: file `%s' opened for reading, not writing"),
+ file);
+ free_temp(tmp);
+ return tmp_number((AWKNUM) status);
+ }
+ fp = rp->fp;
+ if (fp != NULL)
+ status = fflush(fp);
+ } else if ((fp = stdfile(tmp->stptr, tmp->stlen)) != NULL) {
+ status = fflush(fp);
+ } else {
+ status = -1;
+ warning(_("fflush: `%s' is not an open file, pipe or co-process"), file);
+ }
+ free_temp(tmp);
+ return tmp_number((AWKNUM) status);
+}
+
+#ifdef MBS_SUPPORT
+/* strncasecmpmbs --- like strncasecmp(multibyte string version) */
+int
+strncasecmpmbs(const char *s1, mbstate_t mbs1, const char *s2,
+ mbstate_t mbs2, size_t n)
+{
+ int i1, i2, mbclen1, mbclen2, gap;
+ wchar_t wc1, wc2;
+
+ for (i1 = i2 = 0 ; i1 < n && i2 < n ;i1 += mbclen1, i2 += mbclen2) {
+ mbclen1 = mbrtowc(&wc1, s1 + i1, n - i1, &mbs1);
+ if (mbclen1 == (size_t) -1 || mbclen1 == (size_t) -2 || mbclen1 == 0) {
+ /* We treat it as a singlebyte character. */
+ mbclen1 = 1;
+ wc1 = s1[i1];
+ }
+ mbclen2 = mbrtowc(&wc2, s2 + i2, n - i2, &mbs2);
+ if (mbclen2 == (size_t) -1 || mbclen2 == (size_t) -2 || mbclen2 == 0) {
+ /* We treat it as a singlebyte character. */
+ mbclen2 = 1;
+ wc2 = s2[i2];
+ }
+ if ((gap = towlower(wc1) - towlower(wc2)) != 0)
+ /* s1 and s2 are not equivalent. */
+ return gap;
+ }
+ /* s1 and s2 are equivalent. */
+ return 0;
+}
+
+/* Inspect the buffer `src' and write the index of each byte to `dest'.
+ Caller must allocate `dest'.
+ e.g. str = <mb1(1)>, <mb1(2)>, a, b, <mb2(1)>, <mb2(2)>, <mb2(3)>, c
+ where mb(i) means the `i'-th byte of a multibyte character.
+ dest = 1, 2, 1, 1, 1, 2, 3. 1
+*/
+static void
+index_multibyte_buffer(char* src, char* dest, int len)
+{
+ int idx, prev_idx;
+ mbstate_t mbs, prevs;
+ memset(&prevs, 0, sizeof(mbstate_t));
+
+ for (idx = prev_idx = 0 ; idx < len ; idx++) {
+ size_t mbclen;
+ mbs = prevs;
+ mbclen = mbrlen(src + prev_idx, idx - prev_idx + 1, &mbs);
+ if (mbclen == (size_t) -1 || mbclen == 1 || mbclen == 0) {
+ /* singlebyte character. */
+ mbclen = 1;
+ prev_idx = idx + 1;
+ } else if (mbclen == (size_t) -2) {
+ /* a part of a multibyte character. */
+ mbclen = idx - prev_idx + 1;
+ } else if (mbclen > 1) {
+ /* the end of a multibyte character. */
+ prev_idx = idx + 1;
+ prevs = mbs;
+ } else {
+ /* Can't reach. */
+ }
+ dest[idx] = mbclen;
+ }
+}
+#else
+/* a dummy function */
+static void
+index_multibyte_buffer(char* src ATTRIBUTE_UNUSED, char* dest ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
+{
+ cant_happen();
+}
+#endif
+
+/* do_index --- find index of a string */
+
+NODE *
+do_index(NODE *tree)
+{
+ NODE *s1, *s2;
+ register const char *p1, *p2;
+ register size_t l1, l2;
+ long ret;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("index: received non-string first argument"));
+ if ((s2->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("index: received non-string second argument"));
+ }
+ force_string(s1);
+ force_string(s2);
+ p1 = s1->stptr;
+ p2 = s2->stptr;
+ l1 = s1->stlen;
+ l2 = s2->stlen;
+ ret = 0;
+
+ /*
+ * Icky special case, index(foo, "") should return 1,
+ * since both bwk awk and mawk do, and since match("foo", "")
+ * returns 1. This makes index("", "") work, too, fwiw.
+ */
+ if (l2 == 0) {
+ ret = 1;
+ goto out;
+ }
+
+ /* IGNORECASE will already be false if posix */
+ if (IGNORECASE) {
+ while (l1 > 0) {
+ if (l2 > l1)
+ break;
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ const wchar_t *pos;
+
+ s1 = force_wstring(s1);
+ s2 = force_wstring(s2);
+
+ pos = wcasestrstr(s1->wstptr, s1->wstlen, s2->wstptr, s2->wstlen);
+ if (pos == NULL)
+ ret = 0;
+ else
+ ret = pos - s1->wstptr + 1; /* 1-based */
+ goto out;
+ } else {
+#endif
+ /*
+ * Could use tolower(*p1) == tolower(*p2) here. See discussion
+ * in eval.c as to why not.
+ */
+ if (casetable[(unsigned char)*p1] == casetable[(unsigned char)*p2]
+ && (l2 == 1 || strncasecmp(p1, p2, l2) == 0)) {
+ ret = 1 + s1->stlen - l1;
+ break;
+ }
+ l1--;
+ p1++;
+#ifdef MBS_SUPPORT
+ }
+#endif
+ }
+ } else {
+ while (l1 > 0) {
+ if (l2 > l1)
+ break;
+ if (*p1 == *p2
+ && (l2 == 1 || (l2 > 0 && memcmp(p1, p2, l2) == 0))) {
+ ret = 1 + s1->stlen - l1;
+ break;
+ }
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ const wchar_t *pos;
+
+ s1 = force_wstring(s1);
+ s2 = force_wstring(s2);
+
+ pos = wstrstr(s1->wstptr, s1->wstlen, s2->wstptr, s2->wstlen);
+ if (pos == NULL)
+ ret = 0;
+ else
+ ret = pos - s1->wstptr + 1; /* 1-based */
+ goto out;
+ } else {
+ l1--;
+ p1++;
+ }
+#else
+ l1--;
+ p1++;
+#endif
+ }
+ }
+out:
+ free_temp(s1);
+ free_temp(s2);
+ return tmp_number((AWKNUM) ret);
+}
+
+/* double_to_int --- convert double to int, used several places */
+
+double
+double_to_int(double d)
+{
+ if (d >= 0)
+ d = Floor(d);
+ else
+ d = Ceil(d);
+ return d;
+}
+
+/* do_int --- convert double to int for awk */
+
+NODE *
+do_int(NODE *tree)
+{
+ NODE *tmp;
+ double d;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("int: received non-numeric argument"));
+ d = force_number(tmp);
+ d = double_to_int(d);
+ free_temp(tmp);
+ return tmp_number((AWKNUM) d);
+}
+
+/* do_length --- length of a string or $0 */
+
+NODE *
+do_length(NODE *tree)
+{
+ NODE *tmp;
+ size_t len;
+
+ if (tree->lnode->type == Node_var_array
+ || tree->lnode->type == Node_array_ref) {
+ NODE *array_var = tree->lnode;
+
+ if (array_var->type == Node_array_ref)
+ array_var = array_var->orig_array;
+
+ if (do_lint)
+ lintwarn(_("`length(array)' is a gawk extension"));
+ if (do_posix)
+ goto normal; /* will die as fatal error */
+
+ return tmp_number((AWKNUM) array_var->table_size);
+ } else {
+normal:
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("length: received non-string argument"));
+ tmp = force_string(tmp);
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ tmp = force_wstring(tmp);
+ len = tmp->wstlen;
+ } else
+#endif
+ len = tmp->stlen;
+
+ free_temp(tmp);
+ return tmp_number((AWKNUM) len);
+ }
+}
+
+/* do_log --- the log function */
+
+NODE *
+do_log(NODE *tree)
+{
+ NODE *tmp;
+ double d, arg;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("log: received non-numeric argument"));
+ arg = (double) force_number(tmp);
+ if (arg < 0.0)
+ warning(_("log: received negative argument %g"), arg);
+ d = log(arg);
+ free_temp(tmp);
+ return tmp_number((AWKNUM) d);
+}
+
+/*
+ * format_tree() formats nodes of a tree, starting with a left node,
+ * and accordingly to a fmt_string providing a format like in
+ * printf family from C library. Returns a string node which value
+ * is a formatted string. Called by sprintf function.
+ *
+ * It is one of the uglier parts of gawk. Thanks to Michal Jaegermann
+ * for taming this beast and making it compatible with ANSI C.
+ */
+
+NODE *
+format_tree(
+ const char *fmt_string,
+ size_t n0,
+ register NODE *carg,
+ long num_args)
+{
+/* copy 'l' bytes from 's' to 'obufout' checking for space in the process */
+/* difference of pointers should be of ptrdiff_t type, but let us be kind */
+#define bchunk(s, l) if (l) { \
+ while ((l) > ofre) { \
+ size_t olen = obufout - obuf; \
+ erealloc(obuf, char *, osiz * 2, "format_tree"); \
+ ofre += osiz; \
+ osiz *= 2; \
+ obufout = obuf + olen; \
+ } \
+ memcpy(obufout, s, (size_t) (l)); \
+ obufout += (l); \
+ ofre -= (l); \
+}
+
+/* copy one byte from 's' to 'obufout' checking for space in the process */
+#define bchunk_one(s) { \
+ if (ofre < 1) { \
+ size_t olen = obufout - obuf; \
+ erealloc(obuf, char *, osiz * 2, "format_tree"); \
+ ofre += osiz; \
+ osiz *= 2; \
+ obufout = obuf + olen; \
+ } \
+ *obufout++ = *s; \
+ --ofre; \
+}
+
+/* Is there space for something L big in the buffer? */
+#define chksize(l) if ((l) > ofre) { \
+ size_t olen = obufout - obuf; \
+ erealloc(obuf, char *, osiz * 2, "format_tree"); \
+ obufout = obuf + olen; \
+ ofre += osiz; \
+ osiz *= 2; \
+}
+
+ static NODE **the_args = 0;
+ static size_t args_size = 0;
+ size_t cur_arg = 0;
+
+ auto NODE **save_args = 0;
+ auto size_t save_args_size = 0;
+ static int call_level = 0;
+
+ NODE *r;
+ int i;
+ int toofew = FALSE;
+ char *obuf, *obufout;
+ size_t osiz, ofre;
+ const char *chbuf;
+ const char *s0, *s1;
+ int cs1;
+ NODE *arg;
+ long fw, prec, argnum;
+ int used_dollar;
+ int lj, alt, big, bigbig, small, have_prec, need_format;
+ long *cur = NULL;
+#ifdef sun386 /* Can't cast unsigned (int/long) from ptr->value */
+ long tmp_uval; /* on 386i 4.0.1 C compiler -- it just hangs */
+#endif
+ uintmax_t uval;
+ int sgn;
+ int base = 0;
+ char cpbuf[30]; /* if we have numbers bigger than 30 */
+ char *cend = &cpbuf[30];/* chars, we lose, but seems unlikely */
+ char *cp;
+ const char *fill;
+ AWKNUM tmpval;
+ char signchar = FALSE;
+ size_t len;
+ int zero_flag = FALSE;
+ int quote_flag = FALSE;
+ int ii, jj;
+ static const char sp[] = " ";
+ static const char zero_string[] = "0";
+ static const char lchbuf[] = "0123456789abcdef";
+ static const char Uchbuf[] = "0123456789ABCDEF";
+
+#define INITIAL_OUT_SIZE 512
+ emalloc(obuf, char *, INITIAL_OUT_SIZE, "format_tree");
+ obufout = obuf;
+ osiz = INITIAL_OUT_SIZE;
+ ofre = osiz - 2;
+
+ /*
+ * Icky problem. If the args make a nested call to printf/sprintf,
+ * we end up clobbering the static variable `the_args'. Not good.
+ * We don't just malloc and free the_args each time, since most of the
+ * time there aren't nested calls. But if this is a nested call,
+ * save the memory pointed to by the_args and allocate a fresh
+ * array. Then free it on end.
+ */
+ if (++call_level > 1) { /* nested */
+ save_args = the_args;
+ save_args_size = args_size;
+
+ args_size = 0; /* force fresh allocation */
+ }
+
+ if (args_size == 0) {
+ /* allocate array */
+ emalloc(the_args, NODE **, (num_args+1) * sizeof(NODE *), "format_tree");
+ args_size = num_args + 1;
+ } else if (num_args + 1 > args_size) {
+ /* grow it */
+ erealloc(the_args, NODE **, (num_args+1) * sizeof(NODE *), "format_tree");
+ args_size = num_args + 1;
+ }
+
+
+ /* fill it in */
+ /*
+ * We ignore the_args[0] since format strings use
+ * 1-based numbers to indicate the arguments. It's
+ * easiest to just convert to int and index, without
+ * having to remember to subtract 1.
+ */
+ memset(the_args, '\0', num_args * sizeof(NODE *));
+ for (i = 1; carg != NULL; i++, carg = carg->rnode) {
+ NODE *tmp;
+
+ /* Here lies the wumpus's other brother. R.I.P. */
+ tmp = tree_eval(carg->lnode);
+ the_args[i] = dupnode(tmp);
+ free_temp(tmp);
+ }
+ assert(i == num_args);
+ cur_arg = 1;
+
+ /*
+ * Check first for use of `count$'.
+ * If plain argument retrieval was used earlier, choke.
+ * Otherwise, return the requested argument.
+ * If not `count$' now, but it was used earlier, choke.
+ * If this format is more than total number of args, choke.
+ * Otherwise, return the current argument.
+ */
+#define parse_next_arg() { \
+ if (argnum > 0) { \
+ if (cur_arg > 1) \
+ fatal(_("must use `count$' on all formats or none")); \
+ arg = the_args[argnum]; \
+ } else if (used_dollar) { \
+ fatal(_("must use `count$' on all formats or none")); \
+ arg = 0; /* shutup the compiler */ \
+ } else if (cur_arg >= num_args) { \
+ arg = 0; /* shutup the compiler */ \
+ toofew = TRUE; \
+ break; \
+ } else { \
+ arg = the_args[cur_arg]; \
+ cur_arg++; \
+ } \
+}
+
+ need_format = FALSE;
+ used_dollar = FALSE;
+
+ s0 = s1 = fmt_string;
+ while (n0-- > 0) {
+ if (*s1 != '%') {
+ s1++;
+ continue;
+ }
+ need_format = TRUE;
+ bchunk(s0, s1 - s0);
+ s0 = s1;
+ cur = &fw;
+ fw = 0;
+ prec = 0;
+ argnum = 0;
+ have_prec = FALSE;
+ signchar = FALSE;
+ zero_flag = FALSE;
+ lj = alt = big = bigbig = small = FALSE;
+ fill = sp;
+ cp = cend;
+ chbuf = lchbuf;
+ s1++;
+
+retry:
+ if (n0-- == 0) /* ran out early! */
+ break;
+
+ switch (cs1 = *s1++) {
+ case (-1): /* dummy case to allow for checking */
+check_pos:
+ if (cur != &fw)
+ break; /* reject as a valid format */
+ goto retry;
+ case '%':
+ need_format = FALSE;
+ /*
+ * 29 Oct. 2002:
+ * The C99 standard pages 274 and 279 seem to imply that
+ * since there's no arg converted, the field width doesn't
+ * apply. The code already was that way, but this
+ * comment documents it, at least in the code.
+ */
+ bchunk_one("%");
+ s0 = s1;
+ break;
+
+ case '0':
+ /*
+ * Only turn on zero_flag if we haven't seen
+ * the field width or precision yet. Otherwise,
+ * screws up floating point formatting.
+ */
+ if (cur == & fw)
+ zero_flag = TRUE;
+ if (lj)
+ goto retry;
+ /* FALL through */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (cur == NULL)
+ break;
+ if (prec >= 0)
+ *cur = cs1 - '0';
+ /*
+ * with a negative precision *cur is already set
+ * to -1, so it will remain negative, but we have
+ * to "eat" precision digits in any case
+ */
+ while (n0 > 0 && *s1 >= '0' && *s1 <= '9') {
+ --n0;
+ *cur = *cur * 10 + *s1++ - '0';
+ }
+ if (prec < 0) /* negative precision is discarded */
+ have_prec = FALSE;
+ if (cur == &prec)
+ cur = NULL;
+ if (n0 == 0) /* badly formatted control string */
+ continue;
+ goto retry;
+ case '$':
+ if (do_traditional)
+ fatal(_("`$' is not permitted in awk formats"));
+ if (cur == &fw) {
+ argnum = fw;
+ fw = 0;
+ used_dollar = TRUE;
+ if (argnum <= 0)
+ fatal(_("arg count with `$' must be > 0"));
+ if (argnum >= num_args)
+ fatal(_("arg count %ld greater than total number of supplied arguments"), argnum);
+ } else
+ fatal(_("`$' not permitted after period in format"));
+ goto retry;
+ case '*':
+ if (cur == NULL)
+ break;
+ if (! do_traditional && ISDIGIT(*s1)) {
+ int val = 0;
+
+ for (; n0 > 0 && *s1 && ISDIGIT(*s1); s1++, n0--) {
+ val *= 10;
+ val += *s1 - '0';
+ }
+ if (*s1 != '$') {
+ fatal(_("no `$' supplied for positional field width or precision"));
+ } else {
+ s1++;
+ n0--;
+ }
+ if (val >= num_args) {
+ toofew = TRUE;
+ break;
+ }
+ arg = the_args[val];
+ } else {
+ parse_next_arg();
+ }
+ *cur = force_number(arg);
+ if (*cur < 0 && cur == &fw) {
+ *cur = -*cur;
+ lj++;
+ }
+ if (cur == &prec) {
+ if (*cur >= 0)
+ have_prec = TRUE;
+ else
+ have_prec = FALSE;
+ cur = NULL;
+ }
+ goto retry;
+ case ' ': /* print ' ' or '-' */
+ /* 'space' flag is ignored */
+ /* if '+' already present */
+ if (signchar != FALSE)
+ goto check_pos;
+ /* FALL THROUGH */
+ case '+': /* print '+' or '-' */
+ signchar = cs1;
+ goto check_pos;
+ case '-':
+ if (prec < 0)
+ break;
+ if (cur == &prec) {
+ prec = -1;
+ goto retry;
+ }
+ fill = sp; /* if left justified then other */
+ lj++; /* filling is ignored */
+ goto check_pos;
+ case '.':
+ if (cur != &fw)
+ break;
+ cur = ≺
+ have_prec = TRUE;
+ goto retry;
+ case '#':
+ alt = TRUE;
+ goto check_pos;
+#if defined(HAVE_LOCALE_H)
+ case '\'':
+ quote_flag = TRUE;
+ goto check_pos;
+#endif
+ case 'l':
+ if (big)
+ break;
+ else {
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("`l' is meaningless in awk formats; ignored"));
+ warned = TRUE;
+ }
+ if (do_posix)
+ fatal(_("`l' is not permitted in POSIX awk formats"));
+ }
+ big = TRUE;
+ goto retry;
+ case 'L':
+ if (bigbig)
+ break;
+ else {
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("`L' is meaningless in awk formats; ignored"));
+ warned = TRUE;
+ }
+ if (do_posix)
+ fatal(_("`L' is not permitted in POSIX awk formats"));
+ }
+ bigbig = TRUE;
+ goto retry;
+ case 'h':
+ if (small)
+ break;
+ else {
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("`h' is meaningless in awk formats; ignored"));
+ warned = TRUE;
+ }
+ if (do_posix)
+ fatal(_("`h' is not permitted in POSIX awk formats"));
+ }
+ small = TRUE;
+ goto retry;
+ case 'c':
+ need_format = FALSE;
+ if (zero_flag && ! lj)
+ fill = zero_string;
+ parse_next_arg();
+ /* user input that looks numeric is numeric */
+ if ((arg->flags & (MAYBE_NUM|NUMBER)) == MAYBE_NUM)
+ (void) force_number(arg);
+ if (arg->flags & NUMBER) {
+#ifdef sun386
+ tmp_uval = arg->numbr;
+ uval = (unsigned long) tmp_uval;
+#else
+ uval = (uintmax_t) arg->numbr;
+#endif
+ cpbuf[0] = uval;
+ prec = 1;
+ cp = cpbuf;
+ goto pr_tail;
+ }
+ /*
+ * As per POSIX, only output first character of a
+ * string value. Thus, we ignore any provided
+ * precision, forcing it to 1. (Didn't this
+ * used to work? 6/2003.)
+ */
+ prec = 1;
+ cp = arg->stptr;
+ goto pr_tail;
+ case 's':
+ need_format = FALSE;
+ if (zero_flag && ! lj)
+ fill = zero_string;
+ parse_next_arg();
+ arg = force_string(arg);
+ if (! have_prec || prec > arg->stlen)
+ prec = arg->stlen;
+ cp = arg->stptr;
+ goto pr_tail;
+ case 'd':
+ case 'i':
+ need_format = FALSE;
+ parse_next_arg();
+ tmpval = force_number(arg);
+
+ /*
+ * ``The result of converting a zero value with a
+ * precision of zero is no characters.''
+ */
+ if (have_prec && prec == 0 && tmpval == 0)
+ goto pr_tail;
+
+ if (tmpval < 0) {
+ if (tmpval < INTMAX_MIN)
+ goto out_of_range;
+ sgn = TRUE;
+ uval = - (uintmax_t) (intmax_t) tmpval;
+ } else {
+ /* Use !, so that NaNs are out of range. */
+ if (! (tmpval <= UINTMAX_MAX))
+ goto out_of_range;
+ sgn = FALSE;
+ uval = (uintmax_t) tmpval;
+ }
+ ii = jj = 0;
+ do {
+ *--cp = (char) ('0' + uval % 10);
+ uval /= 10;
+#if defined(HAVE_LOCALE_H)
+ if (quote_flag && loc.grouping[ii] && ++jj == loc.grouping[ii]) {
+ if (uval) /* only add if more digits coming */
+ *--cp = loc.thousands_sep[0]; /* XXX - assumption it's one char */
+ if (loc.grouping[ii+1] == 0)
+ jj = 0; /* keep using current val in loc.grouping[ii] */
+ else if (loc.grouping[ii+1] == CHAR_MAX)
+ quote_flag = FALSE;
+ else {
+ ii++;
+ jj = 0;
+ }
+ }
+#endif
+ } while (uval > 0);
+
+ /* add more output digits to match the precision */
+ if (have_prec) {
+ while (cend - cp < prec)
+ *--cp = '0';
+ }
+
+ if (sgn)
+ *--cp = '-';
+ else if (signchar)
+ *--cp = signchar;
+ /*
+ * When to fill with zeroes is of course not simple.
+ * First: No zero fill if left-justifying.
+ * Next: There seem to be two cases:
+ * A '0' without a precision, e.g. %06d
+ * A precision with no field width, e.g. %.10d
+ * Any other case, we don't want to fill with zeroes.
+ */
+ if (! lj
+ && ((zero_flag && ! have_prec)
+ || (fw == 0 && have_prec)))
+ fill = zero_string;
+ if (prec > fw)
+ fw = prec;
+ prec = cend - cp;
+ if (fw > prec && ! lj && fill != sp
+ && (*cp == '-' || signchar)) {
+ bchunk_one(cp);
+ cp++;
+ prec--;
+ fw--;
+ }
+ goto pr_tail;
+ case 'X':
+ chbuf = Uchbuf; /* FALL THROUGH */
+ case 'x':
+ base += 6; /* FALL THROUGH */
+ case 'u':
+ base += 2; /* FALL THROUGH */
+ case 'o':
+ base += 8;
+ need_format = FALSE;
+ parse_next_arg();
+ tmpval = force_number(arg);
+
+ /*
+ * ``The result of converting a zero value with a
+ * precision of zero is no characters.''
+ *
+ * If I remember the ANSI C standard, though,
+ * it says that for octal conversions
+ * the precision is artificially increased
+ * to add an extra 0 if # is supplied.
+ * Indeed, in C,
+ * printf("%#.0o\n", 0);
+ * prints a single 0.
+ */
+ if (! alt && have_prec && prec == 0 && tmpval == 0)
+ goto pr_tail;
+
+ if (tmpval < 0) {
+ if (tmpval < INTMAX_MIN)
+ goto out_of_range;
+ uval = (uintmax_t) (intmax_t) tmpval;
+ } else {
+ /* Use !, so that NaNs are out of range. */
+ if (! (tmpval <= UINTMAX_MAX))
+ goto out_of_range;
+ uval = (uintmax_t) tmpval;
+ }
+ /*
+ * When to fill with zeroes is of course not simple.
+ * First: No zero fill if left-justifying.
+ * Next: There seem to be two cases:
+ * A '0' without a precision, e.g. %06d
+ * A precision with no field width, e.g. %.10d
+ * Any other case, we don't want to fill with zeroes.
+ */
+ if (! lj
+ && ((zero_flag && ! have_prec)
+ || (fw == 0 && have_prec)))
+ fill = zero_string;
+
+ ii = jj = 0;
+ do {
+ *--cp = chbuf[uval % base];
+ uval /= base;
+#if defined(HAVE_LOCALE_H)
+ if (base == 10 && quote_flag && loc.grouping[ii] && ++jj == loc.grouping[ii]) {
+ if (uval) /* only add if more digits coming */
+ *--cp = loc.thousands_sep[0]; /* XXX --- assumption it's one char */
+ if (loc.grouping[ii+1] == 0)
+ jj = 0; /* keep using current val in loc.grouping[ii] */
+ else if (loc.grouping[ii+1] == CHAR_MAX)
+ quote_flag = FALSE;
+ else {
+ ii++;
+ jj = 0;
+ }
+ }
+#endif
+ } while (uval > 0);
+
+ /* add more output digits to match the precision */
+ if (have_prec) {
+ while (cend - cp < prec)
+ *--cp = '0';
+ }
+
+ if (alt && tmpval != 0) {
+ if (base == 16) {
+ *--cp = cs1;
+ *--cp = '0';
+ if (fill != sp) {
+ bchunk(cp, 2);
+ cp += 2;
+ fw -= 2;
+ }
+ } else if (base == 8)
+ *--cp = '0';
+ }
+ base = 0;
+ if (prec > fw)
+ fw = prec;
+ prec = cend - cp;
+ pr_tail:
+ if (! lj) {
+ while (fw > prec) {
+ bchunk_one(fill);
+ fw--;
+ }
+ }
+ bchunk(cp, (int) prec);
+ while (fw > prec) {
+ bchunk_one(fill);
+ fw--;
+ }
+ s0 = s1;
+ break;
+
+ out_of_range:
+ /* out of range - emergency use of %g format */
+ if (do_lint)
+ lintwarn(_("[s]printf: value %g is out of range for `%%%c' format"),
+ tmpval, cs1);
+ cs1 = 'g';
+ goto format_float;
+
+ case 'F':
+#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
+ cs1 = 'f';
+ /* FALL THROUGH */
+#endif
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'f':
+ case 'E':
+ need_format = FALSE;
+ parse_next_arg();
+ tmpval = force_number(arg);
+ format_float:
+ if (! have_prec)
+ prec = DEFAULT_G_PRECISION;
+ chksize(fw + prec + 9); /* 9 == slop */
+#ifdef VAXCRTL
+ /* pre-ANSI library doesn't handle '0' flag
+ correctly in many cases; reject it */
+ if (zero_flag
+ && (lj || (signchar && signchar != '+')))
+ zero_flag = FALSE;
+#endif
+ cp = cpbuf;
+ *cp++ = '%';
+ if (lj)
+ *cp++ = '-';
+ if (signchar)
+ *cp++ = signchar;
+ if (alt)
+ *cp++ = '#';
+ if (zero_flag)
+ *cp++ = '0';
+ if (quote_flag)
+ *cp++ = '\'';
+ strcpy(cp, "*.*");
+ cp += 3;
+ *cp++ = cs1;
+ *cp = '\0';
+#ifndef GFMT_WORKAROUND
+ (void) sprintf(obufout, cpbuf,
+ (int) fw, (int) prec, (double) tmpval);
+#else /* GFMT_WORKAROUND */
+ if (cs1 == 'g' || cs1 == 'G')
+ sgfmt(obufout, cpbuf, (int) alt,
+ (int) fw, (int) prec, (double) tmpval);
+ else
+ (void) sprintf(obufout, cpbuf,
+ (int) fw, (int) prec, (double) tmpval);
+#endif /* GFMT_WORKAROUND */
+ len = strlen(obufout);
+ ofre -= len;
+ obufout += len;
+ s0 = s1;
+ break;
+ default:
+ break;
+ }
+ if (toofew)
+ fatal("%s\n\t`%s'\n\t%*s%s",
+ _("not enough arguments to satisfy format string"),
+ fmt_string, (int) (s1 - fmt_string - 1), "",
+ _("^ ran out for this one"));
+ }
+ if (do_lint) {
+ if (need_format)
+ lintwarn(
+ _("[s]printf: format specifier does not have control letter"));
+ if (cur_arg < num_args)
+ lintwarn(
+ _("too many arguments supplied for format string"));
+ }
+ bchunk(s0, s1 - s0);
+ r = make_str_node(obuf, obufout - obuf, ALREADY_MALLOCED);
+ r->flags |= TEMP;
+
+ for (i = 1; i < num_args; i++) {
+ unref(the_args[i]);
+ }
+
+ if (call_level-- > 1) {
+ free(the_args);
+ the_args = save_args;
+ args_size = save_args_size;
+ }
+
+ return r;
+}
+
+/* do_sprintf --- perform sprintf */
+
+NODE *
+do_sprintf(NODE *tree)
+{
+ NODE *r;
+ NODE *sfmt = force_string(tree_eval(tree->lnode));
+
+ r = format_tree(sfmt->stptr, sfmt->stlen, tree->rnode, tree->printf_count);
+ free_temp(sfmt);
+ return r;
+}
+
+/*
+ * redirect_to_fp --- return fp for redirection, NULL on failure
+ * or stdout if no redirection, used by all print routines
+ */
+
+static inline FILE *
+redirect_to_fp(NODE *tree, struct redirect **rpp)
+{
+ int errflg; /* not used, sigh */
+ struct redirect *rp;
+
+ if (tree == NULL)
+ return stdout;
+
+ rp = redirect(tree, &errflg);
+ if (rp != NULL) {
+ *rpp = rp;
+ return rp->fp;
+ }
+
+ return NULL;
+}
+
+/* do_printf --- perform printf, including redirection */
+
+void
+do_printf(NODE *tree)
+{
+ struct redirect *rp = NULL;
+ register FILE *fp;
+
+ if (tree->lnode == NULL) {
+ if (do_traditional) {
+ if (do_lint)
+ lintwarn(_("printf: no arguments"));
+ return; /* bwk accepts it silently */
+ }
+ fatal(_("printf: no arguments"));
+ }
+
+ fp = redirect_to_fp(tree->rnode, & rp);
+ if (fp == NULL)
+ return;
+ tree->lnode->printf_count = tree->printf_count;
+ tree = do_sprintf(tree->lnode);
+ efwrite(tree->stptr, sizeof(char), tree->stlen, fp, "printf", rp, TRUE);
+ if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
+ fflush(rp->fp);
+ free_temp(tree);
+}
+
+/* do_sqrt --- do the sqrt function */
+
+NODE *
+do_sqrt(NODE *tree)
+{
+ NODE *tmp;
+ double arg;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("sqrt: received non-numeric argument"));
+ arg = (double) force_number(tmp);
+ free_temp(tmp);
+ if (arg < 0.0)
+ warning(_("sqrt: called with negative argument %g"), arg);
+ return tmp_number((AWKNUM) sqrt(arg));
+}
+
+/* do_substr --- do the substr function */
+
+NODE *
+do_substr(NODE *tree)
+{
+ NODE *t1, *t2, *t3;
+ NODE *r;
+ register size_t indx;
+ size_t length;
+ double d_index, d_length;
+ size_t src_len;
+
+ t1 = force_string(tree_eval(tree->lnode));
+ t2 = tree_eval(tree->rnode->lnode);
+ d_index = force_number(t2);
+ free_temp(t2);
+
+ /* the weird `! (foo)' tests help catch NaN values. */
+ if (! (d_index >= 1)) {
+ if (do_lint)
+ lintwarn(_("substr: start index %g is invalid, using 1"),
+ d_index);
+ d_index = 1;
+ }
+ if (do_lint && double_to_int(d_index) != d_index)
+ lintwarn(_("substr: non-integer start index %g will be truncated"),
+ d_index);
+
+ /* awk indices are from 1, C's are from 0 */
+ if (d_index <= SIZE_MAX)
+ indx = d_index - 1;
+ else
+ indx = SIZE_MAX;
+
+ if (tree->rnode->rnode == NULL) { /* third arg. missing */
+ /* use remainder of string */
+ length = t1->stlen - indx;
+ d_length = length; /* set here in case used in diagnostics, below */
+ } else {
+ t3 = tree_eval(tree->rnode->rnode->lnode);
+ d_length = force_number(t3);
+ free_temp(t3);
+ if (! (d_length >= 1)) {
+ if (do_lint == LINT_ALL)
+ lintwarn(_("substr: length %g is not >= 1"), d_length);
+ else if (do_lint == LINT_INVALID && ! (d_length >= 0))
+ lintwarn(_("substr: length %g is not >= 0"), d_length);
+ free_temp(t1);
+ return Nnull_string;
+ }
+ if (do_lint) {
+ if (double_to_int(d_length) != d_length)
+ lintwarn(
+ _("substr: non-integer length %g will be truncated"),
+ d_length);
+
+ if (d_length > SIZE_MAX)
+ lintwarn(
+ _("substr: length %g too big for string indexing, truncating to %g"),
+ d_length, (double) SIZE_MAX);
+ }
+ if (d_length < SIZE_MAX)
+ length = d_length;
+ else
+ length = SIZE_MAX;
+ }
+
+ if (t1->stlen == 0) {
+ /* substr("", 1, 0) produces a warning only if LINT_ALL */
+ if (do_lint && (do_lint == LINT_ALL || ((indx | length) != 0)))
+ lintwarn(_("substr: source string is zero length"));
+ free_temp(t1);
+ return Nnull_string;
+ }
+
+ /* get total len of input string, for following checks */
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ t1 = force_wstring(t1);
+ src_len = t1->wstlen;
+ } else
+#endif
+ src_len = t1->stlen;
+
+ if (indx >= src_len) {
+ if (do_lint)
+ lintwarn(_("substr: start index %g is past end of string"),
+ d_index);
+ free_temp(t1);
+ return Nnull_string;
+ }
+ if (length > src_len - indx) {
+ if (do_lint)
+ lintwarn(
+ _("substr: length %g at start index %g exceeds length of first argument (%lu)"),
+ d_length, d_index, (unsigned long int) src_len);
+ length = src_len - indx;
+ }
+
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ /* multibyte case, more work */
+ size_t result;
+ wchar_t *wp;
+ mbstate_t mbs;
+ char *substr, *cp;
+
+ /* force_wstring() already called */
+
+ if (t1->stlen == t1->wstlen)
+ goto single_byte_case;
+
+ /*
+ * Convert the wide chars in t1->wstptr back into m.b. chars.
+ * This is pretty grotty, but it's the most straightforward
+ * way to do things.
+ */
+ memset(& mbs, 0, sizeof(mbs));
+ emalloc(substr, char *, (length * gawk_mb_cur_max) + 2, "do_substr");
+ wp = t1->wstptr + indx;
+ for (cp = substr; length > 0; length--) {
+ result = wcrtomb(cp, *wp, & mbs);
+ if (result == (size_t) -1) /* what to do? break seems best */
+ break;
+ cp += result;
+ wp++;
+ }
+ *cp = '\0';
+ r = make_str_node(substr, cp - substr, ALREADY_MALLOCED);
+ r->flags |= TEMP;
+ } else {
+ /* single byte case, easy */
+single_byte_case:
+ r = tmp_string(t1->stptr + indx, length);
+ }
+#else
+ r = tmp_string(t1->stptr + indx, length);
+#endif
+
+ free_temp(t1);
+ return r;
+}
+
+/* do_strftime --- format a time stamp */
+
+NODE *
+do_strftime(NODE *tree)
+{
+ NODE *t1, *t2, *ret;
+ struct tm *tm;
+ time_t fclock;
+ char *bufp;
+ size_t buflen, bufsize;
+ char buf[BUFSIZ];
+ /* FIXME: One day make %d be %e, after C 99 is common. */
+ static const char def_format[] = "%a %b %d %H:%M:%S %Z %Y";
+ const char *format;
+ int formatlen;
+
+ /* set defaults first */
+ format = def_format; /* traditional date format */
+ formatlen = strlen(format);
+ (void) time(&fclock); /* current time of day */
+
+ t1 = t2 = NULL;
+ if (tree != NULL) { /* have args */
+ if (tree->lnode != NULL) {
+ NODE *tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("strftime: received non-string first argument"));
+ t1 = force_string(tmp);
+ format = t1->stptr;
+ formatlen = t1->stlen;
+ if (formatlen == 0) {
+ if (do_lint)
+ lintwarn(_("strftime: received empty format string"));
+ free_temp(t1);
+ return tmp_string("", 0);
+ }
+ }
+
+ if (tree->rnode != NULL) {
+ t2 = tree_eval(tree->rnode->lnode);
+ if (do_lint && (t2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("strftime: received non-numeric second argument"));
+ fclock = (time_t) force_number(t2);
+ free_temp(t2);
+ }
+ }
+
+ tm = localtime(&fclock);
+
+ bufp = buf;
+ bufsize = sizeof(buf);
+ for (;;) {
+ *bufp = '\0';
+ buflen = strftime(bufp, bufsize, format, tm);
+ /*
+ * buflen can be zero EITHER because there's not enough
+ * room in the string, or because the control command
+ * goes to the empty string. Make a reasonable guess that
+ * if the buffer is 1024 times bigger than the length of the
+ * format string, it's not failing for lack of room.
+ * Thanks to Paul Eggert for pointing out this issue.
+ */
+ if (buflen > 0 || bufsize >= 1024 * formatlen)
+ break;
+ bufsize *= 2;
+ if (bufp == buf)
+ emalloc(bufp, char *, bufsize, "do_strftime");
+ else
+ erealloc(bufp, char *, bufsize, "do_strftime");
+ }
+ ret = tmp_string(bufp, buflen);
+ if (bufp != buf)
+ free(bufp);
+ if (t1)
+ free_temp(t1);
+ return ret;
+}
+
+/* do_systime --- get the time of day */
+
+NODE *
+do_systime(NODE *tree ATTRIBUTE_UNUSED)
+{
+ time_t lclock;
+
+ (void) time(&lclock);
+ return tmp_number((AWKNUM) lclock);
+}
+
+/* do_mktime --- turn a time string into a timestamp */
+
+NODE *
+do_mktime(NODE *tree)
+{
+ NODE *t1;
+ struct tm then;
+ long year;
+ int month, day, hour, minute, second, count;
+ int dst = -1; /* default is unknown */
+ time_t then_stamp;
+ char save;
+
+ t1 = tree_eval(tree->lnode);
+ if (do_lint && (t1->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("mktime: received non-string argument"));
+ t1 = force_string(t1);
+
+ save = t1->stptr[t1->stlen];
+ t1->stptr[t1->stlen] = '\0';
+
+ count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d",
+ & year, & month, & day,
+ & hour, & minute, & second,
+ & dst);
+
+ t1->stptr[t1->stlen] = save;
+ free_temp(t1);
+
+ if (count < 6
+ || month < month - 1
+ || year < year - 1900 || year - 1900 != (int) (year - 1900))
+ return tmp_number((AWKNUM) -1);
+
+ memset(& then, '\0', sizeof(then));
+ then.tm_sec = second;
+ then.tm_min = minute;
+ then.tm_hour = hour;
+ then.tm_mday = day;
+ then.tm_mon = month - 1;
+ then.tm_year = year - 1900;
+ then.tm_isdst = dst;
+
+ then_stamp = mktime(& then);
+ return tmp_number((AWKNUM) then_stamp);
+}
+
+/* do_system --- run an external command */
+
+NODE *
+do_system(NODE *tree)
+{
+ NODE *tmp;
+ int ret = 0;
+ char *cmd;
+ char save;
+
+ (void) flush_io(); /* so output is synchronous with gawk's */
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("system: received non-string argument"));
+ cmd = force_string(tmp)->stptr;
+
+ if (cmd && *cmd) {
+ /* insure arg to system is zero-terminated */
+
+ /*
+ * From: David Trueman <david@cs.dal.ca>
+ * To: arnold@cc.gatech.edu (Arnold Robbins)
+ * Date: Wed, 3 Nov 1993 12:49:41 -0400
+ *
+ * It may not be necessary to save the character, but
+ * I'm not sure. It would normally be the field
+ * separator. If the parse has not yet gone beyond
+ * that, it could mess up (although I doubt it). If
+ * FIELDWIDTHS is being used, it might be the first
+ * character of the next field. Unless someone wants
+ * to check it out exhaustively, I suggest saving it
+ * for now...
+ */
+ save = cmd[tmp->stlen];
+ cmd[tmp->stlen] = '\0';
+
+ os_restore_mode(fileno(stdin));
+ ret = system(cmd);
+ if (ret != -1)
+ ret = WEXITSTATUS(ret);
+ if ((BINMODE & 1) != 0)
+ os_setbinmode(fileno(stdin), O_BINARY);
+
+ cmd[tmp->stlen] = save;
+ }
+ free_temp(tmp);
+ return tmp_number((AWKNUM) ret);
+}
+
+extern NODE **fmt_list; /* declared in eval.c */
+
+/* do_print --- print items, separated by OFS, terminated with ORS */
+
+void
+do_print(register NODE *tree)
+{
+ register NODE **t;
+ struct redirect *rp = NULL;
+ register FILE *fp;
+ int numnodes, i;
+ NODE *save;
+ NODE *tval;
+
+ fp = redirect_to_fp(tree->rnode, & rp);
+ if (fp == NULL)
+ return;
+
+ /*
+ * General idea is to evaluate all the expressions first and
+ * then print them, otherwise you get suprising behavior.
+ * See test/prtoeval.awk for an example program.
+ */
+ save = tree = tree->lnode;
+ for (numnodes = 0; tree != NULL; tree = tree->rnode)
+ numnodes++;
+ emalloc(t, NODE **, numnodes * sizeof(NODE *), "do_print");
+
+ tree = save;
+ for (i = 0; tree != NULL; i++, tree = tree->rnode) {
+ NODE *n;
+
+ /* Here lies the wumpus. R.I.P. */
+ n = tree_eval(tree->lnode);
+ t[i] = dupnode(n);
+ free_temp(n);
+
+ if ((t[i]->flags & (NUMBER|STRING)) == NUMBER) {
+ if (OFMTidx == CONVFMTidx)
+ (void) force_string(t[i]);
+ else {
+ tval = tmp_number(t[i]->numbr);
+ unref(t[i]);
+ t[i] = format_val(OFMT, OFMTidx, tval);
+ }
+ }
+ }
+
+ for (i = 0; i < numnodes; i++) {
+ efwrite(t[i]->stptr, sizeof(char), t[i]->stlen, fp, "print", rp, FALSE);
+ unref(t[i]);
+
+ if (i != numnodes - 1 && OFSlen > 0)
+ efwrite(OFS, sizeof(char), (size_t) OFSlen,
+ fp, "print", rp, FALSE);
+
+ }
+ if (ORSlen > 0)
+ efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
+
+ if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
+ fflush(rp->fp);
+
+ free(t);
+}
+
+/* do_print_rec --- special case printing of $0, for speed */
+
+void
+do_print_rec(register NODE *tree)
+{
+ struct redirect *rp = NULL;
+ register FILE *fp;
+ register NODE *f0;
+
+ fp = redirect_to_fp(tree->rnode, & rp);
+ if (fp == NULL)
+ return;
+
+ if (! field0_valid)
+ (void) get_field(0L, NULL); /* rebuild record */
+
+ f0 = fields_arr[0];
+
+ if (do_lint && f0 == Nnull_string)
+ lintwarn(_("reference to uninitialized field `$%d'"), 0);
+
+ efwrite(f0->stptr, sizeof(char), f0->stlen, fp, "print", rp, FALSE);
+
+ if (ORSlen > 0)
+ efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
+
+ if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
+ fflush(rp->fp);
+}
+
+#ifdef MBS_SUPPORT
+/* wide_tolower_toupper --- lower- or uppercase a multibute string */
+
+typedef int (*isw_func)(wint_t);
+typedef wint_t (*tow_func)(wint_t);
+
+static NODE *
+wide_tolower_toupper(NODE *t1, isw_func iswu, tow_func towl)
+{
+ register unsigned char *cp, *cpe;
+ register unsigned char *cp2;
+ size_t mbclen;
+ mbstate_t mbs, prev_mbs;
+ wchar_t wc;
+ NODE *t2;
+ /*
+ * Since the lowercase char and its uppercase equivalent may occupy
+ * different number of bytes (Turkish `i'), we cannot say the length
+ * of the output string.
+ * This approach is adapted from format_tree().
+ */
+ unsigned char *obuf;
+ size_t osiz, ofre;
+
+ /*
+ * Better 2 spare bytes than 1, consistently with make_str_node().
+ * And we need gawk_mb_cur_max free bytes before we convert the last
+ * char, so we add (gawk_mb_cur_max - 1).
+ */
+ osiz = t1->stlen + 2 + (gawk_mb_cur_max - 1);
+ ofre = osiz - 2;
+ emalloc(obuf, char *, osiz, "wide_tolower_toupper");
+
+ memset(&mbs, 0, sizeof(mbstate_t));
+ cp = (unsigned char *)t1->stptr;
+ cpe = (unsigned char *)(t1->stptr + t1->stlen);
+ cp2 = obuf;
+ while (cp < cpe) {
+ if (ofre < gawk_mb_cur_max) {
+ size_t olen = cp2 - obuf;
+ ofre += osiz;
+ osiz *= 2;
+ erealloc(obuf, char *, osiz, "wide_tolower_toupper");
+ cp2 = obuf + olen;
+ }
+ prev_mbs = mbs;
+ mbclen = (size_t) mbrtowc(&wc, (char *) cp, cpe - cp,
+ &mbs);
+ if (mbclen == 0 || mbclen == (size_t) -1 || mbclen == (size_t) -2) {
+ /* Null wide char, or a problem appeared. */
+ *cp2++ = *cp++;
+ ofre--;
+ continue;
+ }
+
+ /* If the character doesn't need change, copy it. */
+ if (!(*iswu)(wc)) {
+ ofre -= mbclen;
+ while (mbclen--)
+ *cp2++ = *cp++;
+ continue;
+ }
+
+ /* Increment the input pointer. */
+ cp += mbclen;
+
+ /* Write the modified wide character. */
+ mbclen = wcrtomb((char *) cp2, (*towl)(wc), &prev_mbs);
+
+ if (mbclen > 0 && mbclen < (size_t) -2) {
+ /* Increment the output pointer. */
+ cp2 += mbclen;
+ ofre -= mbclen;
+ } else {
+ /* A problem appeared. */
+ cp2++;
+ ofre--;
+ }
+ }
+ t2 = make_str_node(obuf, cp2 - obuf, ALREADY_MALLOCED);
+ t2->flags |= TEMP;
+ return t2;
+}
+#endif
+
+/* do_tolower --- lower case a string */
+
+NODE *
+do_tolower(NODE *tree)
+{
+ NODE *t1, *t2;
+
+ t1 = tree_eval(tree->lnode);
+ if (do_lint && (t1->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("tolower: received non-string argument"));
+ t1 = force_string(t1);
+
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1)
+ t2 = wide_tolower_toupper(t1, iswupper, towlower);
+ else
+#endif
+ {
+ register unsigned char *cp, *cpe;
+
+ t2 = tmp_string(t1->stptr, t1->stlen);
+ for (cp = (unsigned char *)t2->stptr,
+ cpe = (unsigned char *)(t2->stptr + t2->stlen); cp < cpe; cp++)
+ if (ISUPPER(*cp))
+ *cp = TOLOWER(*cp);
+ }
+ free_temp(t1);
+ return t2;
+}
+
+/* do_toupper --- upper case a string */
+
+NODE *
+do_toupper(NODE *tree)
+{
+ NODE *t1, *t2;
+
+ t1 = tree_eval(tree->lnode);
+ if (do_lint && (t1->flags & (STRING|STRCUR)) == 0)
+ lintwarn(_("toupper: received non-string argument"));
+ t1 = force_string(t1);
+
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1)
+ t2 = wide_tolower_toupper(t1, iswlower, towupper);
+ else
+#endif
+ {
+ register unsigned char *cp, *cpe;
+
+ t2 = tmp_string(t1->stptr, t1->stlen);
+ for (cp = (unsigned char *)t2->stptr,
+ cpe = (unsigned char *)(t2->stptr + t2->stlen); cp < cpe; cp++)
+ if (ISLOWER(*cp))
+ *cp = TOUPPER(*cp);
+ }
+ free_temp(t1);
+ return t2;
+}
+
+/* do_atan2 --- do the atan2 function */
+
+NODE *
+do_atan2(NODE *tree)
+{
+ NODE *t1, *t2;
+ double d1, d2;
+
+ t1 = tree_eval(tree->lnode);
+ t2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((t1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("atan2: received non-numeric first argument"));
+ if ((t2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("atan2: received non-numeric second argument"));
+ }
+ d1 = force_number(t1);
+ d2 = force_number(t2);
+ free_temp(t1);
+ free_temp(t2);
+ return tmp_number((AWKNUM) atan2(d1, d2));
+}
+
+/* do_sin --- do the sin function */
+
+NODE *
+do_sin(NODE *tree)
+{
+ NODE *tmp;
+ double d;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("sin: received non-numeric argument"));
+ d = sin((double) force_number(tmp));
+ free_temp(tmp);
+ return tmp_number((AWKNUM) d);
+}
+
+/* do_cos --- do the cos function */
+
+NODE *
+do_cos(NODE *tree)
+{
+ NODE *tmp;
+ double d;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("cos: received non-numeric argument"));
+ d = cos((double) force_number(tmp));
+ free_temp(tmp);
+ return tmp_number((AWKNUM) d);
+}
+
+/* do_rand --- do the rand function */
+
+static int firstrand = TRUE;
+static char state[256];
+
+/* ARGSUSED */
+NODE *
+do_rand(NODE *tree ATTRIBUTE_UNUSED)
+{
+ if (firstrand) {
+ (void) initstate((unsigned) 1, state, sizeof state);
+ /* don't need to srandom(1), initstate() does it for us. */
+ firstrand = FALSE;
+ setstate(state);
+ }
+ /*
+ * Per historical practice and POSIX, return value N is
+ *
+ * 0 <= n < 1
+ */
+ return tmp_number((AWKNUM) (random() % GAWK_RANDOM_MAX) / GAWK_RANDOM_MAX);
+}
+
+/* do_srand --- seed the random number generator */
+
+NODE *
+do_srand(NODE *tree)
+{
+ NODE *tmp;
+ static long save_seed = 1;
+ long ret = save_seed; /* SVR4 awk srand returns previous seed */
+
+ if (firstrand) {
+ (void) initstate((unsigned) 1, state, sizeof state);
+ /* don't need to srandom(1), we're changing the seed below */
+ firstrand = FALSE;
+ (void) setstate(state);
+ }
+
+ if (tree == NULL)
+ srandom((unsigned int) (save_seed = (long) time((time_t *) 0)));
+ else {
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("srand: received non-numeric argument"));
+ srandom((unsigned int) (save_seed = (long) force_number(tmp)));
+ free_temp(tmp);
+ }
+ return tmp_number((AWKNUM) ret);
+}
+
+/* do_match --- match a regexp, set RSTART and RLENGTH,
+ * optional third arg is array filled with text of
+ * subpatterns enclosed in parens and start and len info.
+ */
+
+NODE *
+do_match(NODE *tree)
+{
+ NODE *t1, *dest, *it;
+ int rstart, len, ii;
+ int rlength;
+ Regexp *rp;
+ regoff_t s;
+ char *start;
+ char *buf = NULL;
+ char buff[100];
+ size_t amt, oldamt = 0, ilen, slen;
+ char *subsepstr;
+ size_t subseplen;
+
+ t1 = force_string(tree_eval(tree->lnode));
+ tree = tree->rnode;
+ rp = re_update(tree->lnode);
+
+ dest = NULL;
+ if (tree->rnode != NULL) { /* 3rd optional arg for the subpatterns */
+ dest = get_param(tree->rnode->lnode);
+ if (dest->type != Node_var_array)
+ fatal(_("match: third argument is not an array"));
+
+ assoc_clear(dest);
+ }
+
+ rstart = research(rp, t1->stptr, 0, t1->stlen, RE_NEED_START);
+ if (rstart >= 0) { /* match succeded */
+ size_t *wc_indices = NULL;
+
+ rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr); /* byte length */
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ t1 = str2wstr(t1, & wc_indices);
+ rlength = wc_indices[rstart + rlength - 1] - wc_indices[rstart] + 1;
+ rstart = wc_indices[rstart];
+ }
+#endif
+ rstart++; /* now it's 1-based indexing */
+
+ /* Build the array only if the caller wants the optional subpatterns */
+ if (dest != NULL) {
+ subsepstr = SUBSEP_node->var_value->stptr;
+ subseplen = SUBSEP_node->var_value->stlen;
+
+ for (ii = 0; ii < NUMSUBPATS(rp, t1->stptr); ii++) {
+ /*
+ * Loop over all the subpats; some of them may have
+ * matched even if all of them did not.
+ */
+ if ((s = SUBPATSTART(rp, t1->stptr, ii)) != -1) {
+ size_t subpat_start;
+ size_t subpat_len;
+
+ start = t1->stptr + s;
+ subpat_start = s;
+ subpat_len = len = SUBPATEND(rp, t1->stptr, ii) - s;
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ subpat_start = wc_indices[s];
+ subpat_len = wc_indices[s + len - 1] - subpat_start + 1;
+ }
+#endif
+
+ it = make_string(start, len);
+ /*
+ * assoc_lookup() does free_temp() on 2nd arg.
+ */
+ *assoc_lookup(dest, tmp_number((AWKNUM) (ii)), FALSE) = it;
+
+ sprintf(buff, "%d", ii);
+ ilen = strlen(buff);
+ amt = ilen + subseplen + strlen("length") + 2;
+
+ if (oldamt == 0) {
+ emalloc(buf, char *, amt, "do_match");
+ } else if (amt > oldamt) {
+ erealloc(buf, char *, amt, "do_match");
+ }
+ oldamt = amt;
+ memcpy(buf, buff, ilen);
+ memcpy(buf + ilen, subsepstr, subseplen);
+ memcpy(buf + ilen + subseplen, "start", 6);
+
+ slen = ilen + subseplen + 5;
+
+ it = make_number((AWKNUM) subpat_start + 1);
+ *assoc_lookup(dest, tmp_string(buf, slen), FALSE) = it;
+
+ memcpy(buf, buff, ilen);
+ memcpy(buf + ilen, subsepstr, subseplen);
+ memcpy(buf + ilen + subseplen, "length", 7);
+
+ slen = ilen + subseplen + 6;
+
+ it = make_number((AWKNUM) subpat_len);
+ *assoc_lookup(dest, tmp_string(buf, slen), FALSE) = it;
+ }
+ }
+
+ free(buf);
+ if (wc_indices != NULL)
+ free(wc_indices);
+ }
+ } else { /* match failed */
+ rstart = 0;
+ rlength = -1;
+ }
+ free_temp(t1);
+ unref(RSTART_node->var_value);
+ RSTART_node->var_value = make_number((AWKNUM) rstart);
+ unref(RLENGTH_node->var_value);
+ RLENGTH_node->var_value = make_number((AWKNUM) rlength);
+ return tmp_number((AWKNUM) rstart);
+}
+
+/* sub_common --- the common code (does the work) for sub, gsub, and gensub */
+
+/*
+ * Gsub can be tricksy; particularly when handling the case of null strings.
+ * The following awk code was useful in debugging problems. It is too bad
+ * that it does not readily translate directly into the C code, below.
+ *
+ * #! /usr/local/bin/mawk -f
+ *
+ * BEGIN {
+ * TRUE = 1; FALSE = 0
+ * print "--->", mygsub("abc", "b+", "FOO")
+ * print "--->", mygsub("abc", "x*", "X")
+ * print "--->", mygsub("abc", "b*", "X")
+ * print "--->", mygsub("abc", "c", "X")
+ * print "--->", mygsub("abc", "c+", "X")
+ * print "--->", mygsub("abc", "x*$", "X")
+ * }
+ *
+ * function mygsub(str, regex, replace, origstr, newstr, eosflag, nonzeroflag)
+ * {
+ * origstr = str;
+ * eosflag = nonzeroflag = FALSE
+ * while (match(str, regex)) {
+ * if (RLENGTH > 0) { # easy case
+ * nonzeroflag = TRUE
+ * if (RSTART == 1) { # match at front of string
+ * newstr = newstr replace
+ * } else {
+ * newstr = newstr substr(str, 1, RSTART-1) replace
+ * }
+ * str = substr(str, RSTART+RLENGTH)
+ * } else if (nonzeroflag) {
+ * # last match was non-zero in length, and at the
+ * # current character, we get a zero length match,
+ * # which we don't really want, so skip over it
+ * newstr = newstr substr(str, 1, 1)
+ * str = substr(str, 2)
+ * nonzeroflag = FALSE
+ * } else {
+ * # 0-length match
+ * if (RSTART == 1) {
+ * newstr = newstr replace substr(str, 1, 1)
+ * str = substr(str, 2)
+ * } else {
+ * return newstr str replace
+ * }
+ * }
+ * if (length(str) == 0)
+ * if (eosflag)
+ * break
+ * else
+ * eosflag = TRUE
+ * }
+ * if (length(str) > 0)
+ * newstr = newstr str # rest of string
+ *
+ * return newstr
+ * }
+ */
+
+/*
+ * 1/2004: The gawk sub/gsub behavior dates from 1996, when we proposed it
+ * for POSIX. The proposal fell through the cracks, and the 2001 POSIX
+ * standard chose a more simple behavior.
+ *
+ * The relevant text is to be found on lines 6394-6407 (pages 166, 167) of the
+ * 2001 standard:
+ *
+ * sub(ere, repl[, in ])
+ * Substitute the string repl in place of the first instance of the extended regular
+ * expression ERE in string in and return the number of substitutions. An ampersand
+ * ('&') appearing in the string repl shall be replaced by the string from in that
+ * matches the ERE. An ampersand preceded with a backslash ('\') shall be
+ * interpreted as the literal ampersand character. An occurrence of two consecutive
+ * backslashes shall be interpreted as just a single literal backslash character. Any
+ * other occurrence of a backslash (for example, preceding any other character) shall
+ * be treated as a literal backslash character. Note that if repl is a string literal (the
+ * lexical token STRING; see Grammar (on page 170)), the handling of the
+ * ampersand character occurs after any lexical processing, including any lexical
+ * backslash escape sequence processing. If in is specified and it is not an lvalue (see
+ * Expressions in awk (on page 156)), the behavior is undefined. If in is omitted, awk
+ * shall use the current record ($0) in its place.
+ *
+ * Because gawk has had its behavior for 7+ years, that behavior is remaining as
+ * the default, with the POSIX behavior available for do_posix. Fun, fun, fun.
+ */
+
+/*
+ * NB: `howmany' conflicts with a SunOS 4.x macro in <sys/param.h>.
+ */
+
+static NODE *
+sub_common(NODE *tree, long how_many, int backdigs)
+{
+ register char *scan;
+ register char *bp, *cp;
+ char *buf;
+ size_t buflen;
+ register char *matchend;
+ register size_t len;
+ char *matchstart;
+ char *text;
+ size_t textlen;
+ char *repl;
+ char *replend;
+ size_t repllen;
+ int sofar;
+ int ampersands;
+ int matches = 0;
+ Regexp *rp;
+ NODE *s; /* subst. pattern */
+ NODE *t; /* string to make sub. in; $0 if none given */
+ NODE *tmp;
+ NODE **lhs = &tree; /* value not used -- just different from NULL */
+ int priv = FALSE;
+ Func_ptr after_assign = NULL;
+
+ int global = (how_many == -1);
+ long current;
+ int lastmatchnonzero;
+ char *mb_indices = NULL;
+
+ tmp = tree->lnode; /* regexp */
+ rp = re_update(tmp);
+
+ tree = tree->rnode; /* replacement text */
+ s = tree->lnode;
+ s = force_string(tree_eval(s));
+
+ tree = tree->rnode; /* original string */
+ tmp = tree->lnode;
+ t = force_string(tree_eval(tmp));
+
+ /* do the search early to avoid work on non-match */
+ if (research(rp, t->stptr, 0, t->stlen, RE_NEED_START) == -1 ||
+ RESTART(rp, t->stptr) > t->stlen) {
+ free_temp(t);
+ free_temp(s);
+ return tmp_number((AWKNUM) 0.0);
+ }
+
+ if (tmp->type == Node_val)
+ lhs = NULL;
+ else
+ lhs = get_lhs(tmp, &after_assign, FALSE);
+ t->flags |= STRING;
+ /*
+ * create a private copy of the string
+ */
+ if (t->stref > 1 || (t->flags & (PERM|FIELD)) != 0) {
+ tmp = copynode(t);
+ t = tmp;
+ priv = TRUE;
+ }
+ text = t->stptr;
+ textlen = t->stlen;
+ buflen = textlen + 2;
+
+ repl = s->stptr;
+ replend = repl + s->stlen;
+ repllen = replend - repl;
+ emalloc(buf, char *, buflen + 2, "sub_common");
+ buf[buflen] = '\0';
+ buf[buflen + 1] = '\0';
+ ampersands = 0;
+
+ /*
+ * Some systems' malloc() can't handle being called with an
+ * argument of zero. Thus we have to have some special case
+ * code to check for `repllen == 0'. This can occur for
+ * something like:
+ * sub(/foo/, "", mystring)
+ * for example.
+ */
+ if (gawk_mb_cur_max > 1 && repllen > 0) {
+ emalloc(mb_indices, char *, repllen * sizeof(char), "sub_common");
+ index_multibyte_buffer(repl, mb_indices, repllen);
+ }
+
+ for (scan = repl; scan < replend; scan++) {
+ if ((gawk_mb_cur_max == 1 || (repllen > 0 && mb_indices[scan - repl] == 1))
+ && (*scan == '&')) {
+ repllen--;
+ ampersands++;
+ } else if (*scan == '\\') {
+ if (backdigs) { /* gensub, behave sanely */
+ if (ISDIGIT(scan[1])) {
+ ampersands++;
+ scan++;
+ } else { /* \q for any q --> q */
+ repllen--;
+ scan++;
+ }
+ } else if (do_posix) {
+ /* \& --> &, \\ --> \ */
+ if (scan[1] == '&' || scan[1] == '\\') {
+ repllen--;
+ scan++;
+ } /* else
+ leave alone, it goes into the output */
+ } else {
+ /* gawk default behavior since 1996 */
+ if (strncmp(scan, "\\\\\\&", 4) == 0) {
+ /* \\\& --> \& */
+ repllen -= 2;
+ scan += 3;
+ } else if (strncmp(scan, "\\\\&", 3) == 0) {
+ /* \\& --> \<string> */
+ ampersands++;
+ repllen--;
+ scan += 2;
+ } else if (scan[1] == '&') {
+ /* \& --> & */
+ repllen--;
+ scan++;
+ } /* else
+ leave alone, it goes into the output */
+ }
+ }
+ }
+
+ lastmatchnonzero = FALSE;
+ bp = buf;
+ for (current = 1;; current++) {
+ matches++;
+ matchstart = t->stptr + RESTART(rp, t->stptr);
+ matchend = t->stptr + REEND(rp, t->stptr);
+
+ /*
+ * create the result, copying in parts of the original
+ * string
+ */
+ len = matchstart - text + repllen
+ + ampersands * (matchend - matchstart);
+ sofar = bp - buf;
+ while (buflen < (sofar + len + 1)) {
+ buflen *= 2;
+ erealloc(buf, char *, buflen, "sub_common");
+ bp = buf + sofar;
+ }
+ for (scan = text; scan < matchstart; scan++)
+ *bp++ = *scan;
+ if (global || current == how_many) {
+ /*
+ * If the current match matched the null string,
+ * and the last match didn't and did a replacement,
+ * and the match of the null string is at the front of
+ * the text (meaning right after end of the previous
+ * replacement), then skip this one.
+ */
+ if (matchstart == matchend
+ && lastmatchnonzero
+ && matchstart == text) {
+ lastmatchnonzero = FALSE;
+ matches--;
+ goto empty;
+ }
+ /*
+ * If replacing all occurrences, or this is the
+ * match we want, copy in the replacement text,
+ * making substitutions as we go.
+ */
+ for (scan = repl; scan < replend; scan++)
+ if (*scan == '&'
+ /*
+ * Don't test repllen here. A simple "&" could
+ * end up with repllen == 0.
+ */
+ && (gawk_mb_cur_max == 1
+ || mb_indices[scan - repl] == 1)
+ ) {
+ for (cp = matchstart; cp < matchend; cp++)
+ *bp++ = *cp;
+ } else if (*scan == '\\'
+ && (gawk_mb_cur_max == 1
+ || (repllen > 0 && mb_indices[scan - repl] == 1))
+ ) {
+ if (backdigs) { /* gensub, behave sanely */
+ if (ISDIGIT(scan[1])) {
+ int dig = scan[1] - '0';
+ char *start, *end;
+
+ start = t->stptr
+ + SUBPATSTART(rp, t->stptr, dig);
+ end = t->stptr
+ + SUBPATEND(rp, t->stptr, dig);
+
+ for (cp = start; cp < end; cp++)
+ *bp++ = *cp;
+ scan++;
+ } else /* \q for any q --> q */
+ *bp++ = *++scan;
+ } else if (do_posix) {
+ /* \& --> &, \\ --> \ */
+ if (scan[1] == '&' || scan[1] == '\\')
+ scan++;
+ *bp++ = *scan;
+ } else {
+ /* gawk default behavior since 1996 */
+ if (strncmp(scan, "\\\\\\&", 4) == 0) {
+ /* \\\& --> \& */
+ *bp++ = '\\';
+ *bp++ = '&';
+ scan += 3;
+ } else if (strncmp(scan, "\\\\&", 3) == 0) {
+ /* \\& --> \<string> */
+ *bp++ = '\\';
+ for (cp = matchstart; cp < matchend; cp++)
+ *bp++ = *cp;
+ scan += 2;
+ } else if (scan[1] == '&') {
+ /* \& --> & */
+ *bp++ = '&';
+ scan++;
+ } else
+ *bp++ = *scan;
+ }
+ } else
+ *bp++ = *scan;
+ if (matchstart != matchend)
+ lastmatchnonzero = TRUE;
+ } else {
+ /*
+ * don't want this match, skip over it by copying
+ * in current text.
+ */
+ for (cp = matchstart; cp < matchend; cp++)
+ *bp++ = *cp;
+ }
+ empty:
+ /* catch the case of gsub(//, "blah", whatever), i.e. empty regexp */
+ if (matchstart == matchend && matchend < text + textlen) {
+ *bp++ = *matchend;
+ matchend++;
+ }
+ textlen = text + textlen - matchend;
+ text = matchend;
+
+ if ((current >= how_many && !global)
+ || ((long) textlen <= 0 && matchstart == matchend)
+ || research(rp, t->stptr, text - t->stptr, textlen, RE_NEED_START) == -1)
+ break;
+
+ }
+ sofar = bp - buf;
+ if (buflen - sofar - textlen - 1) {
+ buflen = sofar + textlen + 2;
+ erealloc(buf, char *, buflen, "sub_common");
+ bp = buf + sofar;
+ }
+ for (scan = matchend; scan < text + textlen; scan++)
+ *bp++ = *scan;
+ *bp = '\0';
+ textlen = bp - buf;
+ free(t->stptr);
+ t->stptr = buf;
+ t->stlen = textlen;
+
+ free_temp(s);
+ if (matches > 0 && lhs) {
+ if (priv) {
+ unref(*lhs);
+ *lhs = t;
+ }
+ if (after_assign != NULL)
+ (*after_assign)();
+ t->flags &= ~(NUMCUR|NUMBER);
+ }
+ if (mb_indices != NULL)
+ free(mb_indices);
+
+ return tmp_number((AWKNUM) matches);
+}
+
+/* do_gsub --- global substitution */
+
+NODE *
+do_gsub(NODE *tree)
+{
+ return sub_common(tree, -1, FALSE);
+}
+
+/* do_sub --- single substitution */
+
+NODE *
+do_sub(NODE *tree)
+{
+ return sub_common(tree, 1, FALSE);
+}
+
+/* do_gensub --- fix up the tree for sub_common for the gensub function */
+
+NODE *
+do_gensub(NODE *tree)
+{
+ NODE n1, n2, n3, *t, *tmp, *target, *ret;
+ long how_many = 1; /* default is one substitution */
+ double d;
+
+ /*
+ * We have to pull out the value of the global flag, and
+ * build up a tree without the flag in it, turning it into the
+ * kind of tree that sub_common() expects. It helps to draw
+ * a picture of this ...
+ */
+ n1 = *tree;
+ n2 = *(tree->rnode);
+ n1.rnode = & n2;
+
+ t = tree_eval(n2.rnode->lnode); /* value of global flag */
+
+ tmp = force_string(tree_eval(n2.rnode->rnode->lnode)); /* target */
+
+ /*
+ * We make copy of the original target string, and pass that
+ * in to sub_common() as the target to make the substitution in.
+ * We will then return the result string as the return value of
+ * this function.
+ */
+ target = make_string(tmp->stptr, tmp->stlen);
+ free_temp(tmp);
+
+ n3 = *(n2.rnode->rnode);
+ n3.lnode = target;
+ n2.rnode = & n3;
+
+ if ((t->flags & (STRCUR|STRING)) != 0) {
+ if (t->stlen > 0 && (t->stptr[0] == 'g' || t->stptr[0] == 'G'))
+ how_many = -1;
+ else {
+ d = force_number(t);
+
+ if ((t->flags & NUMCUR) != 0)
+ goto set_how_many;
+
+ how_many = 1;
+ }
+ } else {
+ d = force_number(t);
+set_how_many:
+ if (d < 1)
+ how_many = 1;
+ else if (d < LONG_MAX)
+ how_many = d;
+ else
+ how_many = LONG_MAX;
+ if (d == 0)
+ warning(_("gensub: third argument of 0 treated as 1"));
+ }
+
+ free_temp(t);
+
+ ret = sub_common(&n1, how_many, TRUE);
+ free_temp(ret);
+
+ /*
+ * Note that we don't care what sub_common() returns, since the
+ * easiest thing for the programmer is to return the string, even
+ * if no substitutions were done.
+ */
+ target->flags |= TEMP;
+ return target;
+}
+
+#ifdef GFMT_WORKAROUND
+/*
+ * printf's %g format [can't rely on gcvt()]
+ * caveat: don't use as argument to *printf()!
+ * 'format' string HAS to be of "<flags>*.*g" kind, or we bomb!
+ */
+static void
+sgfmt(char *buf, /* return buffer; assumed big enough to hold result */
+ const char *format,
+ int alt, /* use alternate form flag */
+ int fwidth, /* field width in a format */
+ int prec, /* indicates desired significant digits, not decimal places */
+ double g) /* value to format */
+{
+ char dform[40];
+ register char *gpos;
+ register char *d, *e, *p;
+ int again = FALSE;
+
+ strncpy(dform, format, sizeof dform - 1);
+ dform[sizeof dform - 1] = '\0';
+ gpos = strrchr(dform, '.');
+
+ if (g == 0.0 && ! alt) { /* easy special case */
+ *gpos++ = 'd';
+ *gpos = '\0';
+ (void) sprintf(buf, dform, fwidth, 0);
+ return;
+ }
+
+ /* advance to location of 'g' in the format */
+ while (*gpos && *gpos != 'g' && *gpos != 'G')
+ gpos++;
+
+ if (prec <= 0) /* negative precision is ignored */
+ prec = (prec < 0 ? DEFAULT_G_PRECISION : 1);
+
+ if (*gpos == 'G')
+ again = TRUE;
+ /* start with 'e' format (it'll provide nice exponent) */
+ *gpos = 'e';
+ prec--;
+ (void) sprintf(buf, dform, fwidth, prec, g);
+ if ((e = strrchr(buf, 'e')) != NULL) { /* find exponent */
+ int expn = atoi(e+1); /* fetch exponent */
+ if (expn >= -4 && expn <= prec) { /* per K&R2, B1.2 */
+ /* switch to 'f' format and re-do */
+ *gpos = 'f';
+ prec -= expn; /* decimal precision */
+ (void) sprintf(buf, dform, fwidth, prec, g);
+ e = buf + strlen(buf);
+ while (*--e == ' ')
+ continue;
+ e++;
+ }
+ else if (again)
+ *gpos = 'E';
+
+ /* if 'alt' in force, then trailing zeros are not removed */
+ if (! alt && (d = strrchr(buf, '.')) != NULL) {
+ /* throw away an excess of precision */
+ for (p = e; p > d && *--p == '0'; )
+ prec--;
+ if (d == p)
+ prec--;
+ if (prec < 0)
+ prec = 0;
+ /* and do that once again */
+ again = TRUE;
+ }
+ if (again)
+ (void) sprintf(buf, dform, fwidth, prec, g);
+ }
+}
+#endif /* GFMT_WORKAROUND */
+
+/*
+ * The number of base-FLT_RADIX digits in an AWKNUM fraction, assuming
+ * that AWKNUM is not long double.
+ */
+#define AWKSMALL_MANT_DIG \
+ (sizeof (AWKNUM) == sizeof (double) ? DBL_MANT_DIG : FLT_MANT_DIG)
+
+/*
+ * The number of base-FLT_DIGIT digits in an AWKNUM fraction, even if
+ * AWKNUM is long double. Don't mention 'long double' unless
+ * LDBL_MANT_DIG is defined, for the sake of ancient compilers that
+ * lack 'long double'.
+ */
+#ifdef LDBL_MANT_DIG
+#define AWKNUM_MANT_DIG \
+ (sizeof (AWKNUM) == sizeof (long double) ? LDBL_MANT_DIG : AWKSMALL_MANT_DIG)
+#else
+#define AWKNUM_MANT_DIG AWKSMALL_MANT_DIG
+#endif
+
+/*
+ * The number of bits in an AWKNUM fraction, assuming FLT_RADIX is
+ * either 2 or 16. IEEE and VAX formats use radix 2, and IBM
+ * mainframe format uses radix 16; we know of no other radices in
+ * practical use.
+ */
+#if FLT_RADIX != 2 && FLT_RADIX != 16
+Please port the following code to your weird host;
+#endif
+#define AWKNUM_FRACTION_BITS (AWKNUM_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
+
+/* tmp_integer - Convert an integer to a temporary number node. */
+
+static NODE *
+tmp_integer(uintmax_t n)
+{
+#ifdef HAVE_UINTMAX_T
+/* #ifndef LDBL_MANT_DIG */
+ /*
+ * If uintmax_t is so wide that AWKNUM cannot represent all its
+ * values, strip leading nonzero bits of integers that are so large
+ * that they cannot be represented exactly as AWKNUMs, so that their
+ * low order bits are represented exactly, without rounding errors.
+ * This is more desirable in practice, since it means the user sees
+ * integers that are the same width as the AWKNUM fractions.
+ */
+ if (AWKNUM_FRACTION_BITS < CHAR_BIT * sizeof n)
+ n &= ((uintmax_t) 1 << AWKNUM_FRACTION_BITS) - 1;
+/* #endif */ /* LDBL_MANT_DIG */
+#endif /* HAVE_UINTMAX_T */
+
+ return tmp_number((AWKNUM) n);
+}
+
+/* do_lshift --- perform a << operation */
+
+NODE *
+do_lshift(NODE *tree)
+{
+ NODE *s1, *s2;
+ uintmax_t uval, ushift, res;
+ AWKNUM val, shift;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("lshift: received non-numeric first argument"));
+ if ((s2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("lshift: received non-numeric second argument"));
+ }
+ val = force_number(s1);
+ shift = force_number(s2);
+ if (do_lint) {
+ if (val < 0 || shift < 0)
+ lintwarn(_("lshift(%lf, %lf): negative values will give strange results"), val, shift);
+ if (double_to_int(val) != val || double_to_int(shift) != shift)
+ lintwarn(_("lshift(%lf, %lf): fractional values will be truncated"), val, shift);
+ if (shift >= sizeof(uintmax_t) * CHAR_BIT)
+ lintwarn(_("lshift(%lf, %lf): too large shift value will give strange results"), val, shift);
+ }
+
+ free_temp(s1);
+ free_temp(s2);
+
+ uval = (uintmax_t) val;
+ ushift = (uintmax_t) shift;
+
+ res = uval << ushift;
+ return tmp_integer(res);
+}
+
+/* do_rshift --- perform a >> operation */
+
+NODE *
+do_rshift(NODE *tree)
+{
+ NODE *s1, *s2;
+ uintmax_t uval, ushift, res;
+ AWKNUM val, shift;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("rshift: received non-numeric first argument"));
+ if ((s2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("rshift: received non-numeric second argument"));
+ }
+ val = force_number(s1);
+ shift = force_number(s2);
+ if (do_lint) {
+ if (val < 0 || shift < 0)
+ lintwarn(_("rshift(%lf, %lf): negative values will give strange results"), val, shift);
+ if (double_to_int(val) != val || double_to_int(shift) != shift)
+ lintwarn(_("rshift(%lf, %lf): fractional values will be truncated"), val, shift);
+ if (shift >= sizeof(uintmax_t) * CHAR_BIT)
+ lintwarn(_("rshift(%lf, %lf): too large shift value will give strange results"), val, shift);
+ }
+
+ free_temp(s1);
+ free_temp(s2);
+
+ uval = (uintmax_t) val;
+ ushift = (uintmax_t) shift;
+
+ res = uval >> ushift;
+ return tmp_integer(res);
+}
+
+/* do_and --- perform an & operation */
+
+NODE *
+do_and(NODE *tree)
+{
+ NODE *s1, *s2;
+ uintmax_t uleft, uright, res;
+ AWKNUM left, right;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("and: received non-numeric first argument"));
+ if ((s2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("and: received non-numeric second argument"));
+ }
+ left = force_number(s1);
+ right = force_number(s2);
+ if (do_lint) {
+ if (left < 0 || right < 0)
+ lintwarn(_("and(%lf, %lf): negative values will give strange results"), left, right);
+ if (double_to_int(left) != left || double_to_int(right) != right)
+ lintwarn(_("and(%lf, %lf): fractional values will be truncated"), left, right);
+ }
+
+ free_temp(s1);
+ free_temp(s2);
+
+ uleft = (uintmax_t) left;
+ uright = (uintmax_t) right;
+
+ res = uleft & uright;
+ return tmp_integer(res);
+}
+
+/* do_or --- perform an | operation */
+
+NODE *
+do_or(NODE *tree)
+{
+ NODE *s1, *s2;
+ uintmax_t uleft, uright, res;
+ AWKNUM left, right;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("or: received non-numeric first argument"));
+ if ((s2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("or: received non-numeric second argument"));
+ }
+ left = force_number(s1);
+ right = force_number(s2);
+ if (do_lint) {
+ if (left < 0 || right < 0)
+ lintwarn(_("or(%lf, %lf): negative values will give strange results"), left, right);
+ if (double_to_int(left) != left || double_to_int(right) != right)
+ lintwarn(_("or(%lf, %lf): fractional values will be truncated"), left, right);
+ }
+
+ free_temp(s1);
+ free_temp(s2);
+
+ uleft = (uintmax_t) left;
+ uright = (uintmax_t) right;
+
+ res = uleft | uright;
+ return tmp_integer(res);
+}
+
+/* do_xor --- perform an ^ operation */
+
+NODE *
+do_xor(NODE *tree)
+{
+ NODE *s1, *s2;
+ uintmax_t uleft, uright, res;
+ AWKNUM left, right;
+
+ s1 = tree_eval(tree->lnode);
+ s2 = tree_eval(tree->rnode->lnode);
+ if (do_lint) {
+ if ((s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("xor: received non-numeric first argument"));
+ if ((s2->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("xor: received non-numeric second argument"));
+ }
+ left = force_number(s1);
+ right = force_number(s2);
+ if (do_lint) {
+ if (left < 0 || right < 0)
+ lintwarn(_("xor(%lf, %lf): negative values will give strange results"), left, right);
+ if (double_to_int(left) != left || double_to_int(right) != right)
+ lintwarn(_("xor(%lf, %lf): fractional values will be truncated"), left, right);
+ }
+
+ free_temp(s1);
+ free_temp(s2);
+
+ uleft = (uintmax_t) left;
+ uright = (uintmax_t) right;
+
+ res = uleft ^ uright;
+ return tmp_integer(res);
+}
+
+/* do_compl --- perform a ~ operation */
+
+NODE *
+do_compl(NODE *tree)
+{
+ NODE *tmp;
+ double d;
+ uintmax_t uval;
+
+ tmp = tree_eval(tree->lnode);
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("compl: received non-numeric argument"));
+ d = force_number(tmp);
+ free_temp(tmp);
+
+ if (do_lint) {
+ if (d < 0)
+ lintwarn(_("compl(%lf): negative value will give strange results"), d);
+ if (double_to_int(d) != d)
+ lintwarn(_("compl(%lf): fractional value will be truncated"), d);
+ }
+
+ uval = (uintmax_t) d;
+ uval = ~ uval;
+ return tmp_integer(uval);
+}
+
+/* do_strtonum --- the strtonum function */
+
+NODE *
+do_strtonum(NODE *tree)
+{
+ NODE *tmp;
+ AWKNUM d;
+
+ tmp = tree_eval(tree->lnode);
+
+ if ((tmp->flags & (NUMBER|NUMCUR)) != 0)
+ d = (AWKNUM) force_number(tmp);
+ else if (isnondecimal(tmp->stptr, TRUE))
+ d = nondec2awknum(tmp->stptr, tmp->stlen);
+ else
+ d = (AWKNUM) force_number(tmp);
+
+ free_temp(tmp);
+ return tmp_number((AWKNUM) d);
+}
+
+/* nondec2awknum --- convert octal or hex value to double */
+
+/*
+ * Because of awk's concatenation rules and the way awk.y:yylex()
+ * collects a number, this routine has to be willing to stop on the
+ * first invalid character.
+ */
+
+AWKNUM
+nondec2awknum(char *str, size_t len)
+{
+ AWKNUM retval = 0.0;
+ char save;
+ short val;
+ char *start = str;
+
+ if (*str == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ /*
+ * User called strtonum("0x") or some such,
+ * so just quit early.
+ */
+ if (len <= 2)
+ return (AWKNUM) 0.0;
+
+ for (str += 2, len -= 2; len > 0; len--, str++) {
+ switch (*str) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ val = *str - '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ val = *str - 'a' + 10;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ val = *str - 'A' + 10;
+ break;
+ default:
+ goto done;
+ }
+ retval = (retval * 16) + val;
+ }
+ } else if (*str == '0') {
+ for (; len > 0; len--) {
+ if (! ISDIGIT(*str))
+ goto done;
+ else if (*str == '8' || *str == '9') {
+ str = start;
+ goto decimal;
+ }
+ retval = (retval * 8) + (*str - '0');
+ str++;
+ }
+ } else {
+decimal:
+ save = str[len];
+ retval = strtod(str, NULL);
+ str[len] = save;
+ }
+done:
+ return retval;
+}
+
+/* do_dcgettext, do_dcngettext --- handle i18n translations */
+
+#if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
+
+static int
+localecategory_from_argument(NODE *tree)
+{
+ static const struct category_table {
+ int val;
+ const char *name;
+ } cat_tab[] = {
+#ifdef LC_ALL
+ { LC_ALL, "LC_ALL" },
+#endif /* LC_ALL */
+#ifdef LC_COLLATE
+ { LC_COLLATE, "LC_COLLATE" },
+#endif /* LC_COLLATE */
+#ifdef LC_CTYPE
+ { LC_CTYPE, "LC_CTYPE" },
+#endif /* LC_CTYPE */
+#ifdef LC_MESSAGES
+ { LC_MESSAGES, "LC_MESSAGES" },
+#endif /* LC_MESSAGES */
+#ifdef LC_MONETARY
+ { LC_MONETARY, "LC_MONETARY" },
+#endif /* LC_MONETARY */
+#ifdef LC_NUMERIC
+ { LC_NUMERIC, "LC_NUMERIC" },
+#endif /* LC_NUMERIC */
+#ifdef LC_RESPONSE
+ { LC_RESPONSE, "LC_RESPONSE" },
+#endif /* LC_RESPONSE */
+#ifdef LC_TIME
+ { LC_TIME, "LC_TIME" },
+#endif /* LC_TIME */
+ };
+
+ if (tree != NULL) {
+ int low, high, i, mid;
+ NODE *tmp, *t;
+ char *category;
+ int lc_cat = -1;
+
+ tmp = tree->lnode;
+ t = force_string(tree_eval(tmp));
+ category = t->stptr;
+
+ /* binary search the table */
+ low = 0;
+ high = (sizeof(cat_tab) / sizeof(cat_tab[0])) - 1;
+ while (low <= high) {
+ mid = (low + high) / 2;
+ i = strcmp(category, cat_tab[mid].name);
+
+ if (i < 0) /* category < mid */
+ high = mid - 1;
+ else if (i > 0) /* category > mid */
+ low = mid + 1;
+ else {
+ lc_cat = cat_tab[mid].val;
+ break;
+ }
+ }
+ if (lc_cat == -1) /* not there */
+ fatal(_("dcgettext: `%s' is not a valid locale category"), category);
+
+ free_temp(t);
+ return lc_cat;
+ } else
+ return LC_MESSAGES;
+}
+
+#endif
+
+/*
+ * awk usage is
+ *
+ * str = dcgettext(string [, domain [, category]])
+ * str = dcngettext(string1, string2, number [, domain [, category]])
+ *
+ * Default domain is TEXTDOMAIN, default category is LC_MESSAGES.
+ */
+
+NODE *
+do_dcgettext(NODE *tree)
+{
+ NODE *tmp, *t1, *t2;
+ char *string;
+ char *the_result;
+#if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
+ int lc_cat;
+ char *domain;
+#endif /* ENABLE_NLS */
+
+ tmp = tree->lnode; /* first argument */
+ t1 = force_string(tree_eval(tmp));
+ string = t1->stptr;
+
+ t2 = NULL;
+#if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
+ tree = tree->rnode; /* second argument */
+ if (tree != NULL) {
+ tmp = tree->lnode;
+ t2 = force_string(tree_eval(tmp));
+ domain = t2->stptr;
+ } else
+ domain = TEXTDOMAIN;
+
+ if (tree && tree->rnode != NULL) { /* third argument */
+ lc_cat = localecategory_from_argument(tree->rnode);
+ } else
+ lc_cat = LC_MESSAGES;
+
+ the_result = dcgettext(domain, string, lc_cat);
+#else
+ the_result = string;
+#endif
+ free_temp(t1);
+ if (t2 != NULL)
+ free_temp(t2);
+
+ return tmp_string(the_result, strlen(the_result));
+}
+
+NODE *
+do_dcngettext(NODE *tree)
+{
+ NODE *tmp, *t1, *t2, *t3;
+ char *string1, *string2;
+ unsigned long number;
+ char *the_result;
+#if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
+ int lc_cat;
+ char *domain;
+#endif /* ENABLE_NLS */
+
+ tmp = tree->lnode; /* first argument */
+ t1 = force_string(tree_eval(tmp));
+ string1 = t1->stptr;
+
+ tmp = tree->rnode->lnode; /* second argument */
+ t2 = force_string(tree_eval(tmp));
+ string2 = t2->stptr;
+
+ tmp = tree->rnode->rnode->lnode; /* third argument */
+ number = (unsigned long) double_to_int(force_number(tree_eval(tmp)));
+
+ t3 = NULL;
+#if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
+ tree = tree->rnode->rnode->rnode; /* fourth argument */
+ if (tree != NULL) {
+ tmp = tree->lnode;
+ t3 = force_string(tree_eval(tmp));
+ domain = t3->stptr;
+ } else
+ domain = TEXTDOMAIN;
+
+ if (tree && tree->rnode != NULL) { /* fifth argument */
+ lc_cat = localecategory_from_argument(tree->rnode);
+ } else
+ lc_cat = LC_MESSAGES;
+
+ the_result = dcngettext(domain, string1, string2, number, lc_cat);
+#else
+ the_result = (number == 1 ? string1 : string2);
+#endif
+ free_temp(t1);
+ free_temp(t2);
+ if (t3 != NULL)
+ free_temp(t3);
+
+ return tmp_string(the_result, strlen(the_result));
+}
+
+/* do_bindtextdomain --- set the directory for a text domain */
+
+/*
+ * awk usage is
+ *
+ * binding = bindtextdomain(dir [, domain])
+ *
+ * If dir is "", pass NULL to C version.
+ * Default domain is TEXTDOMAIN.
+ */
+
+NODE *
+do_bindtextdomain(NODE *tree)
+{
+ NODE *tmp, *t1, *t2;
+ char *directory, *domain;
+ char *the_result;
+
+ t1 = t2 = NULL;
+ /* set defaults */
+ directory = NULL;
+ domain = TEXTDOMAIN;
+
+ tmp = tree->lnode; /* first argument */
+ t1 = force_string(tree_eval(tmp));
+ if (t1->stlen > 0)
+ directory = t1->stptr;
+
+ tree = tree->rnode; /* second argument */
+ if (tree != NULL) {
+ tmp = tree->lnode;
+ t2 = force_string(tree_eval(tmp));
+ domain = t2->stptr;
+ }
+
+ the_result = bindtextdomain(domain, directory);
+
+ free_temp(t1);
+ if (t2 != NULL)
+ free_temp(t2);
+
+ return tmp_string(the_result, strlen(the_result));
+}
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-02-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amd64:OpenBSD:*:*)
+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ cats:OpenBSD:*:*)
+ echo arm-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ luna88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit 0 ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && exit 0
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ # avoid double evaluation of $set_cc_for_build
+ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit 0 ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ amd64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit 0 ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit 0 ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit 0 ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ *86) UNAME_PROCESSOR=i686 ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit 0 ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms && exit 0 ;;
+ I*) echo ia64-dec-vms && exit 0 ;;
+ V*) echo vax-dec-vms && exit 0 ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2005 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+cc_basename=`echo "$CC" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case "$cc_basename" in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | pw32* | os2*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux*)
+ case $cc_basename in
+ icc* | ecc*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ sco3.2v5*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ case "$host_os" in
+ aix3* | aix4* | aix5*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = yes; then
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case "$cc_basename" in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | kfreebsd*-gnu | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10* | hpux11*)
+ if test "$with_gnu_ld" = no; then
+ case "$host_cpu" in
+ hppa*64*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=no
+ ;;
+ ia64*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ sco3.2v5*)
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4.2uw2*)
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ ;;
+ sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
+ ;;
+ sysv5*)
+ hardcode_libdir_flag_spec=
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ ;;
+ aix4* | aix5*)
+ ;;
+ amigaos*)
+ ;;
+ beos*)
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32*)
+ shrext=.dll
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ ;;
+ dgux*)
+ ;;
+ freebsd1*)
+ ;;
+ kfreebsd*-gnu)
+ ;;
+ freebsd*)
+ ;;
+ gnu*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case "$host_cpu" in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux*)
+ ;;
+ knetbsd*-gnu)
+ ;;
+ netbsd*)
+ ;;
+ newsos6)
+ ;;
+ nto-qnx*)
+ ;;
+ openbsd*)
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ ;;
+ osf3* | osf4* | osf5*)
+ ;;
+ sco3.2v5*)
+ ;;
+ solaris*)
+ ;;
+ sunos4*)
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ ;;
+ sysv4*MP*)
+ ;;
+ uts4*)
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-02-10'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | msp430 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | msp430-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+/* configh.in. Generated from configure.ac by autoheader. */
+
+/* switch statements are enabled in awk programs */
+#undef ALLOW_SWITCH
+
+/* dynamic loading is possible */
+#undef DYNAMIC
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
+
+/* Define to the type of elements in the array set by `getgroups'. Usually
+ this is either `int' or `gid_t'. */
+#undef GETGROUPS_T
+
+/* Define to 1 if the `getpgrp' function requires zero arguments. */
+#undef GETPGRP_VOID
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have the `btowc' function. */
+#undef HAVE_BTOWC
+
+/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
+ CoreFoundation framework. */
+#undef HAVE_CFLOCALECOPYCURRENT
+
+/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
+ the CoreFoundation framework. */
+#undef HAVE_CFPREFERENCESCOPYAPPVALUE
+
+/* Define if the GNU dcgettext() function is already present or preinstalled.
+ */
+#undef HAVE_DCGETTEXT
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fmod' function. */
+#undef HAVE_FMOD
+
+/* Define to 1 if you have the `getgrent' function. */
+#undef HAVE_GETGRENT
+
+/* Define to 1 if you have the `getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
+/* Define to 1 if you have the `grantpt' function. */
+#undef HAVE_GRANTPT
+
+/* Define if you have the iconv() function. */
+#undef HAVE_ICONV
+
+/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+#undef HAVE_INTMAX_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
+ declares uintmax_t. */
+#undef HAVE_INTTYPES_H_WITH_UINTMAX
+
+/* Define to 1 if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define to 1 if you have the `iswctype' function. */
+#undef HAVE_ISWCTYPE
+
+/* Define to 1 if you have the `iswlower' function. */
+#undef HAVE_ISWLOWER
+
+/* Define to 1 if you have the `iswupper' function. */
+#undef HAVE_ISWUPPER
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the 'long long' type. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the `mbrlen' function. */
+#undef HAVE_MBRLEN
+
+/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
+#undef HAVE_MBRTOWC
+
+/* Define to 1 if you have the <mcheck.h> header file. */
+#undef HAVE_MCHECK_H
+
+/* Define to 1 if you have the `memcmp' function. */
+#undef HAVE_MEMCMP
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* we have the mktime function */
+#undef HAVE_MKTIME
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* we have portals on /p on this system */
+#undef HAVE_PORTALS
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the <signum.h> header file. */
+#undef HAVE_SIGNUM_H
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* we have sockets on this system */
+#undef HAVE_SOCKETS
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
+ uintmax_t. */
+#undef HAVE_STDINT_H_WITH_UINTMAX
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if cpp supports the ANSI # stringizing operator. */
+#undef HAVE_STRINGIZE
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if you have the `strtod' function. */
+#undef HAVE_STRTOD
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if `tm_zone' is member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
+ `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
+#undef HAVE_ST_BLKSIZE
+
+/* Define to 1 if you have the `system' function. */
+#undef HAVE_SYSTEM
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+ `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the `towlower' function. */
+#undef HAVE_TOWLOWER
+
+/* Define to 1 if you have the `towupper' function. */
+#undef HAVE_TOWUPPER
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+ `tzname'. */
+#undef HAVE_TZNAME
+
+/* Define to 1 if you have the `tzset' function. */
+#undef HAVE_TZSET
+
+/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
+#undef HAVE_UINTMAX_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the 'unsigned long long' type. */
+#undef HAVE_UNSIGNED_LONG_LONG
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#undef HAVE_WCRTOMB
+
+/* Define to 1 if you have the `wcscoll' function. */
+#undef HAVE_WCSCOLL
+
+/* Define to 1 if you have the `wctype' function. */
+#undef HAVE_WCTYPE
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#undef HAVE_WCTYPE_H
+
+/* systems should define this type here */
+#undef HAVE_WCTYPE_T
+
+/* systems should define this type here */
+#undef HAVE_WINT_T
+
+/* disable lint checks */
+#undef NO_LINT
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if *printf supports %F format */
+#undef PRINTF_HAS_F_FORMAT
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#undef PROTOTYPES
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* The size of a `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of a `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* return type of sprintf */
+#undef SPRINTF_RET
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* strtod doesn't have C89 semantics */
+#undef STRTOD_NOT_C89
+
+/* some systems define this type here */
+#undef TIME_T_IN_SYS_TYPES_H
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* force use of our version of strftime */
+#undef USE_INCLUDED_STRFTIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#undef __PROTOTYPES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
+#undef intmax_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
+ supported. Do not define if restrict is supported directly. */
+#undef restrict
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* type to use in place of socklen_t if not defined */
+#undef socklen_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to unsigned long or unsigned long long if <stdint.h> and
+ <inttypes.h> don't define. */
+#undef uintmax_t
+
+#include "custom.h"
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for GNU Awk 3.1.5.
+#
+# Report bugs to <bug-gawk@gnu.org>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='GNU Awk'
+PACKAGE_TARNAME='gawk'
+PACKAGE_VERSION='3.1.5'
+PACKAGE_STRING='GNU Awk 3.1.5'
+PACKAGE_BUGREPORT='bug-gawk@gnu.org'
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar EGREP YACC LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP RANLIB ac_ct_RANLIB U ANSI2KNR MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE build build_cpu build_vendor build_os host host_cpu host_vendor host_os INTL_MACOSX_LIBS LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS SOCKET_LIBS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures GNU Awk 3.1.5 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of GNU Awk 3.1.5:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-portals Enable /p as path prefix for portals
+ --disable-lint Disable gawk lint checking
+ --enable-switch Enable switch statements for awk programs
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --disable-largefile omit support for large files
+ --disable-nls do not use Native Language Support
+ --disable-rpath do not hardcode runtime library paths
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-whiny-user-strftime Force use of included version of strftime for deficient systems
+ --with-gnu-ld assume the C compiler uses GNU ld default=no
+ --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib
+ --without-libiconv-prefix don't search for libiconv in includedir and libdir
+ --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib
+ --without-libintl-prefix don't search for libintl in includedir and libdir
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <bug-gawk@gnu.org>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+GNU Awk configure 3.1.5
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GNU Awk $as_me 3.1.5, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# This is a hack. Different versions of install on different systems
+# are just too different. Chuck it and use install-sh.
+#
+# If the user supplies $INSTALL, figure they know what they're doing.
+#
+# With Autoconf 2.5x, this needs to come very early on, but *after*
+# the INIT macro. Sigh.
+
+if test "x$INSTALL" = "x"
+then
+ INSTALL="$srcdir/install-sh -c"
+ export INSTALL
+fi
+
+
+am__api_version="1.9"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='gawk'
+ VERSION='3.1.5'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Check whether --enable-portals or --disable-portals was given.
+if test "${enable_portals+set}" = set; then
+ enableval="$enable_portals"
+ if test "$enableval" = yes
+ then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PORTALS 1
+_ACEOF
+
+ fi
+
+fi;
+
+# Check whether --with-whiny-user-strftime or --without-whiny-user-strftime was given.
+if test "${with_whiny_user_strftime+set}" = set; then
+ withval="$with_whiny_user_strftime"
+ if test "$withval" = yes
+ then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_INCLUDED_STRFTIME 1
+_ACEOF
+
+ fi
+
+fi;
+# Check whether --enable-lint or --disable-lint was given.
+if test "${enable_lint+set}" = set; then
+ enableval="$enable_lint"
+ if test "$enableval" = no
+ then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LINT 1
+_ACEOF
+
+ fi
+
+fi;
+# Check whether --enable-switch or --disable-switch was given.
+if test "${enable_switch+set}" = set; then
+ enableval="$enable_switch"
+ if test "$enableval" = yes
+ then
+
+cat >>confdefs.h <<\_ACEOF
+#define ALLOW_SWITCH 1
+_ACEOF
+
+ fi
+
+fi;
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+# This is mainly for my use during testing and development.
+# Yes, it's a bit of a hack.
+echo "$as_me:$LINENO: checking for special development options" >&5
+echo $ECHO_N "checking for special development options... $ECHO_C" >&6
+if test -f $srcdir/.developing
+then
+ # add other debug flags as appropriate, save GAWKDEBUG for emergencies
+ CFLAGS="$CFLAGS -DARRAYDEBUG"
+ if grep dbug $srcdir/.developing
+ then
+ CFLAGS="$CFLAGS -DDBUG"
+ LIBS="$LIBS dbug/libdbug.a"
+ fi
+ # turn on compiler warnings if we're doing development
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -Wall"
+ fi
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for AIX" >&5
+echo $ECHO_N "checking for AIX... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef _AIX
+ yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+cat >>confdefs.h <<\_ACEOF
+#define _ALL_SOURCE 1
+_ACEOF
+
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest*
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+ for ac_lib in cposix; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+ test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval="$enable_largefile"
+
+fi;
+if test "$enable_largefile" != no; then
+
+ echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_largefile_CC=' -n32'; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ ac_cv_sys_file_offset_bits=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_file_offset_bits=64; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+
+fi
+rm -f conftest*
+ echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ ac_cv_sys_large_files=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_large_files=1; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+
+fi
+rm -f conftest*
+fi
+
+
+echo "$as_me:$LINENO: checking for AIX compilation hacks" >&5
+echo $ECHO_N "checking for AIX compilation hacks... $ECHO_C" >&6
+if test "${gawk_cv_aix_hack+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+if test -d /lpp
+then
+ CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=1 -DGAWK_AIX=1"
+ gawk_cv_aix_hack=yes
+else
+ gawk_cv_aix_hack=no
+fi
+
+fi
+echo "$as_me:$LINENO: result: ${gawk_cv_aix_hack}" >&5
+echo "${ECHO_T}${gawk_cv_aix_hack}" >&6
+
+
+echo "$as_me:$LINENO: checking for Linux/Alpha compilation hacks" >&5
+echo $ECHO_N "checking for Linux/Alpha compilation hacks... $ECHO_C" >&6
+if test "${gawk_cv_linux_alpha_hack+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+if test "Linux" = "`uname`" && test "alpha" = "`uname -m`"
+then
+ # this isn't necessarily always true,
+ # the vendor's compiler is also often found
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -mieee"
+ gawk_cv_linux_alpha_hack=yes
+ else
+ gawk_cv_linux_alpha_hack=no
+ fi
+else
+ gawk_cv_linux_alpha_hack=no
+fi
+
+fi
+echo "$as_me:$LINENO: result: ${gawk_cv_linux_alpha_hack}" >&5
+echo "${ECHO_T}${gawk_cv_linux_alpha_hack}" >&6
+
+
+if test "$ISC" = 1 # will be set by test for ISC
+then
+ CFLAGS="$CFLAGS -D_SYSV3"
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
+
+echo "$as_me:$LINENO: checking for function prototypes" >&5
+echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6
+if test "$ac_cv_prog_cc_stdc" != no; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define PROTOTYPES 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define __PROTOTYPES 1
+_ACEOF
+
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+if test "$ac_cv_prog_cc_stdc" != no; then
+ U= ANSI2KNR=
+else
+ U=_ ANSI2KNR=./ansi2knr
+fi
+# Ensure some checks needed by ansi2knr itself.
+
+
+for ac_header in string.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+case `(uname) 2> /dev/null` in
+*CYGWIN*)
+ with_libiconv_prefix=no
+ with_libintl_prefix=no
+ ;;
+*)
+ ;;
+esac
+
+
+
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ case "$ac_aux_dir" in
+ /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;;
+ *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;;
+ esac
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+
+
+
+ echo "$as_me:$LINENO: checking whether NLS is requested" >&5
+echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi;
+ echo "$as_me:$LINENO: result: $USE_NLS" >&5
+echo "${ECHO_T}$USE_NLS" >&6
+
+
+
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$MSGFMT" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&5
+ if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 &&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test "$MSGFMT" != ":"; then
+ echo "$as_me:$LINENO: result: $MSGFMT" >&5
+echo "${ECHO_T}$MSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GMSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+
+if test -n "$GMSGFMT"; then
+ echo "$as_me:$LINENO: result: $GMSGFMT" >&5
+echo "${ECHO_T}$GMSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_XGETTEXT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$XGETTEXT" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&5
+ if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test "$XGETTEXT" != ":"; then
+ echo "$as_me:$LINENO: result: $XGETTEXT" >&5
+echo "${ECHO_T}$XGETTEXT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ rm -f messages.po
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MSGMERGE+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$MSGMERGE" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&5
+ if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then
+ ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":"
+ ;;
+esac
+fi
+MSGMERGE="$ac_cv_path_MSGMERGE"
+if test "$MSGMERGE" != ":"; then
+ echo "$as_me:$LINENO: result: $MSGMERGE" >&5
+echo "${ECHO_T}$MSGMERGE" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+ if test "$GMSGFMT" != ":"; then
+ if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 &&
+ (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'`
+ echo "$as_me:$LINENO: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5
+echo "${ECHO_T}found $GMSGFMT program is not GNU msgfmt; ignore it" >&6
+ GMSGFMT=":"
+ fi
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
+ (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ echo "$as_me:$LINENO: result: found xgettext program is not GNU xgettext; ignore it" >&5
+echo "${ECHO_T}found xgettext program is not GNU xgettext; ignore it" >&6
+ XGETTEXT=":"
+ fi
+ rm -f messages.po
+ fi
+
+ ac_config_commands="$ac_config_commands default-1"
+
+
+
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi;
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo "$as_me:$LINENO: checking for ld used by GCC" >&5
+echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${acl_cv_path_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+
+
+
+ echo "$as_me:$LINENO: checking for shared library run path origin" >&5
+echo $ECHO_N "checking for shared library run path origin... $ECHO_C" >&6
+if test "${acl_cv_rpath+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+
+fi
+echo "$as_me:$LINENO: result: $acl_cv_rpath" >&5
+echo "${ECHO_T}$acl_cv_rpath" >&6
+ wl="$acl_cv_wl"
+ libext="$acl_cv_libext"
+ shlibext="$acl_cv_shlibext"
+ hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ hardcode_direct="$acl_cv_hardcode_direct"
+ hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ # Check whether --enable-rpath or --disable-rpath was given.
+if test "${enable_rpath+set}" = set; then
+ enableval="$enable_rpath"
+ :
+else
+ enable_rpath=yes
+fi;
+
+
+
+
+
+
+
+ use_additional=yes
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+
+# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given.
+if test "${with_libiconv_prefix+set}" = set; then
+ withval="$with_libiconv_prefix"
+
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/lib"
+ fi
+ fi
+
+fi;
+ LIBICONV=
+ LTLIBICONV=
+ INCICONV=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='iconv '
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value"
+ else
+ :
+ fi
+ else
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ if test $use_additional = yes; then
+ if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
+ found_dir="$additional_libdir"
+ found_so="$additional_libdir/lib$name.$shlibext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ else
+ if test -f "$additional_libdir/lib$name.$libext"; then
+ found_dir="$additional_libdir"
+ found_a="$additional_libdir/lib$name.$libext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIBICONV; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
+ found_dir="$dir"
+ found_so="$dir/lib$name.$shlibext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ else
+ if test -f "$dir/lib$name.$libext"; then
+ found_dir="$dir"
+ found_a="$dir/lib$name.$libext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+ else
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ if test "$hardcode_direct" = yes; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+ else
+ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ haveit=
+ for x in $LDFLAGS $LIBICONV; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir"
+ fi
+ if test "$hardcode_minus_L" != no; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+ else
+ LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a"
+ else
+ LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name"
+ fi
+ fi
+ additional_includedir=
+ case "$found_dir" in
+ */lib | */lib/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INCICONV; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test -n "$found_la"; then
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ if test "X$additional_libdir" != "X/usr/lib"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/lib"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIBICONV; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIBICONV; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$dep"
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$hardcode_libdir_separator"; then
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
+ else
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ for found_dir in $ltrpathdirs; do
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir"
+ done
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for CFPreferencesCopyAppValue" >&5
+echo $ECHO_N "checking for CFPreferencesCopyAppValue... $ECHO_C" >&6
+if test "${gt_cv_func_CFPreferencesCopyAppValue+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -framework CoreFoundation"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <CFPreferences.h>
+int
+main ()
+{
+CFPreferencesCopyAppValue(NULL, NULL)
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_CFPreferencesCopyAppValue=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_CFPreferencesCopyAppValue=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5
+echo "${ECHO_T}$gt_cv_func_CFPreferencesCopyAppValue" >&6
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CFPREFERENCESCOPYAPPVALUE 1
+_ACEOF
+
+ fi
+ echo "$as_me:$LINENO: checking for CFLocaleCopyCurrent" >&5
+echo $ECHO_N "checking for CFLocaleCopyCurrent... $ECHO_C" >&6
+if test "${gt_cv_func_CFLocaleCopyCurrent+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -framework CoreFoundation"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <CFLocale.h>
+int
+main ()
+{
+CFLocaleCopyCurrent();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_CFLocaleCopyCurrent=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_CFLocaleCopyCurrent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_CFLocaleCopyCurrent" >&5
+echo "${ECHO_T}$gt_cv_func_CFLocaleCopyCurrent" >&6
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CFLOCALECOPYCURRENT 1
+_ACEOF
+
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+
+
+
+
+ echo "$as_me:$LINENO: checking whether NLS is requested" >&5
+echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi;
+ echo "$as_me:$LINENO: result: $USE_NLS" >&5
+echo "${ECHO_T}$USE_NLS" >&6
+
+
+
+
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for GNU gettext in libc" >&5
+echo $ECHO_N "checking for GNU gettext in libc... $ECHO_C" >&6
+if test "${gt_cv_func_gnugettext1_libc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libintl.h>
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_gnugettext1_libc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_gnugettext1_libc=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libc" >&5
+echo "${ECHO_T}$gt_cv_func_gnugettext1_libc" >&6
+
+ if test "$gt_cv_func_gnugettext1_libc" != "yes"; then
+
+
+
+
+
+ am_save_CPPFLAGS="$CPPFLAGS"
+
+ for element in $INCICONV; do
+ haveit=
+ for x in $CPPFLAGS; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+ fi
+ done
+
+
+ echo "$as_me:$LINENO: checking for iconv" >&5
+echo $ECHO_N "checking for iconv... $ECHO_C" >&6
+if test "${am_cv_func_iconv+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_func_iconv=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_lib_iconv=yes
+ am_cv_func_iconv=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$am_save_LIBS"
+ fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5
+echo "${ECHO_T}$am_cv_func_iconv" >&6
+ if test "$am_cv_func_iconv" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ICONV 1
+_ACEOF
+
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ echo "$as_me:$LINENO: checking how to link with libiconv" >&5
+echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $LIBICONV" >&5
+echo "${ECHO_T}$LIBICONV" >&6
+ else
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+
+
+
+
+
+
+ use_additional=yes
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+
+# Check whether --with-libintl-prefix or --without-libintl-prefix was given.
+if test "${with_libintl_prefix+set}" = set; then
+ withval="$with_libintl_prefix"
+
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/lib"
+ fi
+ fi
+
+fi;
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='intl '
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value"
+ else
+ :
+ fi
+ else
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ if test $use_additional = yes; then
+ if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
+ found_dir="$additional_libdir"
+ found_so="$additional_libdir/lib$name.$shlibext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ else
+ if test -f "$additional_libdir/lib$name.$libext"; then
+ found_dir="$additional_libdir"
+ found_a="$additional_libdir/lib$name.$libext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIBINTL; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
+ found_dir="$dir"
+ found_so="$dir/lib$name.$shlibext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ else
+ if test -f "$dir/lib$name.$libext"; then
+ found_dir="$dir"
+ found_a="$dir/lib$name.$libext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
+ else
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ if test "$hardcode_direct" = yes; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
+ else
+ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ haveit=
+ for x in $LDFLAGS $LIBINTL; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir"
+ fi
+ if test "$hardcode_minus_L" != no; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
+ else
+ LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a"
+ else
+ LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name"
+ fi
+ fi
+ additional_includedir=
+ case "$found_dir" in
+ */lib | */lib/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INCINTL; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test -n "$found_la"; then
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ if test "X$additional_libdir" != "X/usr/lib"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/lib"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIBINTL; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIBINTL; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$dep"
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name"
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$hardcode_libdir_separator"; then
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
+ else
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ for found_dir in $ltrpathdirs; do
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir"
+ done
+ fi
+
+ echo "$as_me:$LINENO: checking for GNU gettext in libintl" >&5
+echo $ECHO_N "checking for GNU gettext in libintl... $ECHO_C" >&6
+if test "${gt_cv_func_gnugettext1_libintl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libintl.h>
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_gnugettext1_libintl=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_gnugettext1_libintl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libintl.h>
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ gt_cv_func_gnugettext1_libintl=yes
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libintl" >&5
+echo "${ECHO_T}$gt_cv_func_gnugettext1_libintl" >&6
+ fi
+
+ if test "$gt_cv_func_gnugettext1_libc" = "yes" \
+ || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \
+ && test "$PACKAGE" != gettext-runtime \
+ && test "$PACKAGE" != gettext-tools; }; then
+ gt_use_preinstalled_gnugettext=yes
+ else
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ fi
+
+
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+ LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+ fi
+ fi
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS 1
+_ACEOF
+
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ echo "$as_me:$LINENO: checking whether to use NLS" >&5
+echo $ECHO_N "checking whether to use NLS... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $USE_NLS" >&5
+echo "${ECHO_T}$USE_NLS" >&6
+ if test "$USE_NLS" = "yes"; then
+ echo "$as_me:$LINENO: checking where the gettext function comes from" >&5
+echo $ECHO_N "checking where the gettext function comes from... $ECHO_C" >&6
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ echo "$as_me:$LINENO: result: $gt_source" >&5
+echo "${ECHO_T}$gt_source" >&6
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then
+ echo "$as_me:$LINENO: checking how to link with libintl" >&5
+echo $ECHO_N "checking how to link with libintl... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $LIBINTL" >&5
+echo "${ECHO_T}$LIBINTL" >&6
+
+ for element in $INCINTL; do
+ haveit=
+ for x in $CPPFLAGS; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+ fi
+ done
+
+ fi
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETTEXT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DCGETTEXT 1
+_ACEOF
+
+ fi
+
+ POSUB=po
+ fi
+
+
+
+ INTLLIBS="$LIBINTL"
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+if test $ac_cv_header_sys_wait_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_time=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h locale.h libintl.h mcheck.h \
+ netdb.h netinet/in.h signum.h stdarg.h string.h \
+ sys/param.h sys/socket.h sys/time.h unistd.h \
+ termios.h stropts.h wchar.h wctype.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "$ac_cv_header_string_h" = yes
+then
+
+for ac_header in memory.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+else
+
+for ac_header in strings.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+ return 0;
+if (sizeof (pid_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_pid_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_signal=void
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+ return 0;
+if (sizeof (size_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_size_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
+echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
+if test "${ac_cv_type_uid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uid_t" >/dev/null 2>&1; then
+ ac_cv_type_uid_t=yes
+else
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
+echo "${ECHO_T}$ac_cv_type_uid_t" >&6
+if test $ac_cv_type_uid_t = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define uid_t int
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define gid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking type of array argument to getgroups" >&5
+echo $ECHO_N "checking type of array argument to getgroups... $ECHO_C" >&6
+if test "${ac_cv_type_getgroups+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_type_getgroups=cross
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Thanks to Mike Rendell for this test. */
+#include <sys/types.h>
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+
+int
+main ()
+{
+ gid_t gidset[NGID];
+ int i, n;
+ union { gid_t gval; long lval; } val;
+
+ val.lval = -1;
+ for (i = 0; i < NGID; i++)
+ gidset[i] = val.gval;
+ n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+ gidset);
+ /* Exit non-zero if getgroups seems to require an array of ints. This
+ happens when gid_t is short but getgroups modifies an array of ints. */
+ exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_getgroups=gid_t
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_type_getgroups=int
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if test $ac_cv_type_getgroups = cross; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <unistd.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then
+ ac_cv_type_getgroups=gid_t
+else
+ ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_getgroups" >&5
+echo "${ECHO_T}$ac_cv_type_getgroups" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+_ACEOF
+
+
+
+ echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+long long ll = 1LL; int i = 63;
+int
+main ()
+{
+long long llmax = (long long) -1;
+ return ll << i | ll >> i | llmax / ll | llmax % ll;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_long_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
+ if test $ac_cv_type_long_long = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+ fi
+
+
+ echo "$as_me:$LINENO: checking for unsigned long long" >&5
+echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6
+if test "${ac_cv_type_unsigned_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+unsigned long long ull = 1ULL; int i = 63;
+int
+main ()
+{
+unsigned long long ullmax = (unsigned long long) -1;
+ return ull << i | ull >> i | ullmax / ull | ullmax % ull;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_unsigned_long_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_unsigned_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6
+ if test $ac_cv_type_unsigned_long_long = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_UNSIGNED_LONG_LONG 1
+_ACEOF
+
+ fi
+
+
+ echo "$as_me:$LINENO: checking for inttypes.h" >&5
+echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6
+if test "${gl_cv_header_inttypes_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <inttypes.h>
+int
+main ()
+{
+uintmax_t i = (uintmax_t) -1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gl_cv_header_inttypes_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gl_cv_header_inttypes_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gl_cv_header_inttypes_h" >&5
+echo "${ECHO_T}$gl_cv_header_inttypes_h" >&6
+ if test $gl_cv_header_inttypes_h = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INTTYPES_H_WITH_UINTMAX 1
+_ACEOF
+
+ fi
+
+
+ echo "$as_me:$LINENO: checking for stdint.h" >&5
+echo $ECHO_N "checking for stdint.h... $ECHO_C" >&6
+if test "${gl_cv_header_stdint_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <stdint.h>
+int
+main ()
+{
+uintmax_t i = (uintmax_t) -1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gl_cv_header_stdint_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gl_cv_header_stdint_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gl_cv_header_stdint_h" >&5
+echo "${ECHO_T}$gl_cv_header_stdint_h" >&6
+ if test $gl_cv_header_stdint_h = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STDINT_H_WITH_UINTMAX 1
+_ACEOF
+
+ fi
+
+
+
+
+ if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+
+ test $ac_cv_type_long_long = yes \
+ && ac_type='long long' \
+ || ac_type='long'
+
+cat >>confdefs.h <<_ACEOF
+#define intmax_t $ac_type
+_ACEOF
+
+ else
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_INTMAX_T 1
+_ACEOF
+
+ fi
+
+
+
+
+ if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+
+ test $ac_cv_type_unsigned_long_long = yes \
+ && ac_type='unsigned long long' \
+ || ac_type='unsigned long'
+
+cat >>confdefs.h <<_ACEOF
+#define uintmax_t $ac_type
+_ACEOF
+
+ else
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_UINTMAX_T 1
+_ACEOF
+
+ fi
+
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((ssize_t *) 0)
+ return 0;
+if (sizeof (ssize_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_ssize_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_ssize_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+if test $ac_cv_type_ssize_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ssize_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for unsigned int" >&5
+echo $ECHO_N "checking for unsigned int... $ECHO_C" >&6
+if test "${ac_cv_type_unsigned_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((unsigned int *) 0)
+ return 0;
+if (sizeof (unsigned int))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_unsigned_int=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_unsigned_int=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_int" >&5
+echo "${ECHO_T}$ac_cv_type_unsigned_int" >&6
+
+echo "$as_me:$LINENO: checking size of unsigned int" >&5
+echo $ECHO_N "checking size of unsigned int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_unsigned_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_unsigned_int" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned int))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_unsigned_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (unsigned int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (unsigned int)); }
+unsigned long ulongval () { return (long) (sizeof (unsigned int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (unsigned int))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (unsigned int))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (unsigned int))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_unsigned_int=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (unsigned int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_unsigned_int=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_unsigned_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for unsigned long" >&5
+echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6
+if test "${ac_cv_type_unsigned_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((unsigned long *) 0)
+ return 0;
+if (sizeof (unsigned long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_unsigned_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_unsigned_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long" >&5
+echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6
+
+echo "$as_me:$LINENO: checking size of unsigned long" >&5
+echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_unsigned_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_unsigned_long" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_unsigned_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (unsigned long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (unsigned long)); }
+unsigned long ulongval () { return (long) (sizeof (unsigned long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (unsigned long))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (unsigned long))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (unsigned long))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_unsigned_long=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (unsigned long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_unsigned_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "int.*sprintf" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SPRINTF_RET int
+_ACEOF
+
+else
+ cat >>confdefs.h <<\_ACEOF
+#define SPRINTF_RET char *
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+int
+main ()
+{
+
+ time_t foo;
+ foo = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_T_IN_SYS_TYPES_H 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <wctype.h>
+int
+main ()
+{
+
+ wctype_t foo;
+ foo = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WCTYPE_T 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <wctype.h>
+int
+main ()
+{
+
+ wint_t foo;
+ foo = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WINT_T 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ac_cv_type_socklen_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+if ((socklen_t *) 0)
+ return 0;
+if (sizeof (socklen_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_socklen_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_socklen_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
+if test $ac_cv_type_socklen_t = yes; then
+ :
+else
+
+ echo "$as_me:$LINENO: checking for socklen_t equivalent" >&5
+echo $ECHO_N "checking for socklen_t equivalent... $ECHO_C" >&6
+ if test "${rsync_cv_socklen_t_equiv+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ rsync_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+
+int
+main ()
+{
+
+ $t len;
+ getpeername(0,0,&len);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ rsync_cv_socklen_t_equiv="$t"
+ break
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ done
+
+ if test "x$rsync_cv_socklen_t_equiv" = x; then
+ rsync_cv_socklen_t_equiv=int
+ fi
+
+fi
+
+ echo "$as_me:$LINENO: result: $rsync_cv_socklen_t_equiv" >&5
+echo "${ECHO_T}$rsync_cv_socklen_t_equiv" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define socklen_t $rsync_cv_socklen_t_equiv
+_ACEOF
+
+fi
+
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func__doprnt=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+for ac_header in stdlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in strtod
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for strtod with C89 semantics" >&5
+echo $ECHO_N "checking for strtod with C89 semantics... $ECHO_C" >&6
+if test "${gawk_ac_cv_func_strtod_c89+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ gawk_ac_cv_func_strtod_c89=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Test program from Arnold Robbins (arnold@skeeve.com) */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#else
+extern double strtod();
+#endif
+
+int
+main ()
+{
+#if ! HAVE_STRTOD
+ exit(1);
+#else
+ double d;
+ char *str = "0x345a";
+
+ d = strtod(str, 0);
+ if (d == 0)
+ exit (0);
+ else
+ exit (1);
+#endif
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gawk_ac_cv_func_strtod_c89=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gawk_ac_cv_func_strtod_c89=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $gawk_ac_cv_func_strtod_c89" >&5
+echo "${ECHO_T}$gawk_ac_cv_func_strtod_c89" >&6
+if test $gawk_ac_cv_func_strtod_c89 = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STRTOD_NOT_C89 1
+_ACEOF
+
+fi
+
+
+
+
+for ac_header in stdlib.h sys/time.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in alarm
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for working mktime" >&5
+echo $ECHO_N "checking for working mktime... $ECHO_C" >&6
+if test "${ac_cv_func_working_mktime+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_working_mktime=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Test program from Paul Eggert and Tony Leneis. */
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if !HAVE_ALARM
+# define alarm(X) /* empty */
+#endif
+
+/* Work around redefinition to rpl_putenv by other config tests. */
+#undef putenv
+
+static time_t time_t_max;
+static time_t time_t_min;
+
+/* Values we'll use to set the TZ environment variable. */
+static char *tz_strings[] = {
+ (char *) 0, "TZ=GMT0", "TZ=JST-9",
+ "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00"
+};
+#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0]))
+
+/* Fail if mktime fails to convert a date in the spring-forward gap.
+ Based on a problem report from Andreas Jaeger. */
+static void
+spring_forward_gap ()
+{
+ /* glibc (up to about 1998-10-07) failed this test. */
+ struct tm tm;
+
+ /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0"
+ instead of "TZ=America/Vancouver" in order to detect the bug even
+ on systems that don't support the Olson extension, or don't have the
+ full zoneinfo tables installed. */
+ putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
+
+ tm.tm_year = 98;
+ tm.tm_mon = 3;
+ tm.tm_mday = 5;
+ tm.tm_hour = 2;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ tm.tm_isdst = -1;
+ if (mktime (&tm) == (time_t)-1)
+ exit (1);
+}
+
+static void
+mktime_test1 (now)
+ time_t now;
+{
+ struct tm *lt;
+ if ((lt = localtime (&now)) && mktime (lt) != now)
+ exit (1);
+}
+
+static void
+mktime_test (now)
+ time_t now;
+{
+ mktime_test1 (now);
+ mktime_test1 ((time_t) (time_t_max - now));
+ mktime_test1 ((time_t) (time_t_min + now));
+}
+
+static void
+irix_6_4_bug ()
+{
+ /* Based on code from Ariel Faigon. */
+ struct tm tm;
+ tm.tm_year = 96;
+ tm.tm_mon = 3;
+ tm.tm_mday = 0;
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ tm.tm_isdst = -1;
+ mktime (&tm);
+ if (tm.tm_mon != 2 || tm.tm_mday != 31)
+ exit (1);
+}
+
+static void
+bigtime_test (j)
+ int j;
+{
+ struct tm tm;
+ time_t now;
+ tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j;
+ now = mktime (&tm);
+ if (now != (time_t) -1)
+ {
+ struct tm *lt = localtime (&now);
+ if (! (lt
+ && lt->tm_year == tm.tm_year
+ && lt->tm_mon == tm.tm_mon
+ && lt->tm_mday == tm.tm_mday
+ && lt->tm_hour == tm.tm_hour
+ && lt->tm_min == tm.tm_min
+ && lt->tm_sec == tm.tm_sec
+ && lt->tm_yday == tm.tm_yday
+ && lt->tm_wday == tm.tm_wday
+ && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst)
+ == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst))))
+ exit (1);
+ }
+}
+
+int
+main ()
+{
+ time_t t, delta;
+ int i, j;
+
+ /* This test makes some buggy mktime implementations loop.
+ Give up after 60 seconds; a mktime slower than that
+ isn't worth using anyway. */
+ alarm (60);
+
+ for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
+ continue;
+ time_t_max--;
+ if ((time_t) -1 < 0)
+ for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
+ continue;
+ delta = time_t_max / 997; /* a suitable prime number */
+ for (i = 0; i < N_STRINGS; i++)
+ {
+ if (tz_strings[i])
+ putenv (tz_strings[i]);
+
+ for (t = 0; t <= time_t_max - delta; t += delta)
+ mktime_test (t);
+ mktime_test ((time_t) 1);
+ mktime_test ((time_t) (60 * 60));
+ mktime_test ((time_t) (60 * 60 * 24));
+
+ for (j = 1; 0 < j; j *= 2)
+ bigtime_test (j);
+ bigtime_test (j - 1);
+ }
+ irix_6_4_bug ();
+ spring_forward_gap ();
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_working_mktime=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_working_mktime=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_working_mktime" >&5
+echo "${ECHO_T}$ac_cv_func_working_mktime" >&6
+if test $ac_cv_func_working_mktime = no; then
+ case $LIBOBJS in
+ "mktime.$ac_objext" | \
+ *" mktime.$ac_objext" | \
+ "mktime.$ac_objext "* | \
+ *" mktime.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS mktime.$ac_objext" ;;
+esac
+
+fi
+
+case "$ac_cv_func_working_mktime" in
+yes)
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MKTIME 1
+_ACEOF
+
+ ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for fmod in -lm" >&5
+echo $ECHO_N "checking for fmod in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_fmod+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char fmod ();
+int
+main ()
+{
+fmod ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_fmod=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_fmod=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_fmod" >&5
+echo "${ECHO_T}$ac_cv_lib_m_fmod" >&6
+if test $ac_cv_lib_m_fmod = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+ LIBS="-lm $LIBS"
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in fmod getgrent getgroups grantpt iswctype mbrlen \
+ memcmp memcpy memmove memset setlocale snprintf strchr \
+ strerror strftime strncasecmp strtod strtoul system tzset \
+ isascii btowc \
+ iswlower iswupper towlower towupper \
+ wcrtomb wcscoll wcscoll wctype
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ echo "$as_me:$LINENO: checking whether mbrtowc and mbstate_t are properly declared" >&5
+echo $ECHO_N "checking whether mbrtowc and mbstate_t are properly declared... $ECHO_C" >&6
+if test "${ac_cv_func_mbrtowc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <wchar.h>
+int
+main ()
+{
+mbstate_t state; return ! (sizeof state && mbrtowc);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_mbrtowc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_mbrtowc=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mbrtowc" >&5
+echo "${ECHO_T}$ac_cv_func_mbrtowc" >&6
+ if test $ac_cv_func_mbrtowc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MBRTOWC 1
+_ACEOF
+
+ fi
+
+
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <dlfcn.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define DYNAMIC 1
+_ACEOF
+
+ if test "$GCC" = yes
+ then
+ # Add others here as appropriate,
+ # one day use GNU libtool.
+ if uname | $EGREP -i 'linux|freebsd|cygwin' > /dev/null
+ then
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ fi
+ fi
+
+ # Check this separately. Some systems have dlopen
+ # in libc. Notably freebsd and cygwin.
+
+echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dl_dlopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+ LIBS="-ldl $LIBS"
+
+fi
+
+
+fi
+
+
+
+case `(uname) 2> /dev/null` in
+*VMS*|*BeOS*|*OS/2*|*MS-DOS*)
+
+cat >>confdefs.h <<\_ACEOF
+#define GETPGRP_VOID 1
+_ACEOF
+
+ ;;
+*) echo "$as_me:$LINENO: checking whether getpgrp requires zero arguments" >&5
+echo $ECHO_N "checking whether getpgrp requires zero arguments... $ECHO_C" >&6
+if test "${ac_cv_func_getpgrp_void+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Use it with a single arg.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+getpgrp (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_getpgrp_void=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getpgrp_void=yes
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getpgrp_void" >&5
+echo "${ECHO_T}$ac_cv_func_getpgrp_void" >&6
+if test $ac_cv_func_getpgrp_void = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GETPGRP_VOID 1
+_ACEOF
+
+fi
+
+ ;;
+esac
+
+echo "$as_me:$LINENO: checking for printf %F format" >&5
+echo $ECHO_N "checking for printf %F format... $ECHO_C" >&6
+if test "$cross_compiling" = yes; then
+ has_f_format=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+
+#include <stdio.h>
+
+int main()
+{
+ char buf[100];
+
+ sprintf(buf, "%F", 123.45);
+
+ if (strcmp(buf, "123.450000") == 0)
+ return 0;
+ else
+ return 1;
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ has_f_format=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+has_f_format=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if test "$has_f_format" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PRINTF_HAS_F_FORMAT 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $has_f_format" >&5
+echo "${ECHO_T}$has_f_format" >&6
+
+
+gawk_have_sockets=no
+# Check for system-dependent location of socket libraries
+
+SOCKET_LIBS=
+if test "$ISC" = yes; then
+ SOCKET_LIBS="-lnsl_s -linet"
+else
+ # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And karl@cs.umb.edu says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ #
+ # ADR: Is this needed just for sockets???
+# AC_CHECK_LIB(dnet, dnet_ntoa, [SOCKET_LIBS="$SOCKET_LIBS -ldnet"])
+# if test $ac_cv_lib_dnet_ntoa = no; then
+# AC_CHECK_LIB(dnet_stub, dnet_ntoa,
+# [SOCKET_LIBS="$SOCKET_LIBS -ldnet_stub"])
+# fi
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # chad@anasazi.com says the Pyramid MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to dickey@clark.net.
+ echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_gethostbyname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+
+ if test $ac_cv_func_gethostbyname = no; then
+ echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+ SOCKET_LIBS="$SOCKET_LIBS -lnsl"
+fi
+
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says simon@lia.di.epfl.ch: it contains
+ # gethostby* variants that don't use the nameserver (or something).
+ # -lsocket must be given before -lnsl if both are needed.
+ # We assume that if connect needs -lnsl, so does gethostbyname.
+ echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char connect (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_connect=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+
+ if test $ac_cv_func_connect = no; then
+ echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $SOCKET_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect ();
+int
+main ()
+{
+connect ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_socket_connect=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+if test $ac_cv_lib_socket_connect = yes; then
+ SOCKET_LIBS="-lsocket $SOCKET_LIBS"
+ gawk_have_sockets=yes
+fi
+
+ else
+ gawk_have_sockets=yes
+ fi
+fi
+
+if test "${gawk_have_sockets}" = "yes"
+then
+ echo "$as_me:$LINENO: checking where to find the socket library calls" >&5
+echo $ECHO_N "checking where to find the socket library calls... $ECHO_C" >&6
+ case "${SOCKET_LIBS}" in
+ ?*) gawk_lib_loc="${SOCKET_LIBS}" ;;
+ *) gawk_lib_loc="the standard library" ;;
+ esac
+ echo "$as_me:$LINENO: result: ${gawk_lib_loc}" >&5
+echo "${ECHO_T}${gawk_lib_loc}" >&6
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKETS 1
+_ACEOF
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5
+echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_blksize)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_stat_st_blksize=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_blksize)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_stat_st_blksize=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_blksize=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6
+if test $ac_cv_member_struct_stat_st_blksize = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ST_BLKSIZE 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_time=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_struct_tm=time.h
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for struct tm.tm_zone" >&5
+echo $ECHO_N "checking for struct tm.tm_zone... $ECHO_C" >&6
+if test "${ac_cv_member_struct_tm_tm_zone+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+
+int
+main ()
+{
+static struct tm ac_aggr;
+if (ac_aggr.tm_zone)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_tm_tm_zone=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+
+int
+main ()
+{
+static struct tm ac_aggr;
+if (sizeof ac_aggr.tm_zone)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_tm_tm_zone=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_tm_tm_zone=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_tm_tm_zone" >&5
+echo "${ECHO_T}$ac_cv_member_struct_tm_tm_zone" >&6
+if test $ac_cv_member_struct_tm_tm_zone = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+_ACEOF
+
+
+fi
+
+if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TM_ZONE 1
+_ACEOF
+
+else
+ echo "$as_me:$LINENO: checking for tzname" >&5
+echo $ECHO_N "checking for tzname... $ECHO_C" >&6
+if test "${ac_cv_var_tzname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <time.h>
+#ifndef tzname /* For SGI. */
+extern char *tzname[]; /* RS6000 and others reject char **tzname. */
+#endif
+
+int
+main ()
+{
+atoi(*tzname);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_var_tzname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_var_tzname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_var_tzname" >&5
+echo "${ECHO_T}$ac_cv_var_tzname" >&6
+ if test $ac_cv_var_tzname = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TZNAME 1
+_ACEOF
+
+ fi
+fi
+
+
+
+echo "$as_me:$LINENO: checking whether char is unsigned" >&5
+echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6
+if test "${ac_cv_c_char_unsigned+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((char) -1) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_char_unsigned=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_char_unsigned=yes
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5
+echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define __CHAR_UNSIGNED__ 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ }
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for C/C++ restrict keyword" >&5
+echo $ECHO_N "checking for C/C++ restrict keyword... $ECHO_C" >&6
+if test "${ac_cv_c_restrict+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_restrict=no
+ # Try the official restrict keyword, then gcc's __restrict, and
+ # the less common variants.
+ for ac_kw in restrict __restrict __restrict__ _Restrict; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+float * $ac_kw x;
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_restrict=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_restrict" >&5
+echo "${ECHO_T}$ac_cv_c_restrict" >&6
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no)
+cat >>confdefs.h <<\_ACEOF
+#define restrict
+_ACEOF
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+echo "$as_me:$LINENO: checking for preprocessor stringizing operator" >&5
+echo $ECHO_N "checking for preprocessor stringizing operator... $ECHO_C" >&6
+if test "${ac_cv_c_stringize+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define x(y) #y
+
+char *s = x(teststring);
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "#teststring" >/dev/null 2>&1; then
+ ac_cv_c_stringize=no
+else
+ ac_cv_c_stringize=yes
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stringize" >&5
+echo "${ECHO_T}$ac_cv_c_stringize" >&6
+if test $ac_cv_c_stringize = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRINGIZE 1
+_ACEOF
+
+fi
+
+
+ ac_config_headers="$ac_config_headers config.h:configh.in"
+
+
+
+
+ ac_config_files="$ac_config_files Makefile awklib/Makefile doc/Makefile po/Makefile.in test/Makefile version.c:version.in"
+
+
+
+
+
+
+
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by GNU Awk $as_me 3.1.5, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+GNU Awk config.status 3.1.5
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "awklib/Makefile" ) CONFIG_FILES="$CONFIG_FILES awklib/Makefile" ;;
+ "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
+ "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+ "version.c" ) CONFIG_FILES="$CONFIG_FILES version.c:version.in" ;;
+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:configh.in" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@am__tar@,$am__tar,;t t
+s,@am__untar@,$am__untar,;t t
+s,@EGREP@,$EGREP,;t t
+s,@YACC@,$YACC,;t t
+s,@LN_S@,$LN_S,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@CPP@,$CPP,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@U@,$U,;t t
+s,@ANSI2KNR@,$ANSI2KNR,;t t
+s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t
+s,@USE_NLS@,$USE_NLS,;t t
+s,@MSGFMT@,$MSGFMT,;t t
+s,@GMSGFMT@,$GMSGFMT,;t t
+s,@XGETTEXT@,$XGETTEXT,;t t
+s,@MSGMERGE@,$MSGMERGE,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@INTL_MACOSX_LIBS@,$INTL_MACOSX_LIBS,;t t
+s,@LIBICONV@,$LIBICONV,;t t
+s,@LTLIBICONV@,$LTLIBICONV,;t t
+s,@INTLLIBS@,$INTLLIBS,;t t
+s,@LIBINTL@,$LIBINTL,;t t
+s,@LTLIBINTL@,$LTLIBINTL,;t t
+s,@POSUB@,$POSUB,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@SOCKET_LIBS@,$SOCKET_LIBS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ default-1 )
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+sed '$i\
+ echo $as_me: fixing Makefile to keep version.c\
+ sed "/CONFIG_CLEAN_FILES/s/version.c//" < Makefile > $$.Makefile\
+ mv $$.Makefile Makefile
+ ' < $CONFIG_STATUS > $$.gawk-hack
+ mv $$.gawk-hack $CONFIG_STATUS
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
--- /dev/null
+dnl
+dnl configure.ac --- autoconf input file for gawk
+dnl
+dnl Copyright (C) 1995-2005 the Free Software Foundation, Inc.
+dnl
+dnl This file is part of GAWK, the GNU implementation of the
+dnl AWK Programming Language.
+dnl
+dnl GAWK is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl GAWK is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+dnl
+
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT([GNU Awk], 3.1.5, bug-gawk@gnu.org, gawk)
+
+# This is a hack. Different versions of install on different systems
+# are just too different. Chuck it and use install-sh.
+#
+# If the user supplies $INSTALL, figure they know what they're doing.
+#
+# With Autoconf 2.5x, this needs to come very early on, but *after*
+# the INIT macro. Sigh.
+
+if test "x$INSTALL" = "x"
+then
+ INSTALL="$srcdir/install-sh -c"
+ export INSTALL
+fi
+
+AC_PREREQ(2.59)
+AM_INIT_AUTOMAKE
+
+dnl Additional argument stuff
+AC_ARG_ENABLE(portals, [ --enable-portals Enable /p as path prefix for portals],
+ if test "$enableval" = yes
+ then
+ AC_DEFINE(HAVE_PORTALS, 1, [we have portals on /p on this system])
+ fi
+)
+AC_ARG_WITH(whiny-user-strftime, [ --with-whiny-user-strftime Force use of included version of strftime for deficient systems],
+ if test "$withval" = yes
+ then
+ AC_DEFINE(USE_INCLUDED_STRFTIME, 1,
+ [force use of our version of strftime])
+ fi
+)
+AC_ARG_ENABLE([lint], [ --disable-lint Disable gawk lint checking],
+ if test "$enableval" = no
+ then
+ AC_DEFINE(NO_LINT, 1, [disable lint checks])
+ fi
+)
+AC_ARG_ENABLE(switch, [ --enable-switch Enable switch statements for awk programs],
+ if test "$enableval" = yes
+ then
+ AC_DEFINE(ALLOW_SWITCH, 1, [switch statements are enabled in awk programs])
+ fi
+)
+
+dnl checks for programs
+AC_PROG_EGREP
+AC_PROG_YACC
+AC_PROG_LN_S
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_RANLIB
+
+AC_OBJEXT
+AC_EXEEXT
+
+AC_PROG_INSTALL
+
+AC_PROG_MAKE_SET
+
+# This is mainly for my use during testing and development.
+# Yes, it's a bit of a hack.
+AC_MSG_CHECKING([for special development options])
+if test -f $srcdir/.developing
+then
+ # add other debug flags as appropriate, save GAWKDEBUG for emergencies
+ CFLAGS="$CFLAGS -DARRAYDEBUG"
+ if grep dbug $srcdir/.developing
+ then
+ CFLAGS="$CFLAGS -DDBUG"
+ LIBS="$LIBS dbug/libdbug.a"
+ fi
+ # turn on compiler warnings if we're doing development
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -Wall"
+ fi
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_SUBST(CFLAGS)
+
+dnl checks for systems
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+AC_SYS_LARGEFILE
+GAWK_AC_AIX_TWEAK
+GAWK_AC_LINUX_ALPHA
+
+if test "$ISC" = 1 # will be set by test for ISC
+then
+dnl need -D_SYSV3 for ISC
+ CFLAGS="$CFLAGS -D_SYSV3"
+fi
+
+dnl check for C compiler for automake
+AM_PROG_CC_STDC
+AM_C_PROTOTYPES
+
+dnl Cygwin doesn't like to get libs with full paths
+dnl since that overrides linking against DLLs.
+case `(uname) 2> /dev/null` in
+*CYGWIN*)
+ with_libiconv_prefix=no
+ with_libintl_prefix=no
+ ;;
+*)
+ ;;
+esac
+
+dnl initialize GNU gettext
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.14.4])
+
+dnl checks for header files
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
+AC_CHECK_HEADERS(fcntl.h limits.h locale.h libintl.h mcheck.h \
+ netdb.h netinet/in.h signum.h stdarg.h string.h \
+ sys/param.h sys/socket.h sys/time.h unistd.h \
+ termios.h stropts.h wchar.h wctype.h)
+
+if test "$ac_cv_header_string_h" = yes
+then
+ AC_CHECK_HEADERS(memory.h)
+else
+ AC_CHECK_HEADERS(strings.h)
+fi
+
+dnl checks for typedefs
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_SIZE_T
+AC_TYPE_GETGROUPS
+gl_AC_TYPE_LONG_LONG
+gl_AC_TYPE_UNSIGNED_LONG_LONG
+gl_AC_TYPE_INTMAX_T
+gl_AC_TYPE_UINTMAX_T
+AC_CHECK_TYPE(ssize_t, int)
+AC_CHECK_SIZEOF(unsigned int)
+AC_CHECK_SIZEOF(unsigned long)
+AC_EGREP_HEADER([int.*sprintf], stdio.h,
+ AC_DEFINE(SPRINTF_RET, int, [return type of sprintf]),
+ AC_DEFINE(SPRINTF_RET, char *))
+dnl see if time_t is defined in <sys/types.h>
+AC_TRY_COMPILE([#include <sys/types.h>],[
+ time_t foo;
+ foo = 0;
+],
+ AC_DEFINE(TIME_T_IN_SYS_TYPES_H, 1,
+ [some systems define this type here]))
+dnl check for wctype_t in <wctype.h>
+AC_TRY_COMPILE([#include <wctype.h>],[
+ wctype_t foo;
+ foo = 0;
+],
+ AC_DEFINE(HAVE_WCTYPE_T, 1, [systems should define this type here]))
+dnl check for wint_t in <wctype.h>
+AC_TRY_COMPILE([#include <wctype.h>],[
+ wint_t foo;
+ foo = 0;
+],
+ AC_DEFINE(HAVE_WINT_T, 1, [systems should define this type here]))
+
+dnl Borrwed from rsync, thanks to to Jim Meyering.
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+
+dnl This is no good, because passing the wrong pointer on C compilers is
+dnl likely to only generate a warning, not an error.
+
+AC_DEFUN([TYPE_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([rsync_cv_socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ rsync_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ rsync_cv_socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$rsync_cv_socklen_t_equiv" = x; then
+dnl Some systems get this. Default to int. -- ADR
+dnl AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ rsync_cv_socklen_t_equiv=int
+ fi
+ ])
+ AC_MSG_RESULT($rsync_cv_socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+TYPE_SOCKLEN_T
+
+dnl checks for functions
+AC_FUNC_VPRINTF
+GAWK_AC_FUNC_STRTOD_C89
+AC_FUNC_MKTIME
+case "$ac_cv_func_working_mktime" in
+yes) AC_DEFINE(HAVE_MKTIME, 1, [we have the mktime function])
+ ;;
+esac
+
+AC_CHECK_LIB(m, fmod)
+AC_CHECK_FUNCS(fmod getgrent getgroups grantpt iswctype mbrlen \
+ memcmp memcpy memmove memset setlocale snprintf strchr \
+ strerror strftime strncasecmp strtod strtoul system tzset \
+ isascii btowc \
+ iswlower iswupper towlower towupper \
+ wcrtomb wcscoll wcscoll wctype)
+dnl this check is for both mbrtowc and the mbstate_t type, which is good
+AC_FUNC_MBRTOWC
+
+dnl check for dynamic linking
+dnl This is known to be very primitive
+AC_CHECK_HEADER(dlfcn.h,
+ [AC_DEFINE([DYNAMIC], 1, [dynamic loading is possible])
+ if test "$GCC" = yes
+ then
+ # Add others here as appropriate,
+ # one day use GNU libtool.
+ if uname | $EGREP -i 'linux|freebsd|cygwin' > /dev/null
+ then
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ fi
+ fi
+
+ # Check this separately. Some systems have dlopen
+ # in libc. Notably freebsd and cygwin.
+ AC_CHECK_LIB(dl, dlopen)
+])
+
+dnl check for how to use getpgrp
+dnl have to hardwire it for VMS POSIX. Sigh.
+dnl ditto for BeOS, OS/2, and MS-DOS.
+case `(uname) 2> /dev/null` in
+*VMS*|*BeOS*|*OS/2*|*MS-DOS*)
+ AC_DEFINE(GETPGRP_VOID, 1,
+ [Define to 1 if the getpgrp function requires zero arguments.])
+ ;;
+*) AC_FUNC_GETPGRP
+ ;;
+esac
+
+dnl check for printf %F format
+AC_MSG_CHECKING([for printf %F format])
+AC_RUN_IFELSE([
+#include <stdio.h>
+
+int main()
+{
+ char buf[[100]];
+
+ sprintf(buf, "%F", 123.45);
+
+ if (strcmp(buf, "123.450000") == 0)
+ return 0;
+ else
+ return 1;
+}
+],
+ has_f_format=yes,
+ has_f_format=no,
+ has_f_format=no dnl Cross-compiling, assuming the worst.
+)
+if test "$has_f_format" = yes; then
+ AC_DEFINE(PRINTF_HAS_F_FORMAT, 1, [Define to 1 if *printf supports %F format])
+fi
+AC_MSG_RESULT($has_f_format)
+
+dnl check for sockets
+GAWK_AC_LIB_SOCKETS
+
+dnl checks for structure members
+AC_STRUCT_ST_BLKSIZE
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_STRUCT_TIMEZONE
+
+dnl checks for compiler characteristics
+AC_C_CHAR_UNSIGNED
+AC_C_CONST
+AC_C_RESTRICT
+AC_C_INLINE
+AC_C_STRINGIZE
+
+AC_CONFIG_HEADERS([config.h:configh.in])
+AH_BOTTOM([#include "custom.h"])
+
+AC_CONFIG_FILES(Makefile
+ awklib/Makefile
+ doc/Makefile
+ po/Makefile.in
+ test/Makefile
+ [version.c:version.in])
+
+dnl This is a significant and rather ugly hack. We want to keep
+dnl version.c from being removed upon `make distclean'.
+dnl We put the `$$' on the front for old systems with 14-char filenames.
+
+dnl At this point, `configure' has finished creating `config.status' which
+dnl actually does all the checking and configuring. `config.status' is run
+dnl by the AC_OUTPUT macro below. This step comes in between the two: it
+dnl adds code to `config.status'. Doing it there ensures that this step
+dnl happens *every* time `config.status' is run, such as when `make' decides
+dnl to update something. Fun, fun, fun.
+
+dnl Be careful of multiple levels of shell quoting!
+
+dnl The trailing newline in the sed command is needed for Mac OS X. Sigh.
+
+AC_CONFIG_COMMANDS_POST([sed '$i\
+ echo $as_me: fixing Makefile to keep version.c\
+ sed "/CONFIG_CLEAN_FILES/s/version.c//" < Makefile > $$.Makefile\
+ mv $$.Makefile Makefile
+ ' < $CONFIG_STATUS > $$.gawk-hack
+ mv $$.gawk-hack $CONFIG_STATUS])
+
+
+AC_OUTPUT
--- /dev/null
+/*
+ * custom.h
+ *
+ * This file is for use on systems where Autoconf isn't quite able to
+ * get things right. It is appended to the bottom of config.h by configure,
+ * in order to override definitions from Autoconf that are erroneous. See
+ * the manual for more information.
+ *
+ * If you make additions to this file for your system, please send me
+ * the information, to arnold@skeeve.com.
+ */
+
+/*
+ * Copyright (C) 1995-2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* for MIPS RiscOS, from Nelson H. F. Beebe, beebe@math.utah.edu */
+#if defined(__host_mips) && defined(SYSTYPE_BSD43)
+#undef HAVE_STRTOD
+#undef HAVE_STRERROR
+#endif
+
+/* for VMS POSIX, from Pat Rankin, rankin@pactechdata.com */
+#ifdef VMS_POSIX
+#undef VMS
+#include "vms/redirect.h"
+#endif
+
+/* For QNX, based on submission from Michael Hunter, mphunter@qnx.com */
+#ifdef __QNX__
+#define GETPGRP_VOID 1
+#endif
+
+/* For Amigas, from Fred Fish, fnf@ninemoons.com */
+#ifdef __amigaos__
+#define fork vfork
+#endif
+
+/* For BeOS, from mc@whoever.com */
+#if defined(__dest_os) && __dest_os == __be_os
+#define BROKEN_STRNCASECMP
+#define ELIDE_CODE
+#include <alloca.h>
+#endif
+
+/* For Tandems, based on code from scldad@sdc.com.au */
+#ifdef TANDEM
+#define tempnam(a,b) tmpnam(NULL)
+#define variable(a,b,c) variabl(a,b,c)
+#define srandom srand
+#define random rand
+
+#include <cextdecs(PROCESS_GETINFO_)>
+#endif
+
+/* For 16-bit DOS */
+#if defined(MSC_VER) && defined(MSDOS)
+#define NO_PROFILING 1
+#endif
+
+/* For MacOS X, which is almost BSD Unix */
+#ifdef __APPLE__
+#define HAVE_MKTIME 1
+#endif
+
+#ifdef __WIN32__
+#undef HAVE_STRFTIME
+/* #define system(s) os_system(s) */
+#endif
+
+/* For ULTRIX 4.3 */
+#ifdef ultrix
+#define HAVE_MKTIME 1
+#define GETGROUPS_NOT_STANDARD 1
+#endif
+
+/* For whiny users */
+#ifdef USE_INCLUDED_STRFTIME
+#undef HAVE_STRFTIME
+#endif
+
+/* For HP/UX with gcc */
+#if defined(hpux) || defined(_HPUX_SOURCE)
+#undef HAVE_TZSET
+#define HAVE_TZSET 1
+#define _TZSET 1
+#endif
--- /dev/null
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-02-09.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mecanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+/* dfa.c - deterministic extended regexp routines for GNU
+ Copyright 1988, 1998, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
+
+/* Written June, 1988 by Mike Haertel
+ Modified July, 1988 by Arthur David Olson to assist BMG speedups */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#ifndef VMS
+#include <sys/types.h>
+#else
+#include <stddef.h>
+#endif
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern char *calloc(), *malloc(), *realloc();
+extern void free();
+#endif
+
+#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#if HAVE_SETLOCALE
+# include <locale.h>
+#endif
+
+
+#ifndef DEBUG /* use the same approach as regex.c */
+#undef assert
+#define assert(e)
+#endif /* DEBUG */
+
+#ifndef isgraph
+#define isgraph(C) (isprint(C) && !isspace(C))
+#endif
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+#define ISALPHA(C) isalpha(C)
+#define ISUPPER(C) isupper(C)
+#define ISLOWER(C) islower(C)
+#define ISDIGIT(C) isdigit(C)
+#define ISXDIGIT(C) isxdigit(C)
+#define ISSPACE(C) isspace(C)
+#define ISPUNCT(C) ispunct(C)
+#define ISALNUM(C) isalnum(C)
+#define ISPRINT(C) isprint(C)
+#define ISGRAPH(C) isgraph(C)
+#define ISCNTRL(C) iscntrl(C)
+#else
+#define ISALPHA(C) (isascii(C) && isalpha(C))
+#define ISUPPER(C) (isascii(C) && isupper(C))
+#define ISLOWER(C) (isascii(C) && islower(C))
+#define ISDIGIT(C) (isascii(C) && isdigit(C))
+#define ISXDIGIT(C) (isascii(C) && isxdigit(C))
+#define ISSPACE(C) (isascii(C) && isspace(C))
+#define ISPUNCT(C) (isascii(C) && ispunct(C))
+#define ISALNUM(C) (isascii(C) && isalnum(C))
+#define ISPRINT(C) (isascii(C) && isprint(C))
+#define ISGRAPH(C) (isascii(C) && isgraph(C))
+#define ISCNTRL(C) (isascii(C) && iscntrl(C))
+#endif
+
+/* ISASCIIDIGIT differs from ISDIGIT, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
+ only '0' through '9' are digits. Prefer ISASCIIDIGIT to ISDIGIT unless
+ it's important to use the locale's definition of `digit' even when the
+ host does not conform to Posix. */
+#define ISASCIIDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+/* gettext.h ensures that we don't use gettext if ENABLE_NLS is not defined */
+#include "gettext.h"
+#define _(str) gettext (str)
+
+#ifndef NO_MBSUPPORT
+#include "mbsupport.h" /* defines MBS_SUPPORT if appropriate */
+#endif
+#ifdef MBS_SUPPORT
+/* We can handle multibyte strings. */
+# include <wchar.h>
+# include <wctype.h>
+#endif
+
+#include "regex.h"
+#include "dfa.h"
+#include "hard-locale.h"
+
+/* HPUX, define those as macros in sys/param.h */
+#ifdef setbit
+# undef setbit
+#endif
+#ifdef clrbit
+# undef clrbit
+#endif
+
+static void dfamust PARAMS ((struct dfa *dfa));
+
+static ptr_t xcalloc PARAMS ((size_t n, size_t s));
+static ptr_t xmalloc PARAMS ((size_t n));
+static ptr_t xrealloc PARAMS ((ptr_t p, size_t n));
+#ifdef DEBUG
+static void prtok PARAMS ((token t));
+#endif
+static int tstbit PARAMS ((unsigned b, charclass c));
+static void setbit PARAMS ((unsigned b, charclass c));
+static void clrbit PARAMS ((unsigned b, charclass c));
+static void copyset PARAMS ((charclass src, charclass dst));
+static void zeroset PARAMS ((charclass s));
+static void notset PARAMS ((charclass s));
+static int equal PARAMS ((charclass s1, charclass s2));
+static int charclass_index PARAMS ((charclass s));
+static int looking_at PARAMS ((const char *s));
+static token lex PARAMS ((void));
+static void addtok PARAMS ((token t));
+static void atom PARAMS ((void));
+static int nsubtoks PARAMS ((int tindex));
+static void copytoks PARAMS ((int tindex, int ntokens));
+static void closure PARAMS ((void));
+static void branch PARAMS ((void));
+static void regexp PARAMS ((int toplevel));
+static void copy PARAMS ((position_set const *src, position_set *dst));
+static void insert PARAMS ((position p, position_set *s));
+static void merge PARAMS ((position_set const *s1, position_set const *s2, position_set *m));
+static void delete PARAMS ((position p, position_set *s));
+static int state_index PARAMS ((struct dfa *d, position_set const *s,
+ int newline, int letter));
+static void build_state PARAMS ((int s, struct dfa *d));
+static void build_state_zero PARAMS ((struct dfa *d));
+static char *icatalloc PARAMS ((char *old, char *new));
+static char *icpyalloc PARAMS ((char *string));
+static char *istrstr PARAMS ((char *lookin, char *lookfor));
+static void ifree PARAMS ((char *cp));
+static void freelist PARAMS ((char **cpp));
+static char **enlist PARAMS ((char **cpp, char *new, size_t len));
+static char **comsubs PARAMS ((char *left, char *right));
+static char **addlists PARAMS ((char **old, char **new));
+static char **inboth PARAMS ((char **left, char **right));
+
+static ptr_t
+xcalloc (size_t n, size_t s)
+{
+ ptr_t r = calloc(n, s);
+
+ if (!r)
+ dfaerror(_("Memory exhausted"));
+ return r;
+}
+
+static ptr_t
+xmalloc (size_t n)
+{
+ ptr_t r = malloc(n);
+
+ assert(n != 0);
+ if (!r)
+ dfaerror(_("Memory exhausted"));
+ return r;
+}
+
+static ptr_t
+xrealloc (ptr_t p, size_t n)
+{
+ ptr_t r = realloc(p, n);
+
+ assert(n != 0);
+ if (!r)
+ dfaerror(_("Memory exhausted"));
+ return r;
+}
+
+#define CALLOC(p, t, n) ((p) = (t *) xcalloc((size_t)(n), sizeof (t)))
+#define MALLOC(p, t, n) ((p) = (t *) xmalloc((n) * sizeof (t)))
+#define REALLOC(p, t, n) ((p) = (t *) xrealloc((ptr_t) (p), (n) * sizeof (t)))
+
+/* Reallocate an array of type t if nalloc is too small for index. */
+#define REALLOC_IF_NECESSARY(p, t, nalloc, index) \
+ if ((index) >= (nalloc)) \
+ { \
+ do \
+ (nalloc) *= 2; \
+ while ((index) >= (nalloc)); \
+ REALLOC(p, t, nalloc); \
+ }
+
+#ifdef DEBUG
+
+static void
+prtok (token t)
+{
+ char const *s;
+
+ if (t < 0)
+ fprintf(stderr, "END");
+ else if (t < NOTCHAR)
+ fprintf(stderr, "%c", t);
+ else
+ {
+ switch (t)
+ {
+ case EMPTY: s = "EMPTY"; break;
+ case BACKREF: s = "BACKREF"; break;
+ case BEGLINE: s = "BEGLINE"; break;
+ case ENDLINE: s = "ENDLINE"; break;
+ case BEGWORD: s = "BEGWORD"; break;
+ case ENDWORD: s = "ENDWORD"; break;
+ case LIMWORD: s = "LIMWORD"; break;
+ case NOTLIMWORD: s = "NOTLIMWORD"; break;
+ case QMARK: s = "QMARK"; break;
+ case STAR: s = "STAR"; break;
+ case PLUS: s = "PLUS"; break;
+ case CAT: s = "CAT"; break;
+ case OR: s = "OR"; break;
+ case ORTOP: s = "ORTOP"; break;
+ case LPAREN: s = "LPAREN"; break;
+ case RPAREN: s = "RPAREN"; break;
+ case CRANGE: s = "CRANGE"; break;
+#ifdef MBS_SUPPORT
+ case ANYCHAR: s = "ANYCHAR"; break;
+ case MBCSET: s = "MBCSET"; break;
+#endif /* MBS_SUPPORT */
+ default: s = "CSET"; break;
+ }
+ fprintf(stderr, "%s", s);
+ }
+}
+#endif /* DEBUG */
+
+/* Stuff pertaining to charclasses. */
+
+static int
+tstbit (unsigned b, charclass c)
+{
+ return c[b / INTBITS] & 1 << b % INTBITS;
+}
+
+static void
+setbit (unsigned b, charclass c)
+{
+ c[b / INTBITS] |= 1 << b % INTBITS;
+}
+
+static void
+clrbit (unsigned b, charclass c)
+{
+ c[b / INTBITS] &= ~(1 << b % INTBITS);
+}
+
+static void
+copyset (charclass src, charclass dst)
+{
+ memcpy (dst, src, sizeof (charclass));
+}
+
+static void
+zeroset (charclass s)
+{
+ memset (s, 0, sizeof (charclass));
+}
+
+static void
+notset (charclass s)
+{
+ int i;
+
+ for (i = 0; i < CHARCLASS_INTS; ++i)
+ s[i] = ~s[i];
+}
+
+static int
+equal (charclass s1, charclass s2)
+{
+ return memcmp (s1, s2, sizeof (charclass)) == 0;
+}
+
+/* A pointer to the current dfa is kept here during parsing. */
+static struct dfa *dfa;
+
+/* Find the index of charclass s in dfa->charclasses, or allocate a new charclass. */
+static int
+charclass_index (charclass s)
+{
+ int i;
+
+ for (i = 0; i < dfa->cindex; ++i)
+ if (equal(s, dfa->charclasses[i]))
+ return i;
+ REALLOC_IF_NECESSARY(dfa->charclasses, charclass, dfa->calloc, dfa->cindex);
+ ++dfa->cindex;
+ copyset(s, dfa->charclasses[i]);
+ return i;
+}
+
+/* Syntax bits controlling the behavior of the lexical analyzer. */
+static reg_syntax_t syntax_bits, syntax_bits_set;
+
+/* Flag for case-folding letters into sets. */
+static int case_fold;
+
+/* End-of-line byte in data. */
+static unsigned char eolbyte;
+
+/* Entry point to set syntax options. */
+void
+dfasyntax (reg_syntax_t bits, int fold, unsigned char eol)
+{
+ syntax_bits_set = 1;
+ syntax_bits = bits;
+ case_fold = fold;
+ eolbyte = eol;
+}
+
+/* Like setbit, but if case is folded, set both cases of a letter. */
+static void
+setbit_case_fold (unsigned b, charclass c)
+{
+ setbit (b, c);
+ if (case_fold)
+ {
+ if (ISUPPER (b))
+ setbit (tolower (b), c);
+ else if (ISLOWER (b))
+ setbit (toupper (b), c);
+ }
+}
+
+/* Lexical analyzer. All the dross that deals with the obnoxious
+ GNU Regex syntax bits is located here. The poor, suffering
+ reader is referred to the GNU Regex documentation for the
+ meaning of the @#%!@#%^!@ syntax bits. */
+
+static char const *lexptr; /* Pointer to next input character. */
+static int lexleft; /* Number of characters remaining. */
+static token lasttok; /* Previous token returned; initially END. */
+static int laststart; /* True if we're separated from beginning or (, |
+ only by zero-width characters. */
+static int parens; /* Count of outstanding left parens. */
+static int minrep, maxrep; /* Repeat counts for {m,n}. */
+static int hard_LC_COLLATE; /* Nonzero if LC_COLLATE is hard. */
+
+#ifdef MBS_SUPPORT
+/* These variables are used only if (MB_CUR_MAX > 1). */
+static mbstate_t mbs; /* Mbstate for mbrlen(). */
+static int cur_mb_len; /* Byte length of the current scanning
+ multibyte character. */
+static int cur_mb_index; /* Byte index of the current scanning multibyte
+ character.
+
+ single byte character : cur_mb_index = 0
+ multibyte character
+ 1st byte : cur_mb_index = 1
+ 2nd byte : cur_mb_index = 2
+ ...
+ nth byte : cur_mb_index = n */
+static unsigned char *mblen_buf;/* Correspond to the input buffer in dfaexec().
+ Each element store the amount of remain
+ byte of corresponding multibyte character
+ in the input string. A element's value
+ is 0 if corresponding character is a
+ single byte chracter.
+ e.g. input : 'a', <mb(0)>, <mb(1)>, <mb(2)>
+ mblen_buf : 0, 3, 2, 1
+ */
+static wchar_t *inputwcs; /* Wide character representation of input
+ string in dfaexec().
+ The length of this array is same as
+ the length of input string(char array).
+ inputstring[i] is a single-byte char,
+ or 1st byte of a multibyte char.
+ And inputwcs[i] is the codepoint. */
+static unsigned char const *buf_begin; /* reference to begin in dfaexec(). */
+static unsigned char const *buf_end; /* reference to end in dfaexec(). */
+#endif /* MBS_SUPPORT */
+
+#ifdef MBS_SUPPORT
+/* This function update cur_mb_len, and cur_mb_index.
+ p points current lexptr, len is the remaining buffer length. */
+static void
+update_mb_len_index (unsigned char const *p, int len)
+{
+ /* If last character is a part of a multibyte character,
+ we update cur_mb_index. */
+ if (cur_mb_index)
+ cur_mb_index = (cur_mb_index >= cur_mb_len)? 0
+ : cur_mb_index + 1;
+
+ /* If last character is a single byte character, or the
+ last portion of a multibyte character, we check whether
+ next character is a multibyte character or not. */
+ if (! cur_mb_index)
+ {
+ cur_mb_len = mbrlen(p, len, &mbs);
+ if (cur_mb_len > 1)
+ /* It is a multibyte character.
+ cur_mb_len was already set by mbrlen(). */
+ cur_mb_index = 1;
+ else if (cur_mb_len < 1)
+ /* Invalid sequence. We treat it as a single byte character.
+ cur_mb_index is aleady 0. */
+ cur_mb_len = 1;
+ /* Otherwise, cur_mb_len == 1, it is a single byte character.
+ cur_mb_index is aleady 0. */
+ }
+}
+#endif /* MBS_SUPPORT */
+
+#ifdef MBS_SUPPORT
+/* Note that characters become unsigned here. */
+# define FETCH(c, eoferr) \
+ { \
+ if (! lexleft) \
+ { \
+ if (eoferr != 0) \
+ dfaerror (eoferr); \
+ else \
+ return lasttok = END; \
+ } \
+ if (MB_CUR_MAX > 1) \
+ update_mb_len_index(lexptr, lexleft); \
+ (c) = (unsigned char) *lexptr++; \
+ --lexleft; \
+ }
+
+/* This function fetch a wide character, and update cur_mb_len,
+ used only if the current locale is a multibyte environment. */
+static wint_t
+fetch_wc (char const *eoferr)
+{
+ wchar_t wc;
+ if (! lexleft)
+ {
+ if (eoferr != 0)
+ dfaerror (eoferr);
+ else
+ return WEOF;
+ }
+
+ cur_mb_len = mbrtowc(&wc, lexptr, lexleft, &mbs);
+ if (cur_mb_len <= 0)
+ {
+ cur_mb_len = 1;
+ wc = *lexptr;
+ }
+ lexptr += cur_mb_len;
+ lexleft -= cur_mb_len;
+ return wc;
+}
+#else
+/* Note that characters become unsigned here. */
+# define FETCH(c, eoferr) \
+ { \
+ if (! lexleft) \
+ { \
+ if (eoferr != 0) \
+ dfaerror (eoferr); \
+ else \
+ return lasttok = END; \
+ } \
+ (c) = (unsigned char) *lexptr++; \
+ --lexleft; \
+ }
+#endif /* MBS_SUPPORT */
+
+#ifdef MBS_SUPPORT
+/* Multibyte character handling sub-routine for lex.
+ This function parse a bracket expression and build a struct
+ mb_char_classes. */
+static void
+parse_bracket_exp_mb ()
+{
+ wint_t wc, wc1, wc2;
+
+ /* Work area to build a mb_char_classes. */
+ struct mb_char_classes *work_mbc;
+ int chars_al, range_sts_al, range_ends_al, ch_classes_al,
+ equivs_al, coll_elems_al;
+
+ REALLOC_IF_NECESSARY(dfa->mbcsets, struct mb_char_classes,
+ dfa->mbcsets_alloc, dfa->nmbcsets + 1);
+ /* dfa->multibyte_prop[] hold the index of dfa->mbcsets.
+ We will update dfa->multibyte_prop[] in addtok(), because we can't
+ decide the index in dfa->tokens[]. */
+
+ /* Initialize work are */
+ work_mbc = &(dfa->mbcsets[dfa->nmbcsets++]);
+
+ chars_al = 1;
+ range_sts_al = range_ends_al = 0;
+ ch_classes_al = equivs_al = coll_elems_al = 0;
+ MALLOC(work_mbc->chars, wchar_t, chars_al);
+
+ work_mbc->nchars = work_mbc->nranges = work_mbc->nch_classes = 0;
+ work_mbc->nequivs = work_mbc->ncoll_elems = 0;
+ work_mbc->chars = NULL;
+ work_mbc->ch_classes = NULL;
+ work_mbc->range_sts = work_mbc->range_ends = NULL;
+ work_mbc->equivs = work_mbc->coll_elems = NULL;
+
+ wc = fetch_wc(_("Unbalanced ["));
+ if (wc == L'^')
+ {
+ wc = fetch_wc(_("Unbalanced ["));
+ work_mbc->invert = 1;
+ }
+ else
+ work_mbc->invert = 0;
+ do
+ {
+ wc1 = WEOF; /* mark wc1 is not initialized". */
+
+ /* Note that if we're looking at some other [:...:] construct,
+ we just treat it as a bunch of ordinary characters. We can do
+ this because we assume regex has checked for syntax errors before
+ dfa is ever called. */
+ if (wc == L'[' && (syntax_bits & RE_CHAR_CLASSES))
+ {
+#define BRACKET_BUFFER_SIZE 128
+ char str[BRACKET_BUFFER_SIZE];
+ wc1 = wc;
+ wc = fetch_wc(_("Unbalanced ["));
+
+ /* If pattern contains `[[:', `[[.', or `[[='. */
+ if (cur_mb_len == 1 && (wc == L':' || wc == L'.' || wc == L'='))
+ {
+ unsigned char c;
+ unsigned char delim = (unsigned char)wc;
+ int len = 0;
+ for (;;)
+ {
+ if (! lexleft)
+ dfaerror (_("Unbalanced ["));
+ c = (unsigned char) *lexptr++;
+ --lexleft;
+
+ if ((c == delim && *lexptr == ']') || lexleft == 0)
+ break;
+ if (len < BRACKET_BUFFER_SIZE)
+ str[len++] = c;
+ else
+ /* This is in any case an invalid class name. */
+ str[0] = '\0';
+ }
+ str[len] = '\0';
+
+ if (lexleft == 0)
+ {
+ REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al,
+ work_mbc->nchars + 2);
+ work_mbc->chars[work_mbc->nchars++] = L'[';
+ work_mbc->chars[work_mbc->nchars++] = delim;
+ break;
+ }
+
+ if (--lexleft, *lexptr++ != ']')
+ dfaerror (_("Unbalanced ["));
+ if (delim == ':')
+ /* build character class. */
+ {
+ wctype_t wt;
+ /* Query the character class as wctype_t. */
+ if (case_fold && (strcmp(str, "upper") == 0 || strcmp(str, "lower") == 0))
+ strcpy(str, "alpha");
+
+ wt = wctype (str);
+
+ if (ch_classes_al == 0)
+ MALLOC(work_mbc->ch_classes, wctype_t, ++ch_classes_al);
+ REALLOC_IF_NECESSARY(work_mbc->ch_classes, wctype_t,
+ ch_classes_al,
+ work_mbc->nch_classes + 1);
+ work_mbc->ch_classes[work_mbc->nch_classes++] = wt;
+
+ }
+ else if (delim == '=' || delim == '.')
+ {
+ char *elem;
+ MALLOC(elem, char, len + 1);
+ strncpy(elem, str, len + 1);
+
+ if (delim == '=')
+ /* build equivalent class. */
+ {
+ if (equivs_al == 0)
+ MALLOC(work_mbc->equivs, char*, ++equivs_al);
+ REALLOC_IF_NECESSARY(work_mbc->equivs, char*,
+ equivs_al,
+ work_mbc->nequivs + 1);
+ work_mbc->equivs[work_mbc->nequivs++] = elem;
+ }
+
+ if (delim == '.')
+ /* build collating element. */
+ {
+ if (coll_elems_al == 0)
+ MALLOC(work_mbc->coll_elems, char*, ++coll_elems_al);
+ REALLOC_IF_NECESSARY(work_mbc->coll_elems, char*,
+ coll_elems_al,
+ work_mbc->ncoll_elems + 1);
+ work_mbc->coll_elems[work_mbc->ncoll_elems++] = elem;
+ }
+ }
+ wc = wc1 = WEOF;
+ }
+ else
+ /* We treat '[' as a normal character here. */
+ {
+ wc2 = wc1; wc1 = wc; wc = wc2; /* swap */
+ }
+ }
+ else
+ {
+ if (wc == L'\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
+ wc = fetch_wc(("Unbalanced ["));
+ }
+
+ if (wc1 == WEOF)
+ wc1 = fetch_wc(_("Unbalanced ["));
+
+ if (wc1 == L'-')
+ /* build range characters. */
+ {
+ wc2 = fetch_wc(_("Unbalanced ["));
+ if (wc2 == L']')
+ {
+ /* In the case [x-], the - is an ordinary hyphen,
+ which is left in c1, the lookahead character. */
+ lexptr -= cur_mb_len;
+ lexleft += cur_mb_len;
+ wc2 = wc;
+ }
+ else
+ {
+ if (wc2 == L'\\'
+ && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
+ wc2 = fetch_wc(_("Unbalanced ["));
+ wc1 = fetch_wc(_("Unbalanced ["));
+ }
+
+ if (range_sts_al == 0)
+ {
+ MALLOC(work_mbc->range_sts, wchar_t, ++range_sts_al);
+ MALLOC(work_mbc->range_ends, wchar_t, ++range_ends_al);
+ }
+ REALLOC_IF_NECESSARY(work_mbc->range_sts, wchar_t,
+ range_sts_al, work_mbc->nranges + 1);
+ work_mbc->range_sts[work_mbc->nranges] = (wchar_t)wc;
+ REALLOC_IF_NECESSARY(work_mbc->range_ends, wchar_t,
+ range_ends_al, work_mbc->nranges + 1);
+ work_mbc->range_ends[work_mbc->nranges++] = (wchar_t)wc2;
+ if (case_fold && (iswlower((wint_t)wc) || iswupper((wint_t)wc))
+ && (iswlower((wint_t)wc2) || iswupper((wint_t)wc2)))
+ {
+ wint_t altcase;
+ altcase = wc;
+ if (iswlower((wint_t)wc))
+ altcase = towupper((wint_t)wc);
+ else
+ altcase = towlower((wint_t)wc);
+ REALLOC_IF_NECESSARY(work_mbc->range_sts, wchar_t,
+ range_sts_al, work_mbc->nranges + 1);
+ work_mbc->range_sts[work_mbc->nranges] = (wchar_t)altcase;
+
+ altcase = wc2;
+ if (iswlower((wint_t)wc2))
+ altcase = towupper((wint_t)wc2);
+ else
+ altcase = towlower((wint_t)wc2);
+ REALLOC_IF_NECESSARY(work_mbc->range_ends, wchar_t,
+ range_ends_al, work_mbc->nranges + 1);
+ work_mbc->range_ends[work_mbc->nranges++] = (wchar_t)altcase;
+ }
+ }
+ else if (wc != WEOF)
+ /* build normal characters. */
+ {
+ REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al,
+ work_mbc->nchars + 1);
+ work_mbc->chars[work_mbc->nchars++] = (wchar_t)wc;
+ if (case_fold && (iswlower(wc) || iswupper(wc)))
+ {
+ REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al,
+ work_mbc->nchars + 1);
+ work_mbc->chars[work_mbc->nchars++] =
+ (wchar_t) (iswlower(wc) ? towupper(wc) : towlower(wc));
+ }
+ }
+ }
+ while ((wc = wc1) != L']');
+}
+#endif /* MBS_SUPPORT */
+
+#ifdef __STDC__
+#define FUNC(F, P) static int F(int c) { return P(c); }
+#else
+#define FUNC(F, P) static int F(c) int c; { return P(c); }
+#endif
+
+FUNC(is_alpha, ISALPHA)
+FUNC(is_upper, ISUPPER)
+FUNC(is_lower, ISLOWER)
+FUNC(is_digit, ISDIGIT)
+FUNC(is_xdigit, ISXDIGIT)
+FUNC(is_space, ISSPACE)
+FUNC(is_punct, ISPUNCT)
+FUNC(is_alnum, ISALNUM)
+FUNC(is_print, ISPRINT)
+FUNC(is_graph, ISGRAPH)
+FUNC(is_cntrl, ISCNTRL)
+
+static int
+is_blank (int c)
+{
+ return (c == ' ' || c == '\t');
+}
+
+/* The following list maps the names of the Posix named character classes
+ to predicate functions that determine whether a given character is in
+ the class. The leading [ has already been eaten by the lexical analyzer. */
+static struct {
+ const char *name;
+ int (*pred) PARAMS ((int));
+} const prednames[] = {
+ { ":alpha:]", is_alpha },
+ { ":upper:]", is_upper },
+ { ":lower:]", is_lower },
+ { ":digit:]", is_digit },
+ { ":xdigit:]", is_xdigit },
+ { ":space:]", is_space },
+ { ":punct:]", is_punct },
+ { ":alnum:]", is_alnum },
+ { ":print:]", is_print },
+ { ":graph:]", is_graph },
+ { ":cntrl:]", is_cntrl },
+ { ":blank:]", is_blank },
+ { 0 }
+};
+
+/* Return non-zero if C is a `word-constituent' byte; zero otherwise. */
+#define IS_WORD_CONSTITUENT(C) (ISALNUM(C) || (C) == '_')
+
+static int
+looking_at (char const *s)
+{
+ size_t len;
+
+ len = strlen(s);
+ if (lexleft < len)
+ return 0;
+ return strncmp(s, lexptr, len) == 0;
+}
+
+static token
+lex (void)
+{
+ unsigned c, c1, c2;
+ int backslash = 0, invert;
+ charclass ccl;
+ int i;
+
+ /* Basic plan: We fetch a character. If it's a backslash,
+ we set the backslash flag and go through the loop again.
+ On the plus side, this avoids having a duplicate of the
+ main switch inside the backslash case. On the minus side,
+ it means that just about every case begins with
+ "if (backslash) ...". */
+ for (i = 0; i < 2; ++i)
+ {
+ FETCH(c, 0);
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1 && cur_mb_index)
+ /* If this is a part of a multi-byte character, we must treat
+ this byte data as a normal character.
+ e.g. In case of SJIS encoding, some character contains '\',
+ but they must not be backslash. */
+ goto normal_char;
+#endif /* MBS_SUPPORT */
+ switch (c)
+ {
+ case '\\':
+ if (backslash)
+ goto normal_char;
+ if (lexleft == 0)
+ dfaerror(_("Unfinished \\ escape"));
+ backslash = 1;
+ break;
+
+ case '^':
+ if (backslash)
+ goto normal_char;
+ if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS
+ || lasttok == END
+ || lasttok == LPAREN
+ || lasttok == OR)
+ return lasttok = BEGLINE;
+ goto normal_char;
+
+ case '$':
+ if (backslash)
+ goto normal_char;
+ if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS
+ || lexleft == 0
+ || (syntax_bits & RE_NO_BK_PARENS
+ ? lexleft > 0 && *lexptr == ')'
+ : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == ')')
+ || (syntax_bits & RE_NO_BK_VBAR
+ ? lexleft > 0 && *lexptr == '|'
+ : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == '|')
+ || ((syntax_bits & RE_NEWLINE_ALT)
+ && lexleft > 0 && *lexptr == '\n'))
+ return lasttok = ENDLINE;
+ goto normal_char;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (backslash && !(syntax_bits & RE_NO_BK_REFS))
+ {
+ laststart = 0;
+ return lasttok = BACKREF;
+ }
+ goto normal_char;
+
+ case '`':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = BEGLINE; /* FIXME: should be beginning of string */
+ goto normal_char;
+
+ case '\'':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = ENDLINE; /* FIXME: should be end of string */
+ goto normal_char;
+
+ case '<':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = BEGWORD;
+ goto normal_char;
+
+ case '>':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = ENDWORD;
+ goto normal_char;
+
+ case 'b':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = LIMWORD;
+ goto normal_char;
+
+ case 'B':
+ if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
+ return lasttok = NOTLIMWORD;
+ goto normal_char;
+
+ case '?':
+ if (syntax_bits & RE_LIMITED_OPS)
+ goto normal_char;
+ if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0))
+ goto normal_char;
+ if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart)
+ goto normal_char;
+ return lasttok = QMARK;
+
+ case '*':
+ if (backslash)
+ goto normal_char;
+ if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart)
+ goto normal_char;
+ return lasttok = STAR;
+
+ case '+':
+ if (syntax_bits & RE_LIMITED_OPS)
+ goto normal_char;
+ if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0))
+ goto normal_char;
+ if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart)
+ goto normal_char;
+ return lasttok = PLUS;
+
+ case '{':
+ if (!(syntax_bits & RE_INTERVALS))
+ goto normal_char;
+ if (backslash != ((syntax_bits & RE_NO_BK_BRACES) == 0))
+ goto normal_char;
+ if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart)
+ goto normal_char;
+
+ if (syntax_bits & RE_NO_BK_BRACES)
+ {
+ /* Scan ahead for a valid interval; if it's not valid,
+ treat it as a literal '{'. */
+ int lo = -1, hi = -1;
+ char const *p = lexptr;
+ char const *lim = p + lexleft;
+ for (; p != lim && ISASCIIDIGIT (*p); p++)
+ lo = (lo < 0 ? 0 : lo * 10) + *p - '0';
+ if (p != lim && *p == ',')
+ while (++p != lim && ISASCIIDIGIT (*p))
+ hi = (hi < 0 ? 0 : hi * 10) + *p - '0';
+ else
+ hi = lo;
+ if (p == lim || *p != '}'
+ || lo < 0 || RE_DUP_MAX < hi || (0 <= hi && hi < lo))
+ goto normal_char;
+ }
+
+ minrep = 0;
+ /* Cases:
+ {M} - exact count
+ {M,} - minimum count, maximum is infinity
+ {M,N} - M through N */
+ FETCH(c, _("unfinished repeat count"));
+ if (ISASCIIDIGIT (c))
+ {
+ minrep = c - '0';
+ for (;;)
+ {
+ FETCH(c, _("unfinished repeat count"));
+ if (! ISASCIIDIGIT (c))
+ break;
+ minrep = 10 * minrep + c - '0';
+ }
+ }
+ else
+ dfaerror(_("malformed repeat count"));
+ if (c == ',')
+ {
+ FETCH (c, _("unfinished repeat count"));
+ if (! ISASCIIDIGIT (c))
+ maxrep = -1;
+ else
+ {
+ maxrep = c - '0';
+ for (;;)
+ {
+ FETCH (c, _("unfinished repeat count"));
+ if (! ISASCIIDIGIT (c))
+ break;
+ maxrep = 10 * maxrep + c - '0';
+ }
+ if (0 <= maxrep && maxrep < minrep)
+ dfaerror (_("malformed repeat count"));
+ }
+ }
+ else
+ maxrep = minrep;
+ if (!(syntax_bits & RE_NO_BK_BRACES))
+ {
+ if (c != '\\')
+ dfaerror(_("malformed repeat count"));
+ FETCH(c, _("unfinished repeat count"));
+ }
+ if (c != '}')
+ dfaerror(_("malformed repeat count"));
+ laststart = 0;
+ return lasttok = REPMN;
+
+ case '|':
+ if (syntax_bits & RE_LIMITED_OPS)
+ goto normal_char;
+ if (backslash != ((syntax_bits & RE_NO_BK_VBAR) == 0))
+ goto normal_char;
+ laststart = 1;
+ return lasttok = OR;
+
+ case '\n':
+ if (syntax_bits & RE_LIMITED_OPS
+ || backslash
+ || !(syntax_bits & RE_NEWLINE_ALT))
+ goto normal_char;
+ laststart = 1;
+ return lasttok = OR;
+
+ case '(':
+ if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0))
+ goto normal_char;
+ ++parens;
+ laststart = 1;
+ return lasttok = LPAREN;
+
+ case ')':
+ if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0))
+ goto normal_char;
+ if (parens == 0 && syntax_bits & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ --parens;
+ laststart = 0;
+ return lasttok = RPAREN;
+
+ case '.':
+ if (backslash)
+ goto normal_char;
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ /* In multibyte environment period must match with a single
+ character not a byte. So we use ANYCHAR. */
+ laststart = 0;
+ return lasttok = ANYCHAR;
+ }
+#endif /* MBS_SUPPORT */
+ zeroset(ccl);
+ notset(ccl);
+ if (!(syntax_bits & RE_DOT_NEWLINE))
+ clrbit(eolbyte, ccl);
+ if (syntax_bits & RE_DOT_NOT_NULL)
+ clrbit('\0', ccl);
+ laststart = 0;
+ return lasttok = CSET + charclass_index(ccl);
+
+#ifndef GAWK
+ case 's':
+ case 'S':
+ if (!backslash || (syntax_bits & RE_NO_GNU_OPS))
+ goto normal_char;
+ zeroset(ccl);
+ for (c2 = 0; c2 < NOTCHAR; ++c2)
+ if (ISSPACE(c2))
+ setbit(c2, ccl);
+ if (c == 'S')
+ notset(ccl);
+ laststart = 0;
+ return lasttok = CSET + charclass_index(ccl);
+#endif
+
+ case 'w':
+ case 'W':
+ if (!backslash || (syntax_bits & RE_NO_GNU_OPS))
+ goto normal_char;
+ zeroset(ccl);
+ for (c2 = 0; c2 < NOTCHAR; ++c2)
+ if (IS_WORD_CONSTITUENT(c2))
+ setbit(c2, ccl);
+ if (c == 'W')
+ notset(ccl);
+ laststart = 0;
+ return lasttok = CSET + charclass_index(ccl);
+
+ case '[':
+ if (backslash)
+ goto normal_char;
+ laststart = 0;
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ /* In multibyte environment a bracket expression may contain
+ multibyte characters, which must be treated as characters
+ (not bytes). So we parse it by parse_bracket_exp_mb(). */
+ parse_bracket_exp_mb();
+ return lasttok = MBCSET;
+ }
+#endif
+ zeroset(ccl);
+ FETCH(c, _("Unbalanced ["));
+ if (c == '^')
+ {
+ FETCH(c, _("Unbalanced ["));
+ invert = 1;
+ }
+ else
+ invert = 0;
+ do
+ {
+ /* Nobody ever said this had to be fast. :-)
+ Note that if we're looking at some other [:...:]
+ construct, we just treat it as a bunch of ordinary
+ characters. We can do this because we assume
+ regex has checked for syntax errors before
+ dfa is ever called. */
+ if (c == '[' && (syntax_bits & RE_CHAR_CLASSES))
+ for (c1 = 0; prednames[c1].name; ++c1)
+ if (looking_at(prednames[c1].name))
+ {
+ int (*pred) PARAMS ((int)) = prednames[c1].pred;
+
+ for (c2 = 0; c2 < NOTCHAR; ++c2)
+ if ((*pred)(c2))
+ setbit_case_fold (c2, ccl);
+ lexptr += strlen(prednames[c1].name);
+ lexleft -= strlen(prednames[c1].name);
+ FETCH(c1, _("Unbalanced ["));
+ goto skip;
+ }
+ if (c == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
+ FETCH(c, _("Unbalanced ["));
+ FETCH(c1, _("Unbalanced ["));
+ if (c1 == '-')
+ {
+ FETCH(c2, _("Unbalanced ["));
+ if (c2 == ']')
+ {
+ /* In the case [x-], the - is an ordinary hyphen,
+ which is left in c1, the lookahead character. */
+ --lexptr;
+ ++lexleft;
+ }
+ else
+ {
+ if (c2 == '\\'
+ && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
+ FETCH(c2, _("Unbalanced ["));
+ FETCH(c1, _("Unbalanced ["));
+ if (!hard_LC_COLLATE) {
+ for (; c <= c2; c++)
+ setbit_case_fold (c, ccl);
+ } else {
+ /* POSIX locales are painful - leave the decision to libc */
+ regex_t re;
+ char expr[6]; /* = { '[', c, '-', c2, ']', '\0' }; */
+
+ expr[0] = '['; expr[1] = c; expr[2] = '-';
+ expr[3] = c2; expr[4] = ']'; expr[5] = '\0';
+ if (regcomp (&re, expr, case_fold ? REG_ICASE : 0) == REG_NOERROR) {
+ for (c = 0; c < NOTCHAR; ++c) {
+ regmatch_t mat;
+ char buf[2]; /* = { c, '\0' }; */
+
+ buf[0] = c; buf[1] = '\0';
+ if (regexec (&re, buf, 1, &mat, 0) == REG_NOERROR
+ && mat.rm_so == 0 && mat.rm_eo == 1)
+ setbit_case_fold (c, ccl);
+ }
+ regfree (&re);
+ }
+ }
+ continue;
+ }
+ }
+
+ setbit_case_fold (c, ccl);
+
+ skip:
+ ;
+ }
+ while ((c = c1) != ']');
+ if (invert)
+ {
+ notset(ccl);
+ if (syntax_bits & RE_HAT_LISTS_NOT_NEWLINE)
+ clrbit(eolbyte, ccl);
+ }
+ return lasttok = CSET + charclass_index(ccl);
+
+ default:
+ normal_char:
+ laststart = 0;
+ if (case_fold && ISALPHA(c))
+ {
+ zeroset(ccl);
+ setbit_case_fold (c, ccl);
+ return lasttok = CSET + charclass_index(ccl);
+ }
+ return lasttok = c;
+ }
+ }
+
+ /* The above loop should consume at most a backslash
+ and some other character. */
+ abort();
+ return END; /* keeps pedantic compilers happy. */
+}
+
+/* Recursive descent parser for regular expressions. */
+
+static token tok; /* Lookahead token. */
+static int depth; /* Current depth of a hypothetical stack
+ holding deferred productions. This is
+ used to determine the depth that will be
+ required of the real stack later on in
+ dfaanalyze(). */
+
+/* Add the given token to the parse tree, maintaining the depth count and
+ updating the maximum depth if necessary. */
+static void
+addtok (token t)
+{
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ REALLOC_IF_NECESSARY(dfa->multibyte_prop, int, dfa->nmultibyte_prop,
+ dfa->tindex);
+ /* Set dfa->multibyte_prop. See struct dfa in dfa.h. */
+ if (t == MBCSET)
+ dfa->multibyte_prop[dfa->tindex] = ((dfa->nmbcsets - 1) << 2) + 3;
+ else if (t < NOTCHAR)
+ dfa->multibyte_prop[dfa->tindex]
+ = (cur_mb_len == 1)? 3 /* single-byte char */
+ : (((cur_mb_index == 1)? 1 : 0) /* 1st-byte of multibyte char */
+ + ((cur_mb_index == cur_mb_len)? 2 : 0)); /* last-byte */
+ else
+ /* It may be unnecessary, but it is safer to treat other
+ symbols as single byte characters. */
+ dfa->multibyte_prop[dfa->tindex] = 3;
+ }
+#endif
+
+ REALLOC_IF_NECESSARY(dfa->tokens, token, dfa->talloc, dfa->tindex);
+ dfa->tokens[dfa->tindex++] = t;
+
+ switch (t)
+ {
+ case QMARK:
+ case STAR:
+ case PLUS:
+ break;
+
+ case CAT:
+ case OR:
+ case ORTOP:
+ --depth;
+ break;
+
+ default:
+ ++dfa->nleaves;
+ case EMPTY:
+ ++depth;
+ break;
+ }
+ if (depth > dfa->depth)
+ dfa->depth = depth;
+}
+
+/* The grammar understood by the parser is as follows.
+
+ regexp:
+ regexp OR branch
+ branch
+
+ branch:
+ branch closure
+ closure
+
+ closure:
+ closure QMARK
+ closure STAR
+ closure PLUS
+ closure REPMN
+ atom
+
+ atom:
+ <normal character>
+ <multibyte character>
+ ANYCHAR
+ MBCSET
+ CSET
+ BACKREF
+ BEGLINE
+ ENDLINE
+ BEGWORD
+ ENDWORD
+ LIMWORD
+ NOTLIMWORD
+ CRANGE
+ LPAREN regexp RPAREN
+ <empty>
+
+ The parser builds a parse tree in postfix form in an array of tokens. */
+
+static void
+atom (void)
+{
+ if ((tok >= 0 && tok < NOTCHAR) || tok >= CSET || tok == BACKREF
+ || tok == BEGLINE || tok == ENDLINE || tok == BEGWORD
+#ifdef MBS_SUPPORT
+ || tok == ANYCHAR || tok == MBCSET /* MB_CUR_MAX > 1 */
+#endif /* MBS_SUPPORT */
+ || tok == ENDWORD || tok == LIMWORD || tok == NOTLIMWORD)
+ {
+ addtok(tok);
+ tok = lex();
+#ifdef MBS_SUPPORT
+ /* We treat a multibyte character as a single atom, so that DFA
+ can treat a multibyte character as a single expression.
+
+ e.g. We construct following tree from "<mb1><mb2>".
+ <mb1(1st-byte)><mb1(2nd-byte)><CAT><mb1(3rd-byte)><CAT>
+ <mb2(1st-byte)><mb2(2nd-byte)><CAT><mb2(3rd-byte)><CAT><CAT>
+ */
+ if (MB_CUR_MAX > 1)
+ {
+ while (cur_mb_index > 1 && tok >= 0 && tok < NOTCHAR)
+ {
+ addtok(tok);
+ addtok(CAT);
+ tok = lex();
+ }
+ }
+#endif /* MBS_SUPPORT */
+ }
+ else if (tok == CRANGE)
+ {
+ /* A character range like "[a-z]" in a locale other than "C" or
+ "POSIX". This range might any sequence of one or more
+ characters. Unfortunately the POSIX locale primitives give
+ us no practical way to find what character sequences might be
+ matched. Treat this approximately like "(.\1)" -- i.e. match
+ one character, and then punt to the full matcher. */
+ charclass ccl;
+ zeroset (ccl);
+ notset (ccl);
+ addtok (CSET + charclass_index (ccl));
+ addtok (BACKREF);
+ addtok (CAT);
+ tok = lex ();
+ }
+ else if (tok == LPAREN)
+ {
+ tok = lex();
+ regexp(0);
+ if (tok != RPAREN)
+ dfaerror(_("Unbalanced ("));
+ tok = lex();
+ }
+ else
+ addtok(EMPTY);
+}
+
+/* Return the number of tokens in the given subexpression. */
+static int
+nsubtoks (int tindex)
+{
+ int ntoks1;
+
+ switch (dfa->tokens[tindex - 1])
+ {
+ default:
+ return 1;
+ case QMARK:
+ case STAR:
+ case PLUS:
+ return 1 + nsubtoks(tindex - 1);
+ case CAT:
+ case OR:
+ case ORTOP:
+ ntoks1 = nsubtoks(tindex - 1);
+ return 1 + ntoks1 + nsubtoks(tindex - 1 - ntoks1);
+ }
+}
+
+/* Copy the given subexpression to the top of the tree. */
+static void
+copytoks (int tindex, int ntokens)
+{
+ int i;
+
+ for (i = 0; i < ntokens; ++i)
+ addtok(dfa->tokens[tindex + i]);
+}
+
+static void
+closure (void)
+{
+ int tindex, ntokens, i;
+
+ atom();
+ while (tok == QMARK || tok == STAR || tok == PLUS || tok == REPMN)
+ if (tok == REPMN)
+ {
+ ntokens = nsubtoks(dfa->tindex);
+ tindex = dfa->tindex - ntokens;
+ if (maxrep < 0)
+ addtok(PLUS);
+ if (minrep == 0)
+ addtok(QMARK);
+ for (i = 1; i < minrep; ++i)
+ {
+ copytoks(tindex, ntokens);
+ addtok(CAT);
+ }
+ for (; i < maxrep; ++i)
+ {
+ copytoks(tindex, ntokens);
+ addtok(QMARK);
+ addtok(CAT);
+ }
+ tok = lex();
+ }
+ else
+ {
+ addtok(tok);
+ tok = lex();
+ }
+}
+
+static void
+branch (void)
+{
+ closure();
+ while (tok != RPAREN && tok != OR && tok >= 0)
+ {
+ closure();
+ addtok(CAT);
+ }
+}
+
+static void
+regexp (int toplevel)
+{
+ branch();
+ while (tok == OR)
+ {
+ tok = lex();
+ branch();
+ if (toplevel)
+ addtok(ORTOP);
+ else
+ addtok(OR);
+ }
+}
+
+/* Main entry point for the parser. S is a string to be parsed, len is the
+ length of the string, so s can include NUL characters. D is a pointer to
+ the struct dfa to parse into. */
+void
+dfaparse (char const *s, size_t len, struct dfa *d)
+{
+ dfa = d;
+ lexptr = s;
+ lexleft = len;
+ lasttok = END;
+ laststart = 1;
+ parens = 0;
+#ifdef LC_COLLATE
+ hard_LC_COLLATE = hard_locale (LC_COLLATE);
+#endif
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ cur_mb_index = 0;
+ cur_mb_len = 0;
+ memset(&mbs, 0, sizeof(mbstate_t));
+ }
+#endif /* MBS_SUPPORT */
+
+ if (! syntax_bits_set)
+ dfaerror(_("No syntax specified"));
+
+ tok = lex();
+ depth = d->depth;
+
+ regexp(1);
+
+ if (tok != END)
+ dfaerror(_("Unbalanced )"));
+
+ addtok(END - d->nregexps);
+ addtok(CAT);
+
+ if (d->nregexps)
+ addtok(ORTOP);
+
+ ++d->nregexps;
+}
+
+/* Some primitives for operating on sets of positions. */
+
+/* Copy one set to another; the destination must be large enough. */
+static void
+copy (position_set const *src, position_set *dst)
+{
+ int i;
+
+ for (i = 0; i < src->nelem; ++i)
+ dst->elems[i] = src->elems[i];
+ dst->nelem = src->nelem;
+}
+
+/* Insert a position in a set. Position sets are maintained in sorted
+ order according to index. If position already exists in the set with
+ the same index then their constraints are logically or'd together.
+ S->elems must point to an array large enough to hold the resulting set. */
+static void
+insert (position p, position_set *s)
+{
+ int i;
+ position t1, t2;
+
+ for (i = 0; i < s->nelem && p.index < s->elems[i].index; ++i)
+ continue;
+ if (i < s->nelem && p.index == s->elems[i].index)
+ s->elems[i].constraint |= p.constraint;
+ else
+ {
+ t1 = p;
+ ++s->nelem;
+ while (i < s->nelem)
+ {
+ t2 = s->elems[i];
+ s->elems[i++] = t1;
+ t1 = t2;
+ }
+ }
+}
+
+/* Merge two sets of positions into a third. The result is exactly as if
+ the positions of both sets were inserted into an initially empty set. */
+static void
+merge (position_set const *s1, position_set const *s2, position_set *m)
+{
+ int i = 0, j = 0;
+
+ m->nelem = 0;
+ while (i < s1->nelem && j < s2->nelem)
+ if (s1->elems[i].index > s2->elems[j].index)
+ m->elems[m->nelem++] = s1->elems[i++];
+ else if (s1->elems[i].index < s2->elems[j].index)
+ m->elems[m->nelem++] = s2->elems[j++];
+ else
+ {
+ m->elems[m->nelem] = s1->elems[i++];
+ m->elems[m->nelem++].constraint |= s2->elems[j++].constraint;
+ }
+ while (i < s1->nelem)
+ m->elems[m->nelem++] = s1->elems[i++];
+ while (j < s2->nelem)
+ m->elems[m->nelem++] = s2->elems[j++];
+}
+
+/* Delete a position from a set. */
+static void
+delete (position p, position_set *s)
+{
+ int i;
+
+ for (i = 0; i < s->nelem; ++i)
+ if (p.index == s->elems[i].index)
+ break;
+ if (i < s->nelem)
+ for (--s->nelem; i < s->nelem; ++i)
+ s->elems[i] = s->elems[i + 1];
+}
+
+/* Find the index of the state corresponding to the given position set with
+ the given preceding context, or create a new state if there is no such
+ state. Newline and letter tell whether we got here on a newline or
+ letter, respectively. */
+static int
+state_index (struct dfa *d, position_set const *s, int newline, int letter)
+{
+ int hash = 0;
+ int constraint;
+ int i, j;
+
+ newline = newline ? 1 : 0;
+ letter = letter ? 1 : 0;
+
+ for (i = 0; i < s->nelem; ++i)
+ hash ^= s->elems[i].index + s->elems[i].constraint;
+
+ /* Try to find a state that exactly matches the proposed one. */
+ for (i = 0; i < d->sindex; ++i)
+ {
+ if (hash != d->states[i].hash || s->nelem != d->states[i].elems.nelem
+ || newline != d->states[i].newline || letter != d->states[i].letter)
+ continue;
+ for (j = 0; j < s->nelem; ++j)
+ if (s->elems[j].constraint
+ != d->states[i].elems.elems[j].constraint
+ || s->elems[j].index != d->states[i].elems.elems[j].index)
+ break;
+ if (j == s->nelem)
+ return i;
+ }
+
+ /* We'll have to create a new state. */
+ REALLOC_IF_NECESSARY(d->states, dfa_state, d->salloc, d->sindex);
+ d->states[i].hash = hash;
+ MALLOC(d->states[i].elems.elems, position, s->nelem);
+ copy(s, &d->states[i].elems);
+ d->states[i].newline = newline;
+ d->states[i].letter = letter;
+ d->states[i].backref = 0;
+ d->states[i].constraint = 0;
+ d->states[i].first_end = 0;
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ d->states[i].mbps.nelem = 0;
+#endif
+ for (j = 0; j < s->nelem; ++j)
+ if (d->tokens[s->elems[j].index] < 0)
+ {
+ constraint = s->elems[j].constraint;
+ if (SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 0)
+ || SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 1)
+ || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 0)
+ || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 1))
+ d->states[i].constraint |= constraint;
+ if (! d->states[i].first_end)
+ d->states[i].first_end = d->tokens[s->elems[j].index];
+ }
+ else if (d->tokens[s->elems[j].index] == BACKREF)
+ {
+ d->states[i].constraint = NO_CONSTRAINT;
+ d->states[i].backref = 1;
+ }
+
+ ++d->sindex;
+
+ return i;
+}
+
+/* Find the epsilon closure of a set of positions. If any position of the set
+ contains a symbol that matches the empty string in some context, replace
+ that position with the elements of its follow labeled with an appropriate
+ constraint. Repeat exhaustively until no funny positions are left.
+ S->elems must be large enough to hold the result. */
+static void
+epsclosure (position_set *s, struct dfa const *d)
+{
+ int i, j;
+ int *visited;
+ position p, old;
+
+ MALLOC(visited, int, d->tindex);
+ for (i = 0; i < d->tindex; ++i)
+ visited[i] = 0;
+
+ for (i = 0; i < s->nelem; ++i)
+ if (d->tokens[s->elems[i].index] >= NOTCHAR
+ && d->tokens[s->elems[i].index] != BACKREF
+#ifdef MBS_SUPPORT
+ && d->tokens[s->elems[i].index] != ANYCHAR
+ && d->tokens[s->elems[i].index] != MBCSET
+#endif
+ && d->tokens[s->elems[i].index] < CSET)
+ {
+ old = s->elems[i];
+ p.constraint = old.constraint;
+ delete(s->elems[i], s);
+ if (visited[old.index])
+ {
+ --i;
+ continue;
+ }
+ visited[old.index] = 1;
+ switch (d->tokens[old.index])
+ {
+ case BEGLINE:
+ p.constraint &= BEGLINE_CONSTRAINT;
+ break;
+ case ENDLINE:
+ p.constraint &= ENDLINE_CONSTRAINT;
+ break;
+ case BEGWORD:
+ p.constraint &= BEGWORD_CONSTRAINT;
+ break;
+ case ENDWORD:
+ p.constraint &= ENDWORD_CONSTRAINT;
+ break;
+ case LIMWORD:
+ p.constraint &= LIMWORD_CONSTRAINT;
+ break;
+ case NOTLIMWORD:
+ p.constraint &= NOTLIMWORD_CONSTRAINT;
+ break;
+ default:
+ break;
+ }
+ for (j = 0; j < d->follows[old.index].nelem; ++j)
+ {
+ p.index = d->follows[old.index].elems[j].index;
+ insert(p, s);
+ }
+ /* Force rescan to start at the beginning. */
+ i = -1;
+ }
+
+ free(visited);
+}
+
+/* Perform bottom-up analysis on the parse tree, computing various functions.
+ Note that at this point, we're pretending constructs like \< are real
+ characters rather than constraints on what can follow them.
+
+ Nullable: A node is nullable if it is at the root of a regexp that can
+ match the empty string.
+ * EMPTY leaves are nullable.
+ * No other leaf is nullable.
+ * A QMARK or STAR node is nullable.
+ * A PLUS node is nullable if its argument is nullable.
+ * A CAT node is nullable if both its arguments are nullable.
+ * An OR node is nullable if either argument is nullable.
+
+ Firstpos: The firstpos of a node is the set of positions (nonempty leaves)
+ that could correspond to the first character of a string matching the
+ regexp rooted at the given node.
+ * EMPTY leaves have empty firstpos.
+ * The firstpos of a nonempty leaf is that leaf itself.
+ * The firstpos of a QMARK, STAR, or PLUS node is the firstpos of its
+ argument.
+ * The firstpos of a CAT node is the firstpos of the left argument, union
+ the firstpos of the right if the left argument is nullable.
+ * The firstpos of an OR node is the union of firstpos of each argument.
+
+ Lastpos: The lastpos of a node is the set of positions that could
+ correspond to the last character of a string matching the regexp at
+ the given node.
+ * EMPTY leaves have empty lastpos.
+ * The lastpos of a nonempty leaf is that leaf itself.
+ * The lastpos of a QMARK, STAR, or PLUS node is the lastpos of its
+ argument.
+ * The lastpos of a CAT node is the lastpos of its right argument, union
+ the lastpos of the left if the right argument is nullable.
+ * The lastpos of an OR node is the union of the lastpos of each argument.
+
+ Follow: The follow of a position is the set of positions that could
+ correspond to the character following a character matching the node in
+ a string matching the regexp. At this point we consider special symbols
+ that match the empty string in some context to be just normal characters.
+ Later, if we find that a special symbol is in a follow set, we will
+ replace it with the elements of its follow, labeled with an appropriate
+ constraint.
+ * Every node in the firstpos of the argument of a STAR or PLUS node is in
+ the follow of every node in the lastpos.
+ * Every node in the firstpos of the second argument of a CAT node is in
+ the follow of every node in the lastpos of the first argument.
+
+ Because of the postfix representation of the parse tree, the depth-first
+ analysis is conveniently done by a linear scan with the aid of a stack.
+ Sets are stored as arrays of the elements, obeying a stack-like allocation
+ scheme; the number of elements in each set deeper in the stack can be
+ used to determine the address of a particular set's array. */
+void
+dfaanalyze (struct dfa *d, int searchflag)
+{
+ int *nullable; /* Nullable stack. */
+ int *nfirstpos; /* Element count stack for firstpos sets. */
+ position *firstpos; /* Array where firstpos elements are stored. */
+ int *nlastpos; /* Element count stack for lastpos sets. */
+ position *lastpos; /* Array where lastpos elements are stored. */
+ int *nalloc; /* Sizes of arrays allocated to follow sets. */
+ position_set tmp; /* Temporary set for merging sets. */
+ position_set merged; /* Result of merging sets. */
+ int wants_newline; /* True if some position wants newline info. */
+ int *o_nullable;
+ int *o_nfirst, *o_nlast;
+ position *o_firstpos, *o_lastpos;
+ int i, j;
+ position *pos;
+
+#ifdef DEBUG
+ fprintf(stderr, "dfaanalyze:\n");
+ for (i = 0; i < d->tindex; ++i)
+ {
+ fprintf(stderr, " %d:", i);
+ prtok(d->tokens[i]);
+ }
+ putc('\n', stderr);
+#endif
+
+ d->searchflag = searchflag;
+
+ MALLOC(nullable, int, d->depth);
+ o_nullable = nullable;
+ MALLOC(nfirstpos, int, d->depth);
+ o_nfirst = nfirstpos;
+ MALLOC(firstpos, position, d->nleaves);
+ o_firstpos = firstpos, firstpos += d->nleaves;
+ MALLOC(nlastpos, int, d->depth);
+ o_nlast = nlastpos;
+ MALLOC(lastpos, position, d->nleaves);
+ o_lastpos = lastpos, lastpos += d->nleaves;
+ MALLOC(nalloc, int, d->tindex);
+ for (i = 0; i < d->tindex; ++i)
+ nalloc[i] = 0;
+ MALLOC(merged.elems, position, d->nleaves);
+
+ CALLOC(d->follows, position_set, d->tindex);
+
+ for (i = 0; i < d->tindex; ++i)
+#ifdef DEBUG
+ { /* Nonsyntactic #ifdef goo... */
+#endif
+ switch (d->tokens[i])
+ {
+ case EMPTY:
+ /* The empty set is nullable. */
+ *nullable++ = 1;
+
+ /* The firstpos and lastpos of the empty leaf are both empty. */
+ *nfirstpos++ = *nlastpos++ = 0;
+ break;
+
+ case STAR:
+ case PLUS:
+ /* Every element in the firstpos of the argument is in the follow
+ of every element in the lastpos. */
+ tmp.nelem = nfirstpos[-1];
+ tmp.elems = firstpos;
+ pos = lastpos;
+ for (j = 0; j < nlastpos[-1]; ++j)
+ {
+ merge(&tmp, &d->follows[pos[j].index], &merged);
+ REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position,
+ nalloc[pos[j].index], merged.nelem - 1);
+ copy(&merged, &d->follows[pos[j].index]);
+ }
+
+ case QMARK:
+ /* A QMARK or STAR node is automatically nullable. */
+ if (d->tokens[i] != PLUS)
+ nullable[-1] = 1;
+ break;
+
+ case CAT:
+ /* Every element in the firstpos of the second argument is in the
+ follow of every element in the lastpos of the first argument. */
+ tmp.nelem = nfirstpos[-1];
+ tmp.elems = firstpos;
+ pos = lastpos + nlastpos[-1];
+ for (j = 0; j < nlastpos[-2]; ++j)
+ {
+ merge(&tmp, &d->follows[pos[j].index], &merged);
+ REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position,
+ nalloc[pos[j].index], merged.nelem - 1);
+ copy(&merged, &d->follows[pos[j].index]);
+ }
+
+ /* The firstpos of a CAT node is the firstpos of the first argument,
+ union that of the second argument if the first is nullable. */
+ if (nullable[-2])
+ nfirstpos[-2] += nfirstpos[-1];
+ else
+ firstpos += nfirstpos[-1];
+ --nfirstpos;
+
+ /* The lastpos of a CAT node is the lastpos of the second argument,
+ union that of the first argument if the second is nullable. */
+ if (nullable[-1])
+ nlastpos[-2] += nlastpos[-1];
+ else
+ {
+ pos = lastpos + nlastpos[-2];
+ for (j = nlastpos[-1] - 1; j >= 0; --j)
+ pos[j] = lastpos[j];
+ lastpos += nlastpos[-2];
+ nlastpos[-2] = nlastpos[-1];
+ }
+ --nlastpos;
+
+ /* A CAT node is nullable if both arguments are nullable. */
+ nullable[-2] = nullable[-1] && nullable[-2];
+ --nullable;
+ break;
+
+ case OR:
+ case ORTOP:
+ /* The firstpos is the union of the firstpos of each argument. */
+ nfirstpos[-2] += nfirstpos[-1];
+ --nfirstpos;
+
+ /* The lastpos is the union of the lastpos of each argument. */
+ nlastpos[-2] += nlastpos[-1];
+ --nlastpos;
+
+ /* An OR node is nullable if either argument is nullable. */
+ nullable[-2] = nullable[-1] || nullable[-2];
+ --nullable;
+ break;
+
+ default:
+ /* Anything else is a nonempty position. (Note that special
+ constructs like \< are treated as nonempty strings here;
+ an "epsilon closure" effectively makes them nullable later.
+ Backreferences have to get a real position so we can detect
+ transitions on them later. But they are nullable. */
+ *nullable++ = d->tokens[i] == BACKREF;
+
+ /* This position is in its own firstpos and lastpos. */
+ *nfirstpos++ = *nlastpos++ = 1;
+ --firstpos, --lastpos;
+ firstpos->index = lastpos->index = i;
+ firstpos->constraint = lastpos->constraint = NO_CONSTRAINT;
+
+ /* Allocate the follow set for this position. */
+ nalloc[i] = 1;
+ MALLOC(d->follows[i].elems, position, nalloc[i]);
+ break;
+ }
+#ifdef DEBUG
+ /* ... balance the above nonsyntactic #ifdef goo... */
+ fprintf(stderr, "node %d:", i);
+ prtok(d->tokens[i]);
+ putc('\n', stderr);
+ fprintf(stderr, nullable[-1] ? " nullable: yes\n" : " nullable: no\n");
+ fprintf(stderr, " firstpos:");
+ for (j = nfirstpos[-1] - 1; j >= 0; --j)
+ {
+ fprintf(stderr, " %d:", firstpos[j].index);
+ prtok(d->tokens[firstpos[j].index]);
+ }
+ fprintf(stderr, "\n lastpos:");
+ for (j = nlastpos[-1] - 1; j >= 0; --j)
+ {
+ fprintf(stderr, " %d:", lastpos[j].index);
+ prtok(d->tokens[lastpos[j].index]);
+ }
+ putc('\n', stderr);
+ }
+#endif
+
+ /* For each follow set that is the follow set of a real position, replace
+ it with its epsilon closure. */
+ for (i = 0; i < d->tindex; ++i)
+ if (d->tokens[i] < NOTCHAR || d->tokens[i] == BACKREF
+#ifdef MBS_SUPPORT
+ || d->tokens[i] == ANYCHAR
+ || d->tokens[i] == MBCSET
+#endif
+ || d->tokens[i] >= CSET)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "follows(%d:", i);
+ prtok(d->tokens[i]);
+ fprintf(stderr, "):");
+ for (j = d->follows[i].nelem - 1; j >= 0; --j)
+ {
+ fprintf(stderr, " %d:", d->follows[i].elems[j].index);
+ prtok(d->tokens[d->follows[i].elems[j].index]);
+ }
+ putc('\n', stderr);
+#endif
+ copy(&d->follows[i], &merged);
+ epsclosure(&merged, d);
+ if (d->follows[i].nelem < merged.nelem)
+ REALLOC(d->follows[i].elems, position, merged.nelem);
+ copy(&merged, &d->follows[i]);
+ }
+
+ /* Get the epsilon closure of the firstpos of the regexp. The result will
+ be the set of positions of state 0. */
+ merged.nelem = 0;
+ for (i = 0; i < nfirstpos[-1]; ++i)
+ insert(firstpos[i], &merged);
+ epsclosure(&merged, d);
+
+ /* Check if any of the positions of state 0 will want newline context. */
+ wants_newline = 0;
+ for (i = 0; i < merged.nelem; ++i)
+ if (PREV_NEWLINE_DEPENDENT(merged.elems[i].constraint))
+ wants_newline = 1;
+
+ /* Build the initial state. */
+ d->salloc = 1;
+ d->sindex = 0;
+ MALLOC(d->states, dfa_state, d->salloc);
+ state_index(d, &merged, wants_newline, 0);
+
+ free(o_nullable);
+ free(o_nfirst);
+ free(o_firstpos);
+ free(o_nlast);
+ free(o_lastpos);
+ free(nalloc);
+ free(merged.elems);
+}
+
+/* Find, for each character, the transition out of state s of d, and store
+ it in the appropriate slot of trans.
+
+ We divide the positions of s into groups (positions can appear in more
+ than one group). Each group is labeled with a set of characters that
+ every position in the group matches (taking into account, if necessary,
+ preceding context information of s). For each group, find the union
+ of the its elements' follows. This set is the set of positions of the
+ new state. For each character in the group's label, set the transition
+ on this character to be to a state corresponding to the set's positions,
+ and its associated backward context information, if necessary.
+
+ If we are building a searching matcher, we include the positions of state
+ 0 in every state.
+
+ The collection of groups is constructed by building an equivalence-class
+ partition of the positions of s.
+
+ For each position, find the set of characters C that it matches. Eliminate
+ any characters from C that fail on grounds of backward context.
+
+ Search through the groups, looking for a group whose label L has nonempty
+ intersection with C. If L - C is nonempty, create a new group labeled
+ L - C and having the same positions as the current group, and set L to
+ the intersection of L and C. Insert the position in this group, set
+ C = C - L, and resume scanning.
+
+ If after comparing with every group there are characters remaining in C,
+ create a new group labeled with the characters of C and insert this
+ position in that group. */
+void
+dfastate (int s, struct dfa *d, int trans[])
+{
+ position_set grps[NOTCHAR]; /* As many as will ever be needed. */
+ charclass labels[NOTCHAR]; /* Labels corresponding to the groups. */
+ int ngrps = 0; /* Number of groups actually used. */
+ position pos; /* Current position being considered. */
+ charclass matches; /* Set of matching characters. */
+ int matchesf; /* True if matches is nonempty. */
+ charclass intersect; /* Intersection with some label set. */
+ int intersectf; /* True if intersect is nonempty. */
+ charclass leftovers; /* Stuff in the label that didn't match. */
+ int leftoversf; /* True if leftovers is nonempty. */
+ static charclass letters; /* Set of characters considered letters. */
+ static charclass newline; /* Set of characters that aren't newline. */
+ position_set follows; /* Union of the follows of some group. */
+ position_set tmp; /* Temporary space for merging sets. */
+ int state; /* New state. */
+ int wants_newline; /* New state wants to know newline context. */
+ int state_newline; /* New state on a newline transition. */
+ int wants_letter; /* New state wants to know letter context. */
+ int state_letter; /* New state on a letter transition. */
+ static int initialized; /* Flag for static initialization. */
+#ifdef MBS_SUPPORT
+ int next_isnt_1st_byte = 0; /* Flag if we can't add state0. */
+#endif
+ int i, j, k;
+
+ /* Initialize the set of letters, if necessary. */
+ if (! initialized)
+ {
+ initialized = 1;
+ for (i = 0; i < NOTCHAR; ++i)
+ if (IS_WORD_CONSTITUENT(i))
+ setbit(i, letters);
+ setbit(eolbyte, newline);
+ }
+
+ zeroset(matches);
+
+ for (i = 0; i < d->states[s].elems.nelem; ++i)
+ {
+ pos = d->states[s].elems.elems[i];
+ if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR)
+ setbit(d->tokens[pos.index], matches);
+ else if (d->tokens[pos.index] >= CSET)
+ copyset(d->charclasses[d->tokens[pos.index] - CSET], matches);
+#ifdef MBS_SUPPORT
+ else if (d->tokens[pos.index] == ANYCHAR
+ || d->tokens[pos.index] == MBCSET)
+ /* MB_CUR_MAX > 1 */
+ {
+ /* ANYCHAR and MBCSET must match with a single character, so we
+ must put it to d->states[s].mbps, which contains the positions
+ which can match with a single character not a byte. */
+ if (d->states[s].mbps.nelem == 0)
+ {
+ MALLOC(d->states[s].mbps.elems, position,
+ d->states[s].elems.nelem);
+ }
+ insert(pos, &(d->states[s].mbps));
+ continue;
+ }
+#endif /* MBS_SUPPORT */
+ else
+ continue;
+
+ /* Some characters may need to be eliminated from matches because
+ they fail in the current context. */
+ if (pos.constraint != 0xFF)
+ {
+ if (! MATCHES_NEWLINE_CONTEXT(pos.constraint,
+ d->states[s].newline, 1))
+ clrbit(eolbyte, matches);
+ if (! MATCHES_NEWLINE_CONTEXT(pos.constraint,
+ d->states[s].newline, 0))
+ for (j = 0; j < CHARCLASS_INTS; ++j)
+ matches[j] &= newline[j];
+ if (! MATCHES_LETTER_CONTEXT(pos.constraint,
+ d->states[s].letter, 1))
+ for (j = 0; j < CHARCLASS_INTS; ++j)
+ matches[j] &= ~letters[j];
+ if (! MATCHES_LETTER_CONTEXT(pos.constraint,
+ d->states[s].letter, 0))
+ for (j = 0; j < CHARCLASS_INTS; ++j)
+ matches[j] &= letters[j];
+
+ /* If there are no characters left, there's no point in going on. */
+ for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j)
+ continue;
+ if (j == CHARCLASS_INTS)
+ continue;
+ }
+
+ for (j = 0; j < ngrps; ++j)
+ {
+ /* If matches contains a single character only, and the current
+ group's label doesn't contain that character, go on to the
+ next group. */
+ if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR
+ && !tstbit(d->tokens[pos.index], labels[j]))
+ continue;
+
+ /* Check if this group's label has a nonempty intersection with
+ matches. */
+ intersectf = 0;
+ for (k = 0; k < CHARCLASS_INTS; ++k)
+ (intersect[k] = matches[k] & labels[j][k]) ? (intersectf = 1) : 0;
+ if (! intersectf)
+ continue;
+
+ /* It does; now find the set differences both ways. */
+ leftoversf = matchesf = 0;
+ for (k = 0; k < CHARCLASS_INTS; ++k)
+ {
+ /* Even an optimizing compiler can't know this for sure. */
+ int match = matches[k], label = labels[j][k];
+
+ (leftovers[k] = ~match & label) ? (leftoversf = 1) : 0;
+ (matches[k] = match & ~label) ? (matchesf = 1) : 0;
+ }
+
+ /* If there were leftovers, create a new group labeled with them. */
+ if (leftoversf)
+ {
+ copyset(leftovers, labels[ngrps]);
+ copyset(intersect, labels[j]);
+ MALLOC(grps[ngrps].elems, position, d->nleaves);
+ copy(&grps[j], &grps[ngrps]);
+ ++ngrps;
+ }
+
+ /* Put the position in the current group. Note that there is no
+ reason to call insert() here. */
+ grps[j].elems[grps[j].nelem++] = pos;
+
+ /* If every character matching the current position has been
+ accounted for, we're done. */
+ if (! matchesf)
+ break;
+ }
+
+ /* If we've passed the last group, and there are still characters
+ unaccounted for, then we'll have to create a new group. */
+ if (j == ngrps)
+ {
+ copyset(matches, labels[ngrps]);
+ zeroset(matches);
+ MALLOC(grps[ngrps].elems, position, d->nleaves);
+ grps[ngrps].nelem = 1;
+ grps[ngrps].elems[0] = pos;
+ ++ngrps;
+ }
+ }
+
+ MALLOC(follows.elems, position, d->nleaves);
+ MALLOC(tmp.elems, position, d->nleaves);
+
+ /* If we are a searching matcher, the default transition is to a state
+ containing the positions of state 0, otherwise the default transition
+ is to fail miserably. */
+ if (d->searchflag)
+ {
+ wants_newline = 0;
+ wants_letter = 0;
+ for (i = 0; i < d->states[0].elems.nelem; ++i)
+ {
+ if (PREV_NEWLINE_DEPENDENT(d->states[0].elems.elems[i].constraint))
+ wants_newline = 1;
+ if (PREV_LETTER_DEPENDENT(d->states[0].elems.elems[i].constraint))
+ wants_letter = 1;
+ }
+ copy(&d->states[0].elems, &follows);
+ state = state_index(d, &follows, 0, 0);
+ if (wants_newline)
+ state_newline = state_index(d, &follows, 1, 0);
+ else
+ state_newline = state;
+ if (wants_letter)
+ state_letter = state_index(d, &follows, 0, 1);
+ else
+ state_letter = state;
+ for (i = 0; i < NOTCHAR; ++i)
+ trans[i] = (IS_WORD_CONSTITUENT(i)) ? state_letter : state;
+ trans[eolbyte] = state_newline;
+ }
+ else
+ for (i = 0; i < NOTCHAR; ++i)
+ trans[i] = -1;
+
+ for (i = 0; i < ngrps; ++i)
+ {
+ follows.nelem = 0;
+
+ /* Find the union of the follows of the positions of the group.
+ This is a hideously inefficient loop. Fix it someday. */
+ for (j = 0; j < grps[i].nelem; ++j)
+ for (k = 0; k < d->follows[grps[i].elems[j].index].nelem; ++k)
+ insert(d->follows[grps[i].elems[j].index].elems[k], &follows);
+
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ /* If a token in follows.elems is not 1st byte of a multibyte
+ character, or the states of follows must accept the bytes
+ which are not 1st byte of the multibyte character.
+ Then, if a state of follows encounter a byte, it must not be
+ a 1st byte of a multibyte character nor single byte character.
+ We cansel to add state[0].follows to next state, because
+ state[0] must accept 1st-byte
+
+ For example, we assume <sb a> is a certain single byte
+ character, <mb A> is a certain multibyte character, and the
+ codepoint of <sb a> equals the 2nd byte of the codepoint of
+ <mb A>.
+ When state[0] accepts <sb a>, state[i] transit to state[i+1]
+ by accepting accepts 1st byte of <mb A>, and state[i+1]
+ accepts 2nd byte of <mb A>, if state[i+1] encounter the
+ codepoint of <sb a>, it must not be <sb a> but 2nd byte of
+ <mb A>, so we can not add state[0]. */
+
+ next_isnt_1st_byte = 0;
+ for (j = 0; j < follows.nelem; ++j)
+ {
+ if (!(d->multibyte_prop[follows.elems[j].index] & 1))
+ {
+ next_isnt_1st_byte = 1;
+ break;
+ }
+ }
+ }
+#endif
+
+ /* If we are building a searching matcher, throw in the positions
+ of state 0 as well. */
+#ifdef MBS_SUPPORT
+ if (d->searchflag && (MB_CUR_MAX == 1 || !next_isnt_1st_byte))
+#else
+ if (d->searchflag)
+#endif
+ for (j = 0; j < d->states[0].elems.nelem; ++j)
+ insert(d->states[0].elems.elems[j], &follows);
+
+ /* Find out if the new state will want any context information. */
+ wants_newline = 0;
+ if (tstbit(eolbyte, labels[i]))
+ for (j = 0; j < follows.nelem; ++j)
+ if (PREV_NEWLINE_DEPENDENT(follows.elems[j].constraint))
+ wants_newline = 1;
+
+ wants_letter = 0;
+ for (j = 0; j < CHARCLASS_INTS; ++j)
+ if (labels[i][j] & letters[j])
+ break;
+ if (j < CHARCLASS_INTS)
+ for (j = 0; j < follows.nelem; ++j)
+ if (PREV_LETTER_DEPENDENT(follows.elems[j].constraint))
+ wants_letter = 1;
+
+ /* Find the state(s) corresponding to the union of the follows. */
+ state = state_index(d, &follows, 0, 0);
+ if (wants_newline)
+ state_newline = state_index(d, &follows, 1, 0);
+ else
+ state_newline = state;
+ if (wants_letter)
+ state_letter = state_index(d, &follows, 0, 1);
+ else
+ state_letter = state;
+
+ /* Set the transitions for each character in the current label. */
+ for (j = 0; j < CHARCLASS_INTS; ++j)
+ for (k = 0; k < INTBITS; ++k)
+ if (labels[i][j] & 1 << k)
+ {
+ int c = j * INTBITS + k;
+
+ if (c == eolbyte)
+ trans[c] = state_newline;
+ else if (IS_WORD_CONSTITUENT(c))
+ trans[c] = state_letter;
+ else if (c < NOTCHAR)
+ trans[c] = state;
+ }
+ }
+
+ for (i = 0; i < ngrps; ++i)
+ free(grps[i].elems);
+ free(follows.elems);
+ free(tmp.elems);
+}
+
+/* Some routines for manipulating a compiled dfa's transition tables.
+ Each state may or may not have a transition table; if it does, and it
+ is a non-accepting state, then d->trans[state] points to its table.
+ If it is an accepting state then d->fails[state] points to its table.
+ If it has no table at all, then d->trans[state] is NULL.
+ TODO: Improve this comment, get rid of the unnecessary redundancy. */
+
+static void
+build_state (int s, struct dfa *d)
+{
+ int *trans; /* The new transition table. */
+ int i;
+
+ /* Set an upper limit on the number of transition tables that will ever
+ exist at once. 1024 is arbitrary. The idea is that the frequently
+ used transition tables will be quickly rebuilt, whereas the ones that
+ were only needed once or twice will be cleared away. */
+ if (d->trcount >= 1024)
+ {
+ for (i = 0; i < d->tralloc; ++i)
+ if (d->trans[i])
+ {
+ free((ptr_t) d->trans[i]);
+ d->trans[i] = NULL;
+ }
+ else if (d->fails[i])
+ {
+ free((ptr_t) d->fails[i]);
+ d->fails[i] = NULL;
+ }
+ d->trcount = 0;
+ }
+
+ ++d->trcount;
+
+ /* Set up the success bits for this state. */
+ d->success[s] = 0;
+ if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 1, d->states[s].letter, 0,
+ s, *d))
+ d->success[s] |= 4;
+ if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 1,
+ s, *d))
+ d->success[s] |= 2;
+ if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 0,
+ s, *d))
+ d->success[s] |= 1;
+
+ MALLOC(trans, int, NOTCHAR);
+ dfastate(s, d, trans);
+
+ /* Now go through the new transition table, and make sure that the trans
+ and fail arrays are allocated large enough to hold a pointer for the
+ largest state mentioned in the table. */
+ for (i = 0; i < NOTCHAR; ++i)
+ if (trans[i] >= d->tralloc)
+ {
+ int oldalloc = d->tralloc;
+
+ while (trans[i] >= d->tralloc)
+ d->tralloc *= 2;
+ REALLOC(d->realtrans, int *, d->tralloc + 1);
+ d->trans = d->realtrans + 1;
+ REALLOC(d->fails, int *, d->tralloc);
+ REALLOC(d->success, int, d->tralloc);
+ REALLOC(d->newlines, int, d->tralloc);
+ while (oldalloc < d->tralloc)
+ {
+ d->trans[oldalloc] = NULL;
+ d->fails[oldalloc++] = NULL;
+ }
+ }
+
+ /* Keep the newline transition in a special place so we can use it as
+ a sentinel. */
+ d->newlines[s] = trans[eolbyte];
+ trans[eolbyte] = -1;
+
+ if (ACCEPTING(s, *d))
+ d->fails[s] = trans;
+ else
+ d->trans[s] = trans;
+}
+
+static void
+build_state_zero (struct dfa *d)
+{
+ d->tralloc = 1;
+ d->trcount = 0;
+ CALLOC(d->realtrans, int *, d->tralloc + 1);
+ d->trans = d->realtrans + 1;
+ CALLOC(d->fails, int *, d->tralloc);
+ MALLOC(d->success, int, d->tralloc);
+ MALLOC(d->newlines, int, d->tralloc);
+ build_state(0, d);
+}
+
+#ifdef MBS_SUPPORT
+/* Multibyte character handling sub-routines for dfaexec. */
+
+/* Initial state may encounter the byte which is not a single byte character
+ nor 1st byte of a multibyte character. But it is incorrect for initial
+ state to accept such a byte.
+ For example, in sjis encoding the regular expression like "\\" accepts
+ the codepoint 0x5c, but should not accept the 2nd byte of the codepoint
+ 0x815c. Then Initial state must skip the bytes which are not a single byte
+ character nor 1st byte of a multibyte character. */
+#define SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p) \
+ if (s == 0) \
+ { \
+ while (inputwcs[p - buf_begin] == 0 \
+ && mblen_buf[p - buf_begin] > 0 \
+ && (unsigned char const *)p < buf_end) \
+ ++p; \
+ if ((char *)p >= end) \
+ { \
+ free(mblen_buf); \
+ free(inputwcs); \
+ return NULL; \
+ } \
+ }
+
+static void
+realloc_trans_if_necessary(struct dfa *d, int new_state)
+{
+ /* Make sure that the trans and fail arrays are allocated large enough
+ to hold a pointer for the new state. */
+ if (new_state >= d->tralloc)
+ {
+ int oldalloc = d->tralloc;
+
+ while (new_state >= d->tralloc)
+ d->tralloc *= 2;
+ REALLOC(d->realtrans, int *, d->tralloc + 1);
+ d->trans = d->realtrans + 1;
+ REALLOC(d->fails, int *, d->tralloc);
+ REALLOC(d->success, int, d->tralloc);
+ REALLOC(d->newlines, int, d->tralloc);
+ while (oldalloc < d->tralloc)
+ {
+ d->trans[oldalloc] = NULL;
+ d->fails[oldalloc++] = NULL;
+ }
+ }
+}
+
+/* Return values of transit_state_singlebyte(), and
+ transit_state_consume_1char. */
+typedef enum
+{
+ TRANSIT_STATE_IN_PROGRESS, /* State transition has not finished. */
+ TRANSIT_STATE_DONE, /* State transition has finished. */
+ TRANSIT_STATE_END_BUFFER /* Reach the end of the buffer. */
+} status_transit_state;
+
+/* Consume a single byte and transit state from 's' to '*next_state'.
+ This function is almost same as the state transition routin in dfaexec().
+ But state transition is done just once, otherwise matching succeed or
+ reach the end of the buffer. */
+static status_transit_state
+transit_state_singlebyte (struct dfa *d, int s, unsigned char const *p,
+ int *next_state)
+{
+ int *t;
+ int works = s;
+
+ status_transit_state rval = TRANSIT_STATE_IN_PROGRESS;
+
+ while (rval == TRANSIT_STATE_IN_PROGRESS)
+ {
+ if ((t = d->trans[works]) != NULL)
+ {
+ works = t[*p];
+ rval = TRANSIT_STATE_DONE;
+ if (works < 0)
+ works = 0;
+ }
+ else if (works < 0)
+ {
+ if (p == buf_end)
+ /* At the moment, it must not happen. */
+ return TRANSIT_STATE_END_BUFFER;
+ works = 0;
+ }
+ else if (d->fails[works])
+ {
+ works = d->fails[works][*p];
+ rval = TRANSIT_STATE_DONE;
+ }
+ else
+ {
+ build_state(works, d);
+ }
+ }
+ *next_state = works;
+ return rval;
+}
+
+/* Check whether period can match or not in the current context. If it can,
+ return the amount of the bytes with which period can match, otherwise
+ return 0.
+ `pos' is the position of the period. `index' is the index from the
+ buf_begin, and it is the current position in the buffer. */
+static int
+match_anychar (struct dfa *d, int s, position pos, int index)
+{
+ int newline = 0;
+ int letter = 0;
+ wchar_t wc;
+ int mbclen;
+
+ wc = inputwcs[index];
+ mbclen = (mblen_buf[index] == 0)? 1 : mblen_buf[index];
+
+ /* Check context. */
+ if (wc == (wchar_t)eolbyte)
+ {
+ if (!(syntax_bits & RE_DOT_NEWLINE))
+ return 0;
+ newline = 1;
+ }
+ else if (wc == (wchar_t)'\0')
+ {
+ if (syntax_bits & RE_DOT_NOT_NULL)
+ return 0;
+ newline = 1;
+ }
+
+ if (iswalnum(wc) || wc == L'_')
+ letter = 1;
+
+ if (!SUCCEEDS_IN_CONTEXT(pos.constraint, d->states[s].newline,
+ newline, d->states[s].letter, letter))
+ return 0;
+
+ return mbclen;
+}
+
+/* Check whether bracket expression can match or not in the current context.
+ If it can, return the amount of the bytes with which expression can match,
+ otherwise return 0.
+ `pos' is the position of the bracket expression. `index' is the index
+ from the buf_begin, and it is the current position in the buffer. */
+int
+match_mb_charset (struct dfa *d, int s, position pos, int index)
+{
+ int i;
+ int match; /* Flag which represent that matching succeed. */
+ int match_len; /* Length of the character (or collating element)
+ with which this operator match. */
+ int op_len; /* Length of the operator. */
+ char buffer[128];
+ wchar_t wcbuf[6];
+
+ /* Pointer to the structure to which we are currently refering. */
+ struct mb_char_classes *work_mbc;
+
+ int newline = 0;
+ int letter = 0;
+ wchar_t wc; /* Current refering character. */
+
+ wc = inputwcs[index];
+
+ /* Check context. */
+ if (wc == (wchar_t)eolbyte)
+ {
+ if (!(syntax_bits & RE_DOT_NEWLINE))
+ return 0;
+ newline = 1;
+ }
+ else if (wc == (wchar_t)'\0')
+ {
+ if (syntax_bits & RE_DOT_NOT_NULL)
+ return 0;
+ newline = 1;
+ }
+ if (iswalnum(wc) || wc == L'_')
+ letter = 1;
+ if (!SUCCEEDS_IN_CONTEXT(pos.constraint, d->states[s].newline,
+ newline, d->states[s].letter, letter))
+ return 0;
+
+ /* Assign the current refering operator to work_mbc. */
+ work_mbc = &(d->mbcsets[(d->multibyte_prop[pos.index]) >> 2]);
+ match = !work_mbc->invert;
+ match_len = (mblen_buf[index] == 0)? 1 : mblen_buf[index];
+
+ /* match with a character class? */
+ for (i = 0; i<work_mbc->nch_classes; i++)
+ {
+ if (iswctype((wint_t)wc, work_mbc->ch_classes[i]))
+ goto charset_matched;
+ }
+
+ strncpy(buffer, buf_begin + index, match_len);
+ buffer[match_len] = '\0';
+
+ /* match with an equivalent class? */
+ for (i = 0; i<work_mbc->nequivs; i++)
+ {
+ op_len = strlen(work_mbc->equivs[i]);
+ strncpy(buffer, buf_begin + index, op_len);
+ buffer[op_len] = '\0';
+ if (strcoll(work_mbc->equivs[i], buffer) == 0)
+ {
+ match_len = op_len;
+ goto charset_matched;
+ }
+ }
+
+ /* match with a collating element? */
+ for (i = 0; i<work_mbc->ncoll_elems; i++)
+ {
+ op_len = strlen(work_mbc->coll_elems[i]);
+ strncpy(buffer, buf_begin + index, op_len);
+ buffer[op_len] = '\0';
+
+ if (strcoll(work_mbc->coll_elems[i], buffer) == 0)
+ {
+ match_len = op_len;
+ goto charset_matched;
+ }
+ }
+
+ wcbuf[0] = wc;
+ wcbuf[1] = wcbuf[3] = wcbuf[5] = '\0';
+
+ /* match with a range? */
+ for (i = 0; i<work_mbc->nranges; i++)
+ {
+ wcbuf[2] = work_mbc->range_sts[i];
+ wcbuf[4] = work_mbc->range_ends[i];
+
+ if (wcscoll(wcbuf, wcbuf+2) >= 0 &&
+ wcscoll(wcbuf+4, wcbuf) >= 0)
+ goto charset_matched;
+ }
+
+ /* match with a character? */
+ for (i = 0; i<work_mbc->nchars; i++)
+ {
+ if (wc == work_mbc->chars[i])
+ goto charset_matched;
+ }
+
+ match = !match;
+
+ charset_matched:
+ return match ? match_len : 0;
+}
+
+/* Check each of `d->states[s].mbps.elem' can match or not. Then return the
+ array which corresponds to `d->states[s].mbps.elem' and each element of
+ the array contains the amount of the bytes with which the element can
+ match.
+ `index' is the index from the buf_begin, and it is the current position
+ in the buffer.
+ Caller MUST free the array which this function return. */
+static int*
+check_matching_with_multibyte_ops (struct dfa *d, int s, int index)
+{
+ int i;
+ int* rarray;
+
+ MALLOC(rarray, int, d->states[s].mbps.nelem);
+ for (i = 0; i < d->states[s].mbps.nelem; ++i)
+ {
+ position pos = d->states[s].mbps.elems[i];
+ switch(d->tokens[pos.index])
+ {
+ case ANYCHAR:
+ rarray[i] = match_anychar(d, s, pos, index);
+ break;
+ case MBCSET:
+ rarray[i] = match_mb_charset(d, s, pos, index);
+ break;
+ default:
+ break; /* can not happen. */
+ }
+ }
+ return rarray;
+}
+
+/* Consume a single character and enumerate all of the positions which can
+ be next position from the state `s'.
+ `match_lens' is the input. It can be NULL, but it can also be the output
+ of check_matching_with_multibyte_ops() for optimization.
+ `mbclen' and `pps' are the output. `mbclen' is the length of the
+ character consumed, and `pps' is the set this function enumerate. */
+static status_transit_state
+transit_state_consume_1char (struct dfa *d, int s, unsigned char const **pp,
+ int *match_lens, int *mbclen, position_set *pps)
+{
+ int i, j;
+ int s1, s2;
+ int* work_mbls;
+ status_transit_state rs = TRANSIT_STATE_DONE;
+
+ /* Calculate the length of the (single/multi byte) character
+ to which p points. */
+ *mbclen = (mblen_buf[*pp - buf_begin] == 0)? 1
+ : mblen_buf[*pp - buf_begin];
+
+ /* Calculate the state which can be reached from the state `s' by
+ consuming `*mbclen' single bytes from the buffer. */
+ s1 = s;
+ for (i = 0; i < *mbclen; i++)
+ {
+ s2 = s1;
+ rs = transit_state_singlebyte(d, s2, (*pp)++, &s1);
+ }
+ /* Copy the positions contained by `s1' to the set `pps'. */
+ copy(&(d->states[s1].elems), pps);
+
+ /* Check (inputed)match_lens, and initialize if it is NULL. */
+ if (match_lens == NULL && d->states[s].mbps.nelem != 0)
+ work_mbls = check_matching_with_multibyte_ops(d, s, *pp - buf_begin);
+ else
+ work_mbls = match_lens;
+
+ /* Add all of the positions which can be reached from `s' by consuming
+ a single character. */
+ for (i = 0; i < d->states[s].mbps.nelem ; i++)
+ {
+ if (work_mbls[i] == *mbclen)
+ for (j = 0; j < d->follows[d->states[s].mbps.elems[i].index].nelem;
+ j++)
+ insert(d->follows[d->states[s].mbps.elems[i].index].elems[j],
+ pps);
+ }
+
+ if (match_lens == NULL && work_mbls != NULL)
+ free(work_mbls);
+ return rs;
+}
+
+/* Transit state from s, then return new state and update the pointer of the
+ buffer. This function is for some operator which can match with a multi-
+ byte character or a collating element (which may be multi characters). */
+static int
+transit_state (struct dfa *d, int s, unsigned char const **pp)
+{
+ int s1;
+ int mbclen; /* The length of current input multibyte character. */
+ int maxlen = 0;
+ int i, j;
+ int *match_lens = NULL;
+ int nelem = d->states[s].mbps.nelem; /* Just a alias. */
+ position_set follows;
+ unsigned char const *p1 = *pp;
+ status_transit_state rs;
+ wchar_t wc;
+
+ if (nelem > 0)
+ /* This state has (a) multibyte operator(s).
+ We check whether each of them can match or not. */
+ {
+ /* Note: caller must free the return value of this function. */
+ match_lens = check_matching_with_multibyte_ops(d, s, *pp - buf_begin);
+
+ for (i = 0; i < nelem; i++)
+ /* Search the operator which match the longest string,
+ in this state. */
+ {
+ if (match_lens[i] > maxlen)
+ maxlen = match_lens[i];
+ }
+ }
+
+ if (nelem == 0 || maxlen == 0)
+ /* This state has no multibyte operator which can match.
+ We need to check only one single byte character. */
+ {
+ status_transit_state rs;
+ rs = transit_state_singlebyte(d, s, *pp, &s1);
+
+ /* We must update the pointer if state transition succeeded. */
+ if (rs == TRANSIT_STATE_DONE)
+ ++*pp;
+
+ if (match_lens != NULL)
+ free(match_lens);
+ return s1;
+ }
+
+ /* This state has some operators which can match a multibyte character. */
+ follows.nelem = 0;
+ MALLOC(follows.elems, position, d->nleaves);
+
+ /* `maxlen' may be longer than the length of a character, because it may
+ not be a character but a (multi character) collating element.
+ We enumerate all of the positions which `s' can reach by consuming
+ `maxlen' bytes. */
+ rs = transit_state_consume_1char(d, s, pp, match_lens, &mbclen, &follows);
+
+ wc = inputwcs[*pp - mbclen - buf_begin];
+ s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc));
+ realloc_trans_if_necessary(d, s1);
+
+ while (*pp - p1 < maxlen)
+ {
+ follows.nelem = 0;
+ rs = transit_state_consume_1char(d, s1, pp, NULL, &mbclen, &follows);
+
+ for (i = 0; i < nelem ; i++)
+ {
+ if (match_lens[i] == *pp - p1)
+ for (j = 0;
+ j < d->follows[d->states[s1].mbps.elems[i].index].nelem; j++)
+ insert(d->follows[d->states[s1].mbps.elems[i].index].elems[j],
+ &follows);
+ }
+
+ wc = inputwcs[*pp - mbclen - buf_begin];
+ s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc));
+ realloc_trans_if_necessary(d, s1);
+ }
+ free(match_lens);
+ free(follows.elems);
+ return s1;
+}
+
+#endif /* MBS_SUPPORT */
+
+/* Search through a buffer looking for a match to the given struct dfa.
+ Find the first occurrence of a string matching the regexp in the buffer,
+ and the shortest possible version thereof. Return a pointer to the first
+ character after the match, or NULL if none is found. Begin points to
+ the beginning of the buffer, and end points to the first character after
+ its end. We store a newline in *end to act as a sentinel, so end had
+ better point somewhere valid. Newline is a flag indicating whether to
+ allow newlines to be in the matching string. If count is non-
+ NULL it points to a place we're supposed to increment every time we
+ see a newline. Finally, if backref is non-NULL it points to a place
+ where we're supposed to store a 1 if backreferencing happened and the
+ match needs to be verified by a backtracking matcher. Otherwise
+ we store a 0 in *backref. */
+char *
+dfaexec (struct dfa *d, char const *begin, char *end,
+ int newline, int *count, int *backref)
+{
+ register int s, s1, tmp; /* Current state. */
+ register unsigned char const *p; /* Current input character. */
+ register int **trans, *t; /* Copy of d->trans so it can be optimized
+ into a register. */
+ register unsigned char eol = eolbyte; /* Likewise for eolbyte. */
+ static int sbit[NOTCHAR]; /* Table for anding with d->success. */
+ static int sbit_init;
+
+ if (! sbit_init)
+ {
+ int i;
+
+ sbit_init = 1;
+ for (i = 0; i < NOTCHAR; ++i)
+ sbit[i] = (IS_WORD_CONSTITUENT(i)) ? 2 : 1;
+ sbit[eol] = 4;
+ }
+
+ if (! d->tralloc)
+ build_state_zero(d);
+
+ s = s1 = 0;
+ p = (unsigned char const *) begin;
+ trans = d->trans;
+ *end = eol;
+
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ int remain_bytes, i;
+ buf_begin = begin;
+ buf_end = end;
+
+ /* initialize mblen_buf, and inputwcs. */
+ MALLOC(mblen_buf, unsigned char, end - begin + 2);
+ MALLOC(inputwcs, wchar_t, end - begin + 2);
+ memset(&mbs, 0, sizeof(mbstate_t));
+ remain_bytes = 0;
+ for (i = 0; i < end - begin + 1; i++)
+ {
+ if (remain_bytes == 0)
+ {
+ remain_bytes
+ = mbrtowc(inputwcs + i, begin + i, end - begin - i + 1, &mbs);
+ if (remain_bytes <= 1)
+ {
+ remain_bytes = 0;
+ inputwcs[i] = (wchar_t)begin[i];
+ mblen_buf[i] = 0;
+ }
+ else
+ {
+ mblen_buf[i] = remain_bytes;
+ remain_bytes--;
+ }
+ }
+ else
+ {
+ mblen_buf[i] = remain_bytes;
+ inputwcs[i] = 0;
+ remain_bytes--;
+ }
+ }
+ mblen_buf[i] = 0;
+ inputwcs[i] = 0; /* sentinel */
+ }
+#endif /* MBS_SUPPORT */
+
+ for (;;)
+ {
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ while ((t = trans[s]))
+ {
+ if ((char *) p > end)
+ break;
+ s1 = s;
+ if (d->states[s].mbps.nelem != 0)
+ {
+ /* Can match with a multibyte character (and multi character
+ collating element). */
+ unsigned char const *nextp;
+
+ SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p);
+
+ nextp = p;
+ s = transit_state(d, s, &nextp);
+ p = (unsigned char *)nextp;
+
+ /* Trans table might be updated. */
+ trans = d->trans;
+ }
+ else
+ {
+ SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p);
+ s = t[*p++];
+ }
+ }
+ else
+#endif /* MBS_SUPPORT */
+ while ((t = trans[s]) != 0) { /* hand-optimized loop */
+ s1 = t[*p++];
+ if ((t = trans[s1]) == 0) {
+ tmp = s ; s = s1 ; s1 = tmp ; /* swap */
+ break;
+ }
+ s = t[*p++];
+ }
+
+ if (s >= 0 && p <= (unsigned char *) end && d->fails[s])
+ {
+ if (d->success[s] & sbit[*p])
+ {
+ if (backref)
+ *backref = (d->states[s].backref != 0);
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ free(mblen_buf);
+ free(inputwcs);
+ }
+#endif /* MBS_SUPPORT */
+ return (char *) p;
+ }
+
+ s1 = s;
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ unsigned char const *nextp;
+ nextp = p;
+ s = transit_state(d, s, &nextp);
+ p = (unsigned char *)nextp;
+
+ /* Trans table might be updated. */
+ trans = d->trans;
+ }
+ else
+#endif /* MBS_SUPPORT */
+ s = d->fails[s][*p++];
+ continue;
+ }
+
+ /* If the previous character was a newline, count it. */
+ if (count && (char *) p <= end && p[-1] == eol)
+ ++*count;
+
+ /* Check if we've run off the end of the buffer. */
+ if ((char *) p > end)
+ {
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ free(mblen_buf);
+ free(inputwcs);
+ }
+#endif /* MBS_SUPPORT */
+ return NULL;
+ }
+
+ if (s >= 0)
+ {
+ build_state(s, d);
+ trans = d->trans;
+ continue;
+ }
+
+ if (p[-1] == eol && newline)
+ {
+ s = d->newlines[s1];
+ continue;
+ }
+
+ s = 0;
+ }
+}
+
+/* Initialize the components of a dfa that the other routines don't
+ initialize for themselves. */
+void
+dfainit (struct dfa *d)
+{
+ d->calloc = 1;
+ MALLOC(d->charclasses, charclass, d->calloc);
+ d->cindex = 0;
+
+ d->talloc = 1;
+ MALLOC(d->tokens, token, d->talloc);
+ d->tindex = d->depth = d->nleaves = d->nregexps = 0;
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ d->nmultibyte_prop = 1;
+ MALLOC(d->multibyte_prop, int, d->nmultibyte_prop);
+ d->nmbcsets = 0;
+ d->mbcsets_alloc = 1;
+ MALLOC(d->mbcsets, struct mb_char_classes, d->mbcsets_alloc);
+ }
+#endif
+
+ d->searchflag = 0;
+ d->tralloc = 0;
+
+ d->musts = 0;
+ d->realtrans = 0;
+ d->fails = 0;
+ d->newlines = 0;
+ d->success = 0;
+}
+
+/* Parse and analyze a single string of the given length. */
+void
+dfacomp (char const *s, size_t len, struct dfa *d, int searchflag)
+{
+ if (case_fold) /* dummy folding in service of dfamust() */
+ {
+ char *lcopy;
+ int i;
+
+ lcopy = malloc(len);
+ if (!lcopy)
+ dfaerror(_("memory exhausted"));
+
+ /* This is a kludge. */
+ case_fold = 0;
+ for (i = 0; i < len; ++i)
+ if (ISUPPER ((unsigned char) s[i]))
+ lcopy[i] = tolower ((unsigned char) s[i]);
+ else
+ lcopy[i] = s[i];
+
+ dfainit(d);
+ dfaparse(lcopy, len, d);
+ free(lcopy);
+ dfamust(d);
+ d->cindex = d->tindex = d->depth = d->nleaves = d->nregexps = 0;
+ case_fold = 1;
+ dfaparse(s, len, d);
+ dfaanalyze(d, searchflag);
+ }
+ else
+ {
+ dfainit(d);
+ dfaparse(s, len, d);
+ dfamust(d);
+ dfaanalyze(d, searchflag);
+ }
+}
+
+/* Free the storage held by the components of a dfa. */
+void
+dfafree (struct dfa *d)
+{
+ int i;
+ struct dfamust *dm, *ndm;
+
+ free((ptr_t) d->charclasses);
+ free((ptr_t) d->tokens);
+
+#ifdef MBS_SUPPORT
+ if (MB_CUR_MAX > 1)
+ {
+ free((ptr_t) d->multibyte_prop);
+ for (i = 0; i < d->nmbcsets; ++i)
+ {
+ int j;
+ struct mb_char_classes *p = &(d->mbcsets[i]);
+ if (p->chars != NULL)
+ free(p->chars);
+ if (p->ch_classes != NULL)
+ free(p->ch_classes);
+ if (p->range_sts != NULL)
+ free(p->range_sts);
+ if (p->range_ends != NULL)
+ free(p->range_ends);
+
+ for (j = 0; j < p->nequivs; ++j)
+ free(p->equivs[j]);
+ if (p->equivs != NULL)
+ free(p->equivs);
+
+ for (j = 0; j < p->ncoll_elems; ++j)
+ free(p->coll_elems[j]);
+ if (p->coll_elems != NULL)
+ free(p->coll_elems);
+ }
+ free((ptr_t) d->mbcsets);
+ }
+#endif /* MBS_SUPPORT */
+
+ for (i = 0; i < d->sindex; ++i)
+ free((ptr_t) d->states[i].elems.elems);
+ free((ptr_t) d->states);
+ for (i = 0; i < d->tindex; ++i)
+ if (d->follows[i].elems)
+ free((ptr_t) d->follows[i].elems);
+ free((ptr_t) d->follows);
+ for (i = 0; i < d->tralloc; ++i)
+ if (d->trans[i])
+ free((ptr_t) d->trans[i]);
+ else if (d->fails[i])
+ free((ptr_t) d->fails[i]);
+ if (d->realtrans) free((ptr_t) d->realtrans);
+ if (d->fails) free((ptr_t) d->fails);
+ if (d->newlines) free((ptr_t) d->newlines);
+ if (d->success) free((ptr_t) d->success);
+ for (dm = d->musts; dm; dm = ndm)
+ {
+ ndm = dm->next;
+ free(dm->must);
+ free((ptr_t) dm);
+ }
+}
+
+/* Having found the postfix representation of the regular expression,
+ try to find a long sequence of characters that must appear in any line
+ containing the r.e.
+ Finding a "longest" sequence is beyond the scope here;
+ we take an easy way out and hope for the best.
+ (Take "(ab|a)b"--please.)
+
+ We do a bottom-up calculation of sequences of characters that must appear
+ in matches of r.e.'s represented by trees rooted at the nodes of the postfix
+ representation:
+ sequences that must appear at the left of the match ("left")
+ sequences that must appear at the right of the match ("right")
+ lists of sequences that must appear somewhere in the match ("in")
+ sequences that must constitute the match ("is")
+
+ When we get to the root of the tree, we use one of the longest of its
+ calculated "in" sequences as our answer. The sequence we find is returned in
+ d->must (where "d" is the single argument passed to "dfamust");
+ the length of the sequence is returned in d->mustn.
+
+ The sequences calculated for the various types of node (in pseudo ANSI c)
+ are shown below. "p" is the operand of unary operators (and the left-hand
+ operand of binary operators); "q" is the right-hand operand of binary
+ operators.
+
+ "ZERO" means "a zero-length sequence" below.
+
+ Type left right is in
+ ---- ---- ----- -- --
+ char c # c # c # c # c
+
+ ANYCHAR ZERO ZERO ZERO ZERO
+
+ MBCSET ZERO ZERO ZERO ZERO
+
+ CSET ZERO ZERO ZERO ZERO
+
+ STAR ZERO ZERO ZERO ZERO
+
+ QMARK ZERO ZERO ZERO ZERO
+
+ PLUS p->left p->right ZERO p->in
+
+ CAT (p->is==ZERO)? (q->is==ZERO)? (p->is!=ZERO && p->in plus
+ p->left : q->right : q->is!=ZERO) ? q->in plus
+ p->is##q->left p->right##q->is p->is##q->is : p->right##q->left
+ ZERO
+
+ OR longest common longest common (do p->is and substrings common to
+ leading trailing q->is have same p->in and q->in
+ (sub)sequence (sub)sequence length and
+ of p->left of p->right content) ?
+ and q->left and q->right p->is : NULL
+
+ If there's anything else we recognize in the tree, all four sequences get set
+ to zero-length sequences. If there's something we don't recognize in the tree,
+ we just return a zero-length sequence.
+
+ Break ties in favor of infrequent letters (choosing 'zzz' in preference to
+ 'aaa')?
+
+ And. . .is it here or someplace that we might ponder "optimizations" such as
+ egrep 'psi|epsilon' -> egrep 'psi'
+ egrep 'pepsi|epsilon' -> egrep 'epsi'
+ (Yes, we now find "epsi" as a "string
+ that must occur", but we might also
+ simplify the *entire* r.e. being sought)
+ grep '[c]' -> grep 'c'
+ grep '(ab|a)b' -> grep 'ab'
+ grep 'ab*' -> grep 'a'
+ grep 'a*b' -> grep 'b'
+
+ There are several issues:
+
+ Is optimization easy (enough)?
+
+ Does optimization actually accomplish anything,
+ or is the automaton you get from "psi|epsilon" (for example)
+ the same as the one you get from "psi" (for example)?
+
+ Are optimizable r.e.'s likely to be used in real-life situations
+ (something like 'ab*' is probably unlikely; something like is
+ 'psi|epsilon' is likelier)? */
+
+static char *
+icatalloc (char *old, char *new)
+{
+ char *result;
+ size_t oldsize, newsize;
+
+ newsize = (new == NULL) ? 0 : strlen(new);
+ if (old == NULL)
+ oldsize = 0;
+ else if (newsize == 0)
+ return old;
+ else oldsize = strlen(old);
+ if (old == NULL)
+ result = (char *) malloc(newsize + 1);
+ else
+ result = (char *) realloc((void *) old, oldsize + newsize + 1);
+ if (result != NULL && new != NULL)
+ (void) strcpy(result + oldsize, new);
+ return result;
+}
+
+static char *
+icpyalloc (char *string)
+{
+ return icatalloc((char *) NULL, string);
+}
+
+static char *
+istrstr (char *lookin, char *lookfor)
+{
+ char *cp;
+ size_t len;
+
+ len = strlen(lookfor);
+ for (cp = lookin; *cp != '\0'; ++cp)
+ if (strncmp(cp, lookfor, len) == 0)
+ return cp;
+ return NULL;
+}
+
+static void
+ifree (char *cp)
+{
+ if (cp != NULL)
+ free(cp);
+}
+
+static void
+freelist (char **cpp)
+{
+ int i;
+
+ if (cpp == NULL)
+ return;
+ for (i = 0; cpp[i] != NULL; ++i)
+ {
+ free(cpp[i]);
+ cpp[i] = NULL;
+ }
+}
+
+static char **
+enlist (char **cpp, char *new, size_t len)
+{
+ int i, j;
+
+ if (cpp == NULL)
+ return NULL;
+ if ((new = icpyalloc(new)) == NULL)
+ {
+ freelist(cpp);
+ return NULL;
+ }
+ new[len] = '\0';
+ /* Is there already something in the list that's new (or longer)? */
+ for (i = 0; cpp[i] != NULL; ++i)
+ if (istrstr(cpp[i], new) != NULL)
+ {
+ free(new);
+ return cpp;
+ }
+ /* Eliminate any obsoleted strings. */
+ j = 0;
+ while (cpp[j] != NULL)
+ if (istrstr(new, cpp[j]) == NULL)
+ ++j;
+ else
+ {
+ free(cpp[j]);
+ if (--i == j)
+ break;
+ cpp[j] = cpp[i];
+ cpp[i] = NULL;
+ }
+ /* Add the new string. */
+ cpp = (char **) realloc((char *) cpp, (i + 2) * sizeof *cpp);
+ if (cpp == NULL)
+ return NULL;
+ cpp[i] = new;
+ cpp[i + 1] = NULL;
+ return cpp;
+}
+
+/* Given pointers to two strings, return a pointer to an allocated
+ list of their distinct common substrings. Return NULL if something
+ seems wild. */
+static char **
+comsubs (char *left, char *right)
+{
+ char **cpp;
+ char *lcp;
+ char *rcp;
+ size_t i, len;
+
+ if (left == NULL || right == NULL)
+ return NULL;
+ cpp = (char **) malloc(sizeof *cpp);
+ if (cpp == NULL)
+ return NULL;
+ cpp[0] = NULL;
+ for (lcp = left; *lcp != '\0'; ++lcp)
+ {
+ len = 0;
+ rcp = strchr (right, *lcp);
+ while (rcp != NULL)
+ {
+ for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i)
+ continue;
+ if (i > len)
+ len = i;
+ rcp = strchr (rcp + 1, *lcp);
+ }
+ if (len == 0)
+ continue;
+ if ((cpp = enlist(cpp, lcp, len)) == NULL)
+ break;
+ }
+ return cpp;
+}
+
+static char **
+addlists (char **old, char **new)
+{
+ int i;
+
+ if (old == NULL || new == NULL)
+ return NULL;
+ for (i = 0; new[i] != NULL; ++i)
+ {
+ old = enlist(old, new[i], strlen(new[i]));
+ if (old == NULL)
+ break;
+ }
+ return old;
+}
+
+/* Given two lists of substrings, return a new list giving substrings
+ common to both. */
+static char **
+inboth (char **left, char **right)
+{
+ char **both;
+ char **temp;
+ int lnum, rnum;
+
+ if (left == NULL || right == NULL)
+ return NULL;
+ both = (char **) malloc(sizeof *both);
+ if (both == NULL)
+ return NULL;
+ both[0] = NULL;
+ for (lnum = 0; left[lnum] != NULL; ++lnum)
+ {
+ for (rnum = 0; right[rnum] != NULL; ++rnum)
+ {
+ temp = comsubs(left[lnum], right[rnum]);
+ if (temp == NULL)
+ {
+ freelist(both);
+ return NULL;
+ }
+ both = addlists(both, temp);
+ freelist(temp);
+ free(temp);
+ if (both == NULL)
+ return NULL;
+ }
+ }
+ return both;
+}
+
+typedef struct
+{
+ char **in;
+ char *left;
+ char *right;
+ char *is;
+} must;
+
+static void
+resetmust (must *mp)
+{
+ mp->left[0] = mp->right[0] = mp->is[0] = '\0';
+ freelist(mp->in);
+}
+
+static void
+dfamust (struct dfa *dfa)
+{
+ must *musts;
+ must *mp;
+ char *result;
+ int ri;
+ int i;
+ int exact;
+ token t;
+ static must must0;
+ struct dfamust *dm;
+ static char empty_string[] = "";
+
+ result = empty_string;
+ exact = 0;
+ musts = (must *) malloc((dfa->tindex + 1) * sizeof *musts);
+ if (musts == NULL)
+ return;
+ mp = musts;
+ for (i = 0; i <= dfa->tindex; ++i)
+ mp[i] = must0;
+ for (i = 0; i <= dfa->tindex; ++i)
+ {
+ mp[i].in = (char **) malloc(sizeof *mp[i].in);
+ mp[i].left = malloc(2);
+ mp[i].right = malloc(2);
+ mp[i].is = malloc(2);
+ if (mp[i].in == NULL || mp[i].left == NULL ||
+ mp[i].right == NULL || mp[i].is == NULL)
+ goto done;
+ mp[i].left[0] = mp[i].right[0] = mp[i].is[0] = '\0';
+ mp[i].in[0] = NULL;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "dfamust:\n");
+ for (i = 0; i < dfa->tindex; ++i)
+ {
+ fprintf(stderr, " %d:", i);
+ prtok(dfa->tokens[i]);
+ }
+ putc('\n', stderr);
+#endif
+ for (ri = 0; ri < dfa->tindex; ++ri)
+ {
+ switch (t = dfa->tokens[ri])
+ {
+ case LPAREN:
+ case RPAREN:
+ goto done; /* "cannot happen" */
+ case EMPTY:
+ case BEGLINE:
+ case ENDLINE:
+ case BEGWORD:
+ case ENDWORD:
+ case LIMWORD:
+ case NOTLIMWORD:
+ case BACKREF:
+ resetmust(mp);
+ break;
+ case STAR:
+ case QMARK:
+ if (mp <= musts)
+ goto done; /* "cannot happen" */
+ --mp;
+ resetmust(mp);
+ break;
+ case OR:
+ case ORTOP:
+ if (mp < &musts[2])
+ goto done; /* "cannot happen" */
+ {
+ char **new;
+ must *lmp;
+ must *rmp;
+ int j, ln, rn, n;
+
+ rmp = --mp;
+ lmp = --mp;
+ /* Guaranteed to be. Unlikely, but. . . */
+ if (strcmp(lmp->is, rmp->is) != 0)
+ lmp->is[0] = '\0';
+ /* Left side--easy */
+ i = 0;
+ while (lmp->left[i] != '\0' && lmp->left[i] == rmp->left[i])
+ ++i;
+ lmp->left[i] = '\0';
+ /* Right side */
+ ln = strlen(lmp->right);
+ rn = strlen(rmp->right);
+ n = ln;
+ if (n > rn)
+ n = rn;
+ for (i = 0; i < n; ++i)
+ if (lmp->right[ln - i - 1] != rmp->right[rn - i - 1])
+ break;
+ for (j = 0; j < i; ++j)
+ lmp->right[j] = lmp->right[(ln - i) + j];
+ lmp->right[j] = '\0';
+ new = inboth(lmp->in, rmp->in);
+ if (new == NULL)
+ goto done;
+ freelist(lmp->in);
+ free((char *) lmp->in);
+ lmp->in = new;
+ }
+ break;
+ case PLUS:
+ if (mp <= musts)
+ goto done; /* "cannot happen" */
+ --mp;
+ mp->is[0] = '\0';
+ break;
+ case END:
+ if (mp != &musts[1])
+ goto done; /* "cannot happen" */
+ for (i = 0; musts[0].in[i] != NULL; ++i)
+ if (strlen(musts[0].in[i]) > strlen(result))
+ result = musts[0].in[i];
+ if (strcmp(result, musts[0].is) == 0)
+ exact = 1;
+ goto done;
+ case CAT:
+ if (mp < &musts[2])
+ goto done; /* "cannot happen" */
+ {
+ must *lmp;
+ must *rmp;
+
+ rmp = --mp;
+ lmp = --mp;
+ /* In. Everything in left, plus everything in
+ right, plus catenation of
+ left's right and right's left. */
+ lmp->in = addlists(lmp->in, rmp->in);
+ if (lmp->in == NULL)
+ goto done;
+ if (lmp->right[0] != '\0' &&
+ rmp->left[0] != '\0')
+ {
+ char *tp;
+
+ tp = icpyalloc(lmp->right);
+ if (tp == NULL)
+ goto done;
+ tp = icatalloc(tp, rmp->left);
+ if (tp == NULL)
+ goto done;
+ lmp->in = enlist(lmp->in, tp,
+ strlen(tp));
+ free(tp);
+ if (lmp->in == NULL)
+ goto done;
+ }
+ /* Left-hand */
+ if (lmp->is[0] != '\0')
+ {
+ lmp->left = icatalloc(lmp->left,
+ rmp->left);
+ if (lmp->left == NULL)
+ goto done;
+ }
+ /* Right-hand */
+ if (rmp->is[0] == '\0')
+ lmp->right[0] = '\0';
+ lmp->right = icatalloc(lmp->right, rmp->right);
+ if (lmp->right == NULL)
+ goto done;
+ /* Guaranteed to be */
+ if (lmp->is[0] != '\0' && rmp->is[0] != '\0')
+ {
+ lmp->is = icatalloc(lmp->is, rmp->is);
+ if (lmp->is == NULL)
+ goto done;
+ }
+ else
+ lmp->is[0] = '\0';
+ }
+ break;
+ default:
+ if (t < END)
+ {
+ /* "cannot happen" */
+ goto done;
+ }
+ else if (t == '\0')
+ {
+ /* not on *my* shift */
+ goto done;
+ }
+ else if (t >= CSET
+#ifdef MBS_SUPPORT
+ || t == ANYCHAR
+ || t == MBCSET
+#endif /* MBS_SUPPORT */
+ )
+ {
+ /* easy enough */
+ resetmust(mp);
+ }
+ else
+ {
+ /* plain character */
+ resetmust(mp);
+ mp->is[0] = mp->left[0] = mp->right[0] = t;
+ mp->is[1] = mp->left[1] = mp->right[1] = '\0';
+ mp->in = enlist(mp->in, mp->is, (size_t)1);
+ if (mp->in == NULL)
+ goto done;
+ }
+ break;
+ }
+#ifdef DEBUG
+ fprintf(stderr, " node: %d:", ri);
+ prtok(dfa->tokens[ri]);
+ fprintf(stderr, "\n in:");
+ for (i = 0; mp->in[i]; ++i)
+ fprintf(stderr, " \"%s\"", mp->in[i]);
+ fprintf(stderr, "\n is: \"%s\"\n", mp->is);
+ fprintf(stderr, " left: \"%s\"\n", mp->left);
+ fprintf(stderr, " right: \"%s\"\n", mp->right);
+#endif
+ ++mp;
+ }
+ done:
+ if (strlen(result))
+ {
+ MALLOC(dm, struct dfamust, 1);
+ dm->exact = exact;
+ MALLOC(dm->must, char, strlen(result) + 1);
+ strcpy(dm->must, result);
+ dm->next = dfa->musts;
+ dfa->musts = dm;
+ }
+ mp = musts;
+ for (i = 0; i <= dfa->tindex; ++i)
+ {
+ freelist(mp[i].in);
+ ifree((char *) mp[i].in);
+ ifree(mp[i].left);
+ ifree(mp[i].right);
+ ifree(mp[i].is);
+ }
+ free((char *) mp);
+}
+/* vim:set shiftwidth=2: */
--- /dev/null
+/* dfa.h - declarations for GNU deterministic regexp compiler
+ Copyright (C) 1988, 1998, 2002, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
+
+/* Written June, 1988 by Mike Haertel */
+
+/* FIXME:
+ 2. We should not export so much of the DFA internals.
+ In addition to clobbering modularity, we eat up valuable
+ name space. */
+
+#ifdef __STDC__
+# ifndef _PTR_T
+# define _PTR_T
+ typedef void * ptr_t;
+# endif
+#else
+# ifndef _PTR_T
+# define _PTR_T
+ typedef char * ptr_t;
+# endif
+#endif
+
+#ifdef PARAMS
+# undef PARAMS
+#endif
+#if PROTOTYPES
+# define PARAMS(x) x
+#else
+# define PARAMS(x) ()
+#endif
+
+/* Number of bits in an unsigned char. */
+#ifndef CHARBITS
+#define CHARBITS 8
+#endif
+
+/* First integer value that is greater than any character code. */
+#define NOTCHAR (1 << CHARBITS)
+
+/* INTBITS need not be exact, just a lower bound. */
+#ifndef INTBITS
+#define INTBITS (CHARBITS * sizeof (int))
+#endif
+
+/* Number of ints required to hold a bit for every character. */
+#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS)
+
+/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
+typedef int charclass[CHARCLASS_INTS];
+
+/* The regexp is parsed into an array of tokens in postfix form. Some tokens
+ are operators and others are terminal symbols. Most (but not all) of these
+ codes are returned by the lexical analyzer. */
+
+typedef enum
+{
+ END = -1, /* END is a terminal symbol that matches the
+ end of input; any value of END or less in
+ the parse tree is such a symbol. Accepting
+ states of the DFA are those that would have
+ a transition on END. */
+
+ /* Ordinary character values are terminal symbols that match themselves. */
+
+ EMPTY = NOTCHAR, /* EMPTY is a terminal symbol that matches
+ the empty string. */
+
+ BACKREF, /* BACKREF is generated by \<digit>; it
+ it not completely handled. If the scanner
+ detects a transition on backref, it returns
+ a kind of "semi-success" indicating that
+ the match will have to be verified with
+ a backtracking matcher. */
+
+ BEGLINE, /* BEGLINE is a terminal symbol that matches
+ the empty string if it is at the beginning
+ of a line. */
+
+ ENDLINE, /* ENDLINE is a terminal symbol that matches
+ the empty string if it is at the end of
+ a line. */
+
+ BEGWORD, /* BEGWORD is a terminal symbol that matches
+ the empty string if it is at the beginning
+ of a word. */
+
+ ENDWORD, /* ENDWORD is a terminal symbol that matches
+ the empty string if it is at the end of
+ a word. */
+
+ LIMWORD, /* LIMWORD is a terminal symbol that matches
+ the empty string if it is at the beginning
+ or the end of a word. */
+
+ NOTLIMWORD, /* NOTLIMWORD is a terminal symbol that
+ matches the empty string if it is not at
+ the beginning or end of a word. */
+
+ QMARK, /* QMARK is an operator of one argument that
+ matches zero or one occurences of its
+ argument. */
+
+ STAR, /* STAR is an operator of one argument that
+ matches the Kleene closure (zero or more
+ occurrences) of its argument. */
+
+ PLUS, /* PLUS is an operator of one argument that
+ matches the positive closure (one or more
+ occurrences) of its argument. */
+
+ REPMN, /* REPMN is a lexical token corresponding
+ to the {m,n} construct. REPMN never
+ appears in the compiled token vector. */
+
+ CAT, /* CAT is an operator of two arguments that
+ matches the concatenation of its
+ arguments. CAT is never returned by the
+ lexical analyzer. */
+
+ OR, /* OR is an operator of two arguments that
+ matches either of its arguments. */
+
+ ORTOP, /* OR at the toplevel in the parse tree.
+ This is used for a boyer-moore heuristic. */
+
+ LPAREN, /* LPAREN never appears in the parse tree,
+ it is only a lexeme. */
+
+ RPAREN, /* RPAREN never appears in the parse tree. */
+
+ CRANGE, /* CRANGE never appears in the parse tree.
+ It stands for a character range that can
+ match a string of one or more characters.
+ For example, [a-z] can match "ch" in
+ a Spanish locale. */
+
+#ifdef MBS_SUPPORT
+ ANYCHAR, /* ANYCHAR is a terminal symbol that matches
+ any multibyte (or single byte) characters.
+ It is used only if MB_CUR_MAX > 1. */
+
+ MBCSET, /* MBCSET is similar to CSET, but for
+ multibyte characters. */
+#endif /* MBS_SUPPORT */
+
+ CSET /* CSET and (and any value greater) is a
+ terminal symbol that matches any of a
+ class of characters. */
+} token;
+
+/* Sets are stored in an array in the compiled dfa; the index of the
+ array corresponding to a given set token is given by SET_INDEX(t). */
+#define SET_INDEX(t) ((t) - CSET)
+
+/* Sometimes characters can only be matched depending on the surrounding
+ context. Such context decisions depend on what the previous character
+ was, and the value of the current (lookahead) character. Context
+ dependent constraints are encoded as 8 bit integers. Each bit that
+ is set indicates that the constraint succeeds in the corresponding
+ context.
+
+ bit 7 - previous and current are newlines
+ bit 6 - previous was newline, current isn't
+ bit 5 - previous wasn't newline, current is
+ bit 4 - neither previous nor current is a newline
+ bit 3 - previous and current are word-constituents
+ bit 2 - previous was word-constituent, current isn't
+ bit 1 - previous wasn't word-constituent, current is
+ bit 0 - neither previous nor current is word-constituent
+
+ Word-constituent characters are those that satisfy isalnum().
+
+ The macro SUCCEEDS_IN_CONTEXT determines whether a a given constraint
+ succeeds in a particular context. Prevn is true if the previous character
+ was a newline, currn is true if the lookahead character is a newline.
+ Prevl and currl similarly depend upon whether the previous and current
+ characters are word-constituent letters. */
+#define MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \
+ ((constraint) & 1 << (((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4))
+#define MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \
+ ((constraint) & 1 << (((prevl) ? 2 : 0) + ((currl) ? 1 : 0)))
+#define SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \
+ (MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \
+ && MATCHES_LETTER_CONTEXT(constraint, prevl, currl))
+
+/* The following macros give information about what a constraint depends on. */
+#define PREV_NEWLINE_DEPENDENT(constraint) \
+ (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30))
+#define PREV_LETTER_DEPENDENT(constraint) \
+ (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03))
+
+/* Tokens that match the empty string subject to some constraint actually
+ work by applying that constraint to determine what may follow them,
+ taking into account what has gone before. The following values are
+ the constraints corresponding to the special tokens previously defined. */
+#define NO_CONSTRAINT 0xff
+#define BEGLINE_CONSTRAINT 0xcf
+#define ENDLINE_CONSTRAINT 0xaf
+#define BEGWORD_CONSTRAINT 0xf2
+#define ENDWORD_CONSTRAINT 0xf4
+#define LIMWORD_CONSTRAINT 0xf6
+#define NOTLIMWORD_CONSTRAINT 0xf9
+
+/* States of the recognizer correspond to sets of positions in the parse
+ tree, together with the constraints under which they may be matched.
+ So a position is encoded as an index into the parse tree together with
+ a constraint. */
+typedef struct
+{
+ unsigned index; /* Index into the parse array. */
+ unsigned constraint; /* Constraint for matching this position. */
+} position;
+
+/* Sets of positions are stored as arrays. */
+typedef struct
+{
+ position *elems; /* Elements of this position set. */
+ int nelem; /* Number of elements in this set. */
+} position_set;
+
+/* A state of the dfa consists of a set of positions, some flags,
+ and the token value of the lowest-numbered position of the state that
+ contains an END token. */
+typedef struct
+{
+ int hash; /* Hash of the positions of this state. */
+ position_set elems; /* Positions this state could match. */
+ char newline; /* True if previous state matched newline. */
+ char letter; /* True if previous state matched a letter. */
+ char backref; /* True if this state matches a \<digit>. */
+ unsigned char constraint; /* Constraint for this state to accept. */
+ int first_end; /* Token value of the first END in elems. */
+#ifdef MBS_SUPPORT
+ position_set mbps; /* Positions which can match multibyte
+ characters. e.g. period.
+ These staff are used only if
+ MB_CUR_MAX > 1. */
+#endif
+} dfa_state;
+
+/* Element of a list of strings, at least one of which is known to
+ appear in any R.E. matching the DFA. */
+struct dfamust
+{
+ int exact;
+ char *must;
+ struct dfamust *next;
+};
+
+#ifdef MBS_SUPPORT
+/* A bracket operator.
+ e.g. [a-c], [[:alpha:]], etc. */
+struct mb_char_classes
+{
+ int invert;
+ wchar_t *chars; /* Normal characters. */
+ int nchars;
+ wctype_t *ch_classes; /* Character classes. */
+ int nch_classes;
+ wchar_t *range_sts; /* Range characters (start of the range). */
+ wchar_t *range_ends; /* Range characters (end of the range). */
+ int nranges;
+ char **equivs; /* Equivalent classes. */
+ int nequivs;
+ char **coll_elems;
+ int ncoll_elems; /* Collating elements. */
+};
+#endif
+
+/* A compiled regular expression. */
+struct dfa
+{
+ /* Stuff built by the scanner. */
+ charclass *charclasses; /* Array of character sets for CSET tokens. */
+ int cindex; /* Index for adding new charclasses. */
+ int calloc; /* Number of charclasses currently allocated. */
+
+ /* Stuff built by the parser. */
+ token *tokens; /* Postfix parse array. */
+ int tindex; /* Index for adding new tokens. */
+ int talloc; /* Number of tokens currently allocated. */
+ int depth; /* Depth required of an evaluation stack
+ used for depth-first traversal of the
+ parse tree. */
+ int nleaves; /* Number of leaves on the parse tree. */
+ int nregexps; /* Count of parallel regexps being built
+ with dfaparse(). */
+#ifdef MBS_SUPPORT
+ /* These stuff are used only if MB_CUR_MAX > 1 or multibyte environments. */
+ int nmultibyte_prop;
+ int *multibyte_prop;
+ /* The value of multibyte_prop[i] is defined by following rule.
+ if tokens[i] < NOTCHAR
+ bit 1 : tokens[i] is a single byte character, or the last-byte of
+ a multibyte character.
+ bit 0 : tokens[i] is a single byte character, or the 1st-byte of
+ a multibyte character.
+ if tokens[i] = MBCSET
+ ("the index of mbcsets correspnd to this operator" << 2) + 3
+
+ e.g.
+ tokens
+ = 'single_byte_a', 'multi_byte_A', single_byte_b'
+ = 'sb_a', 'mb_A(1st byte)', 'mb_A(2nd byte)', 'mb_A(3rd byte)', 'sb_b'
+ multibyte_prop
+ = 3 , 1 , 0 , 2 , 3
+ */
+
+ /* Array of the bracket expressoin in the DFA. */
+ struct mb_char_classes *mbcsets;
+ int nmbcsets;
+ int mbcsets_alloc;
+#endif
+
+ /* Stuff owned by the state builder. */
+ dfa_state *states; /* States of the dfa. */
+ int sindex; /* Index for adding new states. */
+ int salloc; /* Number of states currently allocated. */
+
+ /* Stuff built by the structure analyzer. */
+ position_set *follows; /* Array of follow sets, indexed by position
+ index. The follow of a position is the set
+ of positions containing characters that
+ could conceivably follow a character
+ matching the given position in a string
+ matching the regexp. Allocated to the
+ maximum possible position index. */
+ int searchflag; /* True if we are supposed to build a searching
+ as opposed to an exact matcher. A searching
+ matcher finds the first and shortest string
+ matching a regexp anywhere in the buffer,
+ whereas an exact matcher finds the longest
+ string matching, but anchored to the
+ beginning of the buffer. */
+
+ /* Stuff owned by the executor. */
+ int tralloc; /* Number of transition tables that have
+ slots so far. */
+ int trcount; /* Number of transition tables that have
+ actually been built. */
+ int **trans; /* Transition tables for states that can
+ never accept. If the transitions for a
+ state have not yet been computed, or the
+ state could possibly accept, its entry in
+ this table is NULL. */
+ int **realtrans; /* Trans always points to realtrans + 1; this
+ is so trans[-1] can contain NULL. */
+ int **fails; /* Transition tables after failing to accept
+ on a state that potentially could do so. */
+ int *success; /* Table of acceptance conditions used in
+ dfaexec and computed in build_state. */
+ int *newlines; /* Transitions on newlines. The entry for a
+ newline in any transition table is always
+ -1 so we can count lines without wasting
+ too many cycles. The transition for a
+ newline is stored separately and handled
+ as a special case. Newline is also used
+ as a sentinel at the end of the buffer. */
+ struct dfamust *musts; /* List of strings, at least one of which
+ is known to appear in any r.e. matching
+ the dfa. */
+};
+
+/* Some macros for user access to dfa internals. */
+
+/* ACCEPTING returns true if s could possibly be an accepting state of r. */
+#define ACCEPTING(s, r) ((r).states[s].constraint)
+
+/* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the
+ specified context. */
+#define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, dfa) \
+ SUCCEEDS_IN_CONTEXT((dfa).states[state].constraint, \
+ prevn, currn, prevl, currl)
+
+/* FIRST_MATCHING_REGEXP returns the index number of the first of parallel
+ regexps that a given state could accept. Parallel regexps are numbered
+ starting at 1. */
+#define FIRST_MATCHING_REGEXP(state, dfa) (-(dfa).states[state].first_end)
+
+/* Entry points. */
+
+/* dfasyntax() takes three arguments; the first sets the syntax bits described
+ earlier in this file, the second sets the case-folding flag, and the
+ third specifies the line terminator. */
+extern void dfasyntax PARAMS ((reg_syntax_t, int, unsigned char));
+
+/* Compile the given string of the given length into the given struct dfa.
+ Final argument is a flag specifying whether to build a searching or an
+ exact matcher. */
+extern void dfacomp PARAMS ((char const *, size_t, struct dfa *, int));
+
+/* Execute the given struct dfa on the buffer of characters. The
+ first char * points to the beginning, and the second points to the
+ first character after the end of the buffer, which must be a writable
+ place so a sentinel end-of-buffer marker can be stored there. The
+ second-to-last argument is a flag telling whether to allow newlines to
+ be part of a string matching the regexp. The next-to-last argument,
+ if non-NULL, points to a place to increment every time we see a
+ newline. The final argument, if non-NULL, points to a flag that will
+ be set if further examination by a backtracking matcher is needed in
+ order to verify backreferencing; otherwise the flag will be cleared.
+ Returns NULL if no match is found, or a pointer to the first
+ character after the first & shortest matching string in the buffer. */
+extern char *dfaexec PARAMS ((struct dfa *, char const *, char *, int, int *, int *));
+
+/* Free the storage held by the components of a struct dfa. */
+extern void dfafree PARAMS ((struct dfa *));
+
+/* Entry points for people who know what they're doing. */
+
+/* Initialize the components of a struct dfa. */
+extern void dfainit PARAMS ((struct dfa *));
+
+/* Incrementally parse a string of given length into a struct dfa. */
+extern void dfaparse PARAMS ((char const *, size_t, struct dfa *));
+
+/* Analyze a parsed regexp; second argument tells whether to build a searching
+ or an exact matcher. */
+extern void dfaanalyze PARAMS ((struct dfa *, int));
+
+/* Compute, for each possible character, the transitions out of a given
+ state, storing them in an array of integers. */
+extern void dfastate PARAMS ((int, struct dfa *, int []));
+
+/* Error handling. */
+
+/* dfaerror() is called by the regexp routines whenever an error occurs. It
+ takes a single argument, a NUL-terminated string describing the error.
+ The user must supply a dfaerror. */
+extern void dfaerror PARAMS ((const char *));
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Sun Jun 26 16:24:07 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Document `length(array)'.
+ * gawk.1: Ditto.
+ * awkcard.in: Ditto.
+
+Mon May 23 20:56:32 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Removed references to `--with-included-gettext'.
+
+Fri Apr 1 06:25:30 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2005-01-30.17.
+
+Wed Feb 9 11:39:38 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Per Stepan Kasal, removed html rules, since
+ Automake does it for us.
+
+Tue Jan 4 18:47:34 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2004-11-25.16.
+
+Mon Jan 3 14:09:57 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2004-10-31.06.
+
+Wed Sep 22 11:40:06 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1, gawk.texi, awkcard.in: Documented new --exec option.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Wed Jul 28 17:03:16 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (TROFF): Add -U flag to invocation. Makes it
+ possible to format ref card from a build directory that isn't
+ the source directory.
+ (distclean): Removed target. Let automake handle it.
+
+Tue Jun 15 12:21:09 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2004-06-14.14.
+ * gawk.texi (Dynamic Extensions): Text revised to follow
+ current implementation: new APIs, info on `n->param_cnt'
+ fixed.
+
+ Also in all index entries where comma does not separate
+ primary, secondary or tertiary terms, replaced the comma
+ with @comma{} and removed the corresponding comments.
+
+Mon May 31 09:11:01 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ad.block, awkcard.in, cardfonts, colors, no.colors: Change
+ old email address to current one.
+
+Mon May 3 09:54:46 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version from Automake 1.8.4.
+
+Mon Mar 22 10:53:13 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated.
+
+Tue Jan 6 17:38:40 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated.
+ * gawk.texi: All @strong{Note:} changed to `@quotation NOTE'.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Mon Jun 9 16:06:30 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Set automatic-xref-title and change all cross
+ references to be of the single-argument type. Made all
+ @node lines have just the node name.
+
+ Should have done both of these years ago.
+
+Sun May 11 16:08:58 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (html, gawk.html, gawkinet.html): New targets.
+
+Mon Mar 31 17:15:23 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (install-data-hook, uninstall-hook): Added code to
+ hard link gawk.1 to pgawk.1 upon install and remove pgawk.1 upon
+ uninstall. Avoids MANPATH search problems, etc. etc.
+ (man_MANS): Removed pgawk.1 from the list.
+ * pgawk.1: Removed.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Tue Mar 11 11:22:36 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (man_MANS): Add pgawk.1.
+ * pgawk.1: New file, does `.so gawk.1' so that `man pgawk' will work.
+ Thanks to Nelson Beebe for pointing the need for this.
+
+Sun Feb 9 09:45:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawkinet.texi: Per Karl Berry, change dircategory
+ to follow current standards. In gawkinet.texi, remove
+ bracketing ifinfo.
+
+Thu Feb 6 12:06:22 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2003-02-03.16 from Texinfo 4.5.
+
+Tue Feb 4 15:21:46 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkcard.in: Redid the page-breaking.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Sun Jan 26 11:13:01 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2003-01-24.17 from prep.
+ * gawk.texi: Documented asorti(), new elements in match() 3rd arg,
+ misc cleanups. Updated to FDL 1.2.
+ * awkcard.in, gawk.1: Ditto for asorti(), match().
+ * gawkinet.texi: Updated to FDL 1.2.
+
+Thu Jan 16 18:34:54 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2003-01-12.11 from prep.
+
+Sun Nov 24 17:55:23 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2002-11-05.11 from Texinfo 4.3.
+
+Sun Nov 17 21:34:35 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2002-10-13.14 from automake 1.7.1.
+
+Fri Nov 1 11:25:00 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ From Kaveh Ghazi:
+
+ * gawk.texi (grcat.c): Include stdlib.h.
+ (main): Fix format specifier warnings.
+ * gawk.texi (pwcat.c): Include config.h/stdlib.h.
+ (main): Fix format specifier warnings.
+
+Tue Jun 11 23:08:04 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Fix grcat code ifdef for HAVE_GETGRENT.
+
+2002-05-09 Paul Eggert <eggert@twinsun.com>
+
+ [ ADR: Some minor post-patch editing was required. ]
+
+ * gawk.texi (igawk): Do not put temporary files in /tmp, as that
+ has some security problems. This fixes a problem originally
+ reported by Jarno Huuskonen via solar@openwall.com.
+
+ Fix the following problems with igawk while we're at it.
+
+ * Report missing operands of options; this fixes e.g. an
+ infinite loop with "igawk -W".
+
+ * Check for --source and -Wsource only, not -.source (which matches
+ errors). Similarly for other multichar options.
+
+ * Do not use 'echo', as that mishandles backslashes.
+
+Mon May 13 01:25:40 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkinet.texi: Change `ifinfo' to `ifnottex' around
+ the Top node. Thanks to Eli Zaretskii.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Tue Apr 16 13:26:13 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: FINALLY. All O'Reilly production and
+ indexing changes integrated. Index reviewed and
+ cleaned up.
+ * gawkinet.texi: Ditto.
+ * awkcard.in: Redid page breaking.
+ * Makefile.am (clean): Add `awkcard.tr' to list of files
+ that are removed.
+ (distclean): Depend on clean to REALLY GET `awkcard.tr'.
+ Sheesh.
+
+Mon Apr 15 14:43:51 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version from Texinfo 4.2.
+ * gawk.texi: Modified to use new @copying command.
+ * gawkinet.texi: Ditto.
+
+Wed Mar 20 17:07:50 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version from Texinfo 4.1.
+
+2002-02-10 Paul Eggert <eggert@twinsun.com>
+
+ * gawk.texi (Word Sorting): Don't use sort +1, as POSIX 1003.1-2001
+ no longer allows it. Use sort -k instead.
+
+2002-01-27 Bruno Haible <bruno@clisp.org>
+
+ * gawk.texi: Document the dcngettext function.
+ * awkcard.in: Likewise.
+ * gawk.1: Likewise.
+
+Mon Jan 28 18:41:02 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkinet.texi, Makefile.am: Removed User Friendly cartoon.
+ Sigh.
+
+Wed Dec 19 16:00:39 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawk.texi (Profiling): Describe the signals used for profile
+ dumping in the DJGPP version.
+
+Mon Sep 3 18:30:13 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Top): Put in @ifnottex so that makeinfo
+ --html is now happy.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Mon May 14 19:57:31 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawkinet.texi: Versions for distribution
+ put in place.
+ * gawk.1, awkcard.in: Minor edits for consistency of
+ usage, formatting.
+
+Wed Nov 22 14:57:59 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawk.1, awkcard.in: Removed all documentation
+ of abort.
+
+Sun Aug 13 11:23:50 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawk.1, awkcard.in: documented sort function
+ and optional third argument to match.
+
+Sun Aug 13 00:40:41 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: hardwired publisher info.
+ * publisher.texi: Removed. Not needed any more.
+ * gawkinet.texi: Added title page stuff.
+
+Thu Jul 5 21:05:57 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: moved to use of @command, @option everywhere
+ appropriate. Removed all @page and @group in anticipation
+ of re-page breaking. Updated stuff for install-info.
+ Added FDL.
+
+Tue Nov 10 11:42:26 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * publisher.texi: new file with publisher related info.
+ * Makefile.in: updated dvi and postscript targets to make
+ them lots smarter about not reformatting if need be.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed May 17 19:04:54 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawk.1, awkcard.in: Documented %u. Ooops.
+
+Tue May 2 11:44:13 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 1999-10-01.07.
+ * gawk.texi: Redid page breaking for new texinfo.tex.
+
+Thu Apr 6 12:32:49 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Change info dir file entry to `(gawk)' from
+ `(gawk.info)'.
+ * Makefile.in [$(infodir)/gawk.info]: Fix grep test is
+ accordance with above.
+
+Sun Feb 13 15:36:32 2000 Paul Eggert <eggert@twinsun.com>
+
+ * gawk.texi: Mention that arithmetic is done in double
+ precision floating point, and point to Goldberg's paper for
+ people who want to know more. Fix some other minor floating
+ point discussion issues.
+
+Wed Nov 3 17:04:35 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Lots of troff ``lint'' from Paul Eggert. Not all
+ of his changes, just the ones I thought worth doing.
+
+Mon Oct 11 16:53:54 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (gawk.dvi): Put $(srcdir) first in TEXINPUTS,
+ and also just use texi2dvi, don't run texindex and tex
+ manually. Doing so is no longer necessary.
+
+Mon Aug 9 13:06:01 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: New node `Array Efficiency' on the best use
+ of subscripting to avoid memory bloat.
+
+Thu Jul 29 23:15:34 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in ($(infodir)/gawk.info): Removed loop around
+ $(INSTALL_DATA), since there's only one Info file to install,
+ install it directly.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Wed Oct 7 21:59:33 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * texinfo.tex: Updated to version 2.227, from Texinfo 3.12.
+
+Sun Oct 19 12:26:08 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * ALL: change references to arnold@gnu.ai.mit.edu to arnold@gnu.org.
+
+Tue Sep 23 10:31:17 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * texinfo.tex: Updated to version 2.218, from Texinfo 3.11.
+
+Fri Jul 4 08:19:00 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in ($(infodir)/gawk.info): Don't make dependent upon
+ gawk.info, in case installed one is newer. Instead, check that
+ an installed gawk.info exists and is identical to current one.
+ If so, just exit; otherwise do the install.
+
+Wed Jul 2 14:55:12 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in ($(infodir)/gawk.info): typo fix.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Sun Apr 13 15:39:20 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(infodir)/gawk.info): exit 0 in case install-info
+ fails.
+
+Thu Jan 2 23:17:53 1997 Fred Fish <fnf@ninemoons.com>
+
+ * Makefile.in (awkcard.tr): Use ':' chars to separate parts of
+ sed command, since $(srcdir) may expand to something with '/'
+ characters in it, which confuses sed terribly.
+ * gawk.texi (Amiga Installation): Note change of configuration
+ from "m68k-cbm-amigados" to "m68k-amigaos". Point ftp users
+ towards current ADE distribution and not obsolete Aminet
+ "gcc" distribution. Change "FreshFish" to "Geek Gadgets".
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Wed Dec 25 11:17:32 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(mandir)/igawk$(manext),$(mandir)/gawk$(manext)):
+ remove chmod command; let $(INSTALL_DATA) use -m.
+
+Tue Dec 17 22:38:28 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gawk.info,gawk.dvi,postscript): run makeinfo, TeX,
+ and/or troff against files in $(srcdir). Thanks to Ulrich Drepper.
+ ($(infodir)/gawk.info): use --info-dir to install-info, not
+ --infodir.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Mon Dec 9 12:48:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * no.colors: new file from Michal for old troffs.
+ * Makefile.in [AWKCARD]: changes to parameterize old/new troff.
+
+Sun Dec 1 15:04:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * texinfo.tex: Updated to version 2.193, from Karl Berry.
+
+Tue Nov 26 22:57:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(infodir)/gawk.info): Change option in call
+ to `install-info' to `--info-dir' from `--infodir'.
+
+Mon Nov 4 13:30:39 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in: updates for reference card.
+ (ad.block, awkcard.in, cardfonts, colors, macros, setter.outline):
+ new files for reference card.
+
+Wed Oct 16 12:43:02 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * texinfo.tex: Updated to version 2.185, from texinfo-3.9 dist.
+
+Sun Aug 11 23:12:08 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(infodir)/gawk.info): correct use of
+ $(INSTALL_DATA) and remove chmod command.
+
+Thu Jul 11 22:06:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(mandir)/gawk.$(ext), $(mandir)/igawk.$(ext)):
+ made dependant on files in $(srcdir).
+
+Fri Mar 15 06:45:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): add `*~' to list of files to be removed.
+
+Thu Jan 25 23:40:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dvi): run texindex and tex an extra time.
+ This gets the cross references right. Sigh.
+
+Wed Jan 24 11:51:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (maintainer-clean):
+ Depend on distclean, not the other way around.
+ Output warning message as per GNU standards.
--- /dev/null
+#
+# doc/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2000, 2001, 2002, 2004, 2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+## process this file with automake to produce Makefile.in
+
+info_TEXINFOS = gawk.texi gawkinet.texi
+
+man_MANS = gawk.1 igawk.1
+
+EXTRA_DIST = ChangeLog README.card ad.block setter.outline \
+ awkcard.in awkforai.txt texinfo.tex cardfonts \
+ macros colors no.colors $(man_MANS) \
+ lflashlight.eps rflashlight.eps \
+ statist.jpg statist.eps
+
+MAKEINFO = @MAKEINFO@ --no-split --force
+
+TROFF = groff -t -Tps -U
+SEDME = sed -e "s/^level0 restore/level0 restore flashme 100 72 moveto (Copyright `date '+%m-%d-%y %T'`, FSF, Inc. (all)) show/" \
+ -e "s/^\/level0 save def/\/level0 save def 30 -48 translate/"
+
+CARDSRC = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/colors awkcard.tr
+CARDSRC_N = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/no.colors awkcard.tr
+CARDFILES= $(CARDSRC) ad.block awkcard.in setter.outline
+
+# Use this if your troff can correctly handle macros from 'colors' file
+AWKCARD = awkcard.ps
+
+# Uncomment the following definition of AWKCARD if your troff can produce
+# Postscript but still has troubles with macros from 'colors'. As this
+# is not groff you will have to change TROFF macro as well. Do not forget
+# to ensure that awkcard.tr is processed by tbl.
+#AWKCARD = awkcard.nc
+
+# The following is patterned after the main Makefile.am. The point is to
+# make pgawk.1 a link to gawk.1 in the installed man directory.
+
+# We want hard links for install-data-hook, below
+LN= ln
+
+# Link gawk.1 to pgawk.1
+install-data-hook:
+ (cd $(DESTDIR)$(man1dir); \
+ $(LN) gawk.1 pgawk.1 2>/dev/null ; \
+ exit 0)
+
+# Undo the above when uninstalling
+uninstall-hook:
+ cd $(DESTDIR)$(man1dir); rm -f pgawk.1 ; exit 0
+
+postscript: gawk.ps gawkinet.ps gawk.1.ps igawk.1.ps $(AWKCARD)
+
+gawk.ps: gawk.dvi
+ dvips -o gawk.ps gawk.dvi
+
+gawkinet.ps: gawkinet.dvi
+ dvips -o gawkinet.ps gawkinet.dvi
+
+gawk.1.ps: gawk.1
+ -groff -man $(srcdir)/gawk.1 > gawk.1.ps
+
+igawk.1.ps: igawk.1
+ -groff -man $(srcdir)/igawk.1 > igawk.1.ps
+
+awkcard.tr: awkcard.in
+ sed 's:SRCDIR:$(srcdir):' < $(srcdir)/awkcard.in > awkcard.tr
+
+awkcard.ps: $(CARDFILES)
+ $(TROFF) $(CARDSRC) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps
+
+awkcard.nc: $(CARDFILES)
+ $(TROFF) $(CARDSRC_N) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps && touch awkcard.nc
+
+clean:
+ rm -f *.ps *~ awkcard.nc awkcard.tr *.html
--- /dev/null
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# doc/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2000, 2001, 2002, 2004, 2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog \
+ texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/socket.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/strtod.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/gawk.info $(srcdir)/gawkinet.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = gawk.dvi gawkinet.dvi
+PDFS = gawk.pdf gawkinet.pdf
+PSS = gawk.ps gawkinet.ps
+HTMLS = gawk.html gawkinet.html
+TEXINFOS = gawk.texi gawkinet.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMSGFMT = @GMSGFMT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@ --no-split --force
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+STRIP = @STRIP@
+U = @U@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+info_TEXINFOS = gawk.texi gawkinet.texi
+man_MANS = gawk.1 igawk.1
+EXTRA_DIST = ChangeLog README.card ad.block setter.outline \
+ awkcard.in awkforai.txt texinfo.tex cardfonts \
+ macros colors no.colors $(man_MANS) \
+ lflashlight.eps rflashlight.eps \
+ statist.jpg statist.eps
+
+TROFF = groff -t -Tps -U
+SEDME = sed -e "s/^level0 restore/level0 restore flashme 100 72 moveto (Copyright `date '+%m-%d-%y %T'`, FSF, Inc. (all)) show/" \
+ -e "s/^\/level0 save def/\/level0 save def 30 -48 translate/"
+
+CARDSRC = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/colors awkcard.tr
+CARDSRC_N = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/no.colors awkcard.tr
+CARDFILES = $(CARDSRC) ad.block awkcard.in setter.outline
+
+# Use this if your troff can correctly handle macros from 'colors' file
+AWKCARD = awkcard.ps
+
+# Uncomment the following definition of AWKCARD if your troff can produce
+# Postscript but still has troubles with macros from 'colors'. As this
+# is not groff you will have to change TROFF macro as well. Do not forget
+# to ensure that awkcard.tr is processed by tbl.
+#AWKCARD = awkcard.nc
+
+# The following is patterned after the main Makefile.am. The point is to
+# make pgawk.1 a link to gawk.1 in the installed man directory.
+
+# We want hard links for install-data-hook, below
+LN = ln
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && cd $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ cd $(srcdir); \
+ else \
+ rc=$$?; \
+ cd $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/gawk.info: gawk.texi
+gawk.dvi: gawk.texi
+gawk.pdf: gawk.texi
+gawk.html: gawk.texi
+$(srcdir)/gawkinet.info: gawkinet.texi
+gawkinet.dvi: gawkinet.texi
+gawkinet.pdf: gawkinet.texi
+gawkinet.html: gawkinet.texi
+.dvi.ps:
+ $(DVIPS) -o $@ $<
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in $$d/$$base*; do \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f $(distdir)/$$relfile || \
+ cp -p $$file $(distdir)/$$relfile; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf gawk.aux gawk.cp gawk.cps gawk.fn gawk.ky gawk.kys gawk.log gawk.pg \
+ gawk.pgs gawk.tmp gawk.toc gawk.tp gawk.tps gawk.vr gawk.dvi \
+ gawk.pdf gawk.ps gawk.html gawkinet.aux gawkinet.cp \
+ gawkinet.cps gawkinet.fn gawkinet.ky gawkinet.kys \
+ gawkinet.log gawkinet.pg gawkinet.pgs gawkinet.tmp \
+ gawkinet.toc gawkinet.tp gawkinet.tps gawkinet.vr \
+ gawkinet.dvi gawkinet.pdf gawkinet.ps gawkinet.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+install-man1: $(man1_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
+ echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
+ $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man: install-man1
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-info-am uninstall-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+
+uninstall-man: uninstall-man1
+
+.PHONY: all all-am check check-am clean clean-generic dist-info \
+ distclean distclean-generic distdir dvi dvi-am html html-am \
+ info info-am install install-am install-data install-data-am \
+ install-data-hook install-exec install-exec-am install-info \
+ install-info-am install-man install-man1 install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-aminfo maintainer-clean-generic mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-hook uninstall-info-am \
+ uninstall-man uninstall-man1
+
+
+# Link gawk.1 to pgawk.1
+install-data-hook:
+ (cd $(DESTDIR)$(man1dir); \
+ $(LN) gawk.1 pgawk.1 2>/dev/null ; \
+ exit 0)
+
+# Undo the above when uninstalling
+uninstall-hook:
+ cd $(DESTDIR)$(man1dir); rm -f pgawk.1 ; exit 0
+
+postscript: gawk.ps gawkinet.ps gawk.1.ps igawk.1.ps $(AWKCARD)
+
+gawk.ps: gawk.dvi
+ dvips -o gawk.ps gawk.dvi
+
+gawkinet.ps: gawkinet.dvi
+ dvips -o gawkinet.ps gawkinet.dvi
+
+gawk.1.ps: gawk.1
+ -groff -man $(srcdir)/gawk.1 > gawk.1.ps
+
+igawk.1.ps: igawk.1
+ -groff -man $(srcdir)/igawk.1 > igawk.1.ps
+
+awkcard.tr: awkcard.in
+ sed 's:SRCDIR:$(srcdir):' < $(srcdir)/awkcard.in > awkcard.tr
+
+awkcard.ps: $(CARDFILES)
+ $(TROFF) $(CARDSRC) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps
+
+awkcard.nc: $(CARDFILES)
+ $(TROFF) $(CARDSRC_N) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps && touch awkcard.nc
+
+clean:
+ rm -f *.ps *~ awkcard.nc awkcard.tr *.html
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Mon Dec 9 12:45:48 EST 1996
+
+The AWK reference card included here requires a modern version of troff
+(ditroff). GNU Troff (groff) is known to work.
+
+If your troff is able to produce Postscript but does not know how to
+properly use the macros from `colors' file then try to uncomment in
+Makefile the defintion which sets AWKCARD to awkcard.nc (no colors).
+This will definitely require changes to the TROFF macro and you have to
+ensure that the tbl preprocessor is called. For example, the following
+modifications on NeXT:
+
+TROFF = tbl
+SEDME = ptroff -t | sed -e \
+ "s/^level0 restore/level0 restore flashme 100 72 moveto\
+ (Copyright `date`, FSF, Inc. (all)) show/" \
+ -e "s/^\/level0 save def/\/level0 save def 30 -48 translate/"
+
+will produce a correctly formatted, albeit monochromatic, reference card.
--- /dev/null
+.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
+.\" This file is the Ad block (included in cover)
+.\"
+.\" Copyright (C) 1996, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ft HB
+.ps 10
+.vs 12
+.ES
+.nf
+.ce 7
+\*(CBFree Software Foundation, Inc.
+.ft H
+51 Franklin Street, Fifth Floor
+Boston, MA 02110-1301 USA
+Phone: +1-617-542-5942
+Fax (including Japan): +1-617-542-2652
+E-mail: gnu@gnu.org
+URL: http://www.gnu.org
+
+.ce 5
+.ft HB
+\*(CGSource Distributions on CD-ROM
+.\" Deluxe Distributions
+Emacs, Make and GDB Manuals
+Emacs and GDB References\*(CX
+.EB "\f(HBOTHER FSF PRODUCTS:\*(FR"
+.ps
+.vs
--- /dev/null
+.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
+.\"
+.\" Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+.\" 2003, 2004, 2005 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.\" Strings to save typing
+.ds AK \*(FCawk\*(FR
+.ds GK \*(FCgawk\*(FR
+.ds PK \*(FCpgawk\*(FR
+.ds NK Bell Labs \*(FCawk\*(FR
+.ds MK \*(FCmawk\*(FR
+.\"
+.\"
+.de TD\" tab defaults
+.ta .2i .78i 1i 1.2i 1.4i 1.7i
+..
+.de TE
+.TD
+..
+
+.sp
+.ce
+\*(CD\f(HB\s+8AWK REFERENCE\s0\*(FR
+.sp
+.\" --- Table Of Contents
+.ta 2.4i 2.6iR
+.lc .
+.ES
+.in +.2i
+.nf
+\*(FRAction Statements\ 1 7
+Arrays\ 1 11
+Awk Program Execution\ 1 4
+Bit Manipulation Functions (\*(GK)\ 1 16
+Bug Reports\ 1 2
+Closing Redirections\ 1 12
+Command Line Arguments (standard)\ 1 2
+Command Line Arguments (\*(GK)\ 1 3
+Command Line Arguments (\*(MK)\ 1 4
+Conversions And Comparisons\ 1 9
+Copying Permissions\ 1 18
+Definitions\ 1 2
+Dynamic Extensions (\*(GK)\ 1 14
+Environment Variables (\*(GK)\ 1 16
+Escape Sequences\ 1 8
+Expressions\ 1 11
+Fields\ 1 6
+FTP/HTTP Information\ 1 18
+Historical Features (\*(GK)\ 1 10
+Input Control\ 1 12
+Internationalization (\*(GK)\ 1 18
+Lines And Statements\ 1 5
+Localization (\*(GK)\ 1 17
+Numeric Functions\ 1 14
+Output Control\ 1 12
+Pattern Elements\ 1 7
+POSIX Character Classes (\*(GK)\ 1 6
+Printf Formats\ 1 13
+Records\ 1 6
+Regular Expressions\ 1 5
+Signals (\*(PK)\ 1 4
+Special Filenames\ 1 14
+String Functions\ 1 15
+Time Functions (\*(GK)\ 1 16
+User-defined Functions\ 1 17
+Variables\ 1 8\*(CX
+.in -.2i
+.EB "\s+2\f(HBCONTENTS\*(FR\s0"
+.sp .4
+.TD
+.fi
+\*(CD\*(FRArnold Robbins wrote this reference card.
+We thank
+Brian Kernighan and Michael Brennan who reviewed it.
+.sp .4
+.SL
+.sp .4
+.so SRCDIR/ad.block
+.\" a subtlety here; this line changes color. We rely on it
+.\" also to provide a blank line.
+\*(CD
+.SL
+.nf
+\*(FRCopyright \(co 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+.nf
+.BT
+
+
+.\"
+.\"
+.\" --- Definitions
+.fi
+.ES
+\*(CDThis card describes POSIX AWK, as well as the three
+freely available \*(AK implementations
+(see \fHFTP/HTTP Information\fP below).
+\*(CLCommon extensions (in two or more versions) are printed in light blue.
+\*(CBFeatures specific to just one version\(emusually GNU AWK (\*(GK)\(emare
+printed in dark blue.
+\*(CRExceptions and deprecated features are printed in red.
+\*(CDFeatures mandated by POSIX are printed in black.
+.sp .5
+Several type faces are used to clarify the meaning:
+.br
+.nr IN \w'\(bu '
+\(bu \*(FC\*(CN\fP is used for computer input.
+.br
+.fi
+.in +\n(INu
+.ti -\n(INu
+\(bu\|\^\*(FI\*(IN\fP is used for emphasis, to indicate user input and for syntactic
+placeholders, such as \*(FIvariable\fP or \*(FIaction\fP.
+.in -\n(INu
+.br
+\(bu \*(RN is used for explanatory text.
+.sp .5
+\*(FInumber\fP \- a floating point number as in ANSI C, such as
+\*(FC3\*(FR,
+\*(FC2.3\*(FR,
+\*(FC.4\*(FR,
+\*(FC1.4e2\*(FR
+or
+\*(FC4.1E5\*(FR.
+\*(CBNumbers may also be given in octal or hexadecimal: e.g.,
+\*(FC011\*(FR or \*(FC0x11\*(FR.\*(CD
+.sp .5
+\*(FIescape sequences\fP \- a special sequence of characters beginning
+with a backslash, used to describe otherwise unprintable characters.
+(See \fHEscape Sequences\fP below.)
+.sp .5
+\*(FIstring\fP \- a group of characters enclosed in double quotes.
+Strings may contain \*(FIescape sequences\*(FR.
+.sp .5
+\*(FIregexp\fP \- a regular expression, either a regexp constant
+enclosed in forward slashes, or a dynamic regexp computed at run-time.
+Regexp constants may contain \*(FIescape sequences\*(FR.
+.sp .5
+\*(FIname\fP \- a variable, array or function name.
+.sp .5
+\*(FIentry\fP(\*(FIN\fP) \- entry \*(FIentry\fP in section \*(FIN\fP of the
+UNIX reference manual.
+.sp .5
+\*(FIpattern\fP \- an expression describing an input record to be matched.
+.sp .5
+\*(FIaction\fP \- statements to execute when an input record is matched.
+.sp .5
+\*(FIrule\fP \- a pattern-action pair, where the pattern or action may
+be missing.\*(CX
+.EB "\s+2\f(HBDEFINITIONS\*(FR\s0"
+
+.\"
+.\"
+.\" --- Command Line Arguments
+.ES
+.fi
+\*(CDCommand line arguments control setting the field separator,
+setting variables before the \*(FCBEGIN\fP rule is run, and
+the location of AWK program source code.
+Implementation-specific command line arguments change
+the behavior of the running interpreter.
+.sp .5
+.TS
+expand;
+l lw(2.2i).
+\*(FC\-F \*(FIfs\*(FR use \*(FIfs\fP for the input field separator.
+\*(FC\-v\*(FI var\*(FC\^=\^\*(FIval\*(FR T{
+assign the value \*(FIval\*(FR to the variable \*(FIvar\*(FR
+before execution of the program begins. Such
+variable values are available to the \*(FCBEGIN\fP rule.
+T}
+\*(FC\-f \*(FIprog-file\*(FR T{
+read the AWK program source from the file
+\*(FIprog-file\*(FR, instead of from the first command
+line argument. Multiple \*(FC\-f\*(FR options may be used.
+T}
+\*(FC\-\^\-\*(FR signal the end of options.
+.TE
+.sp .5
+.fi
+\*(CLThe following options are accepted by both \*(NK and \*(GK
+\*(CR(ignored by \*(GK, not in \*(MK).\*(CL
+.sp .5
+.nf
+.TS
+expand, tab(%);
+l lw(2.2i).
+\*(FC\-mf \*(FIval\*(FR%set the maximum number of fields to \*(FIval\fP
+\*(FC\-mr \*(FIval\*(FR%set the maximum record size to \*(FIval\fP\*(CX
+.TE
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (standard)\*(FR\s0"
+
+.\" --- Bug Reports
+.ES
+.fi
+\*(CDIf you find a bug in this reference card, please report it via electronic
+mail to \*(FCbug-gawk@gnu.org\*(FR.\*(CX
+.EB "\s+2\f(HBBUG REPORTS\*(FR\s0"
+
+.BT
+
+.\"
+.\"
+.\" --- Command Line Arguments (gawk)
+.ES
+.fi
+\*(CDThe following options are specific to \*(GK.
+You may also use ``\*(FC\-W \*(FIoption\*(FR''
+for full POSIX compliance.
+Long options may abbreviated as long as the abbreviation
+remains unique.
+.sp .5
+.ig
+.\" This option is left undocumented, on purpose.
+\*(FC\-\^\-nostalgia\*(FR%T{
+provide a moment of nostalgia for
+long time \*(AK users.
+T}
+..
+.TS
+expand, tab(%);
+l lw(1.3i).
+\*(FC\-\^\-assign \*(FIvar\*(FC\^=\^\*(FIval\*(FR%just like \*(FC\-v\fP.
+\*(FC\-\^\-field-separator \*(FIfs\*(FR%just like \*(FC\-F\fP.
+\*(FC\-\^\-file \*(FIprog-file%\*(FRjust like \*(FC\-f\fP.
+.TE
+.TS
+expand, tab(%);
+ls
+l lw(2.2i).
+\*(FC\-\^\-compat\*(FR, \*(FC\-\^\-traditional\*(FR
+%T{
+disable \*(GK-specific extensions
+(the use of \*(FC\-\^\-traditional\*(FR is preferred).
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-copyleft\*(FR, \*(FC\-\^\-copyright\*(FR
+%T{
+print the short version of the GNU
+copyright information on \*(FCstdout\*(FR.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-dump-variables\*(FR[\*(FC=\*(FIfile\*(FR]
+%T{
+print a sorted list of global variables,
+their types and final values to
+\*(FIfile\*(FR.
+If no \*(FIfile\*(FR
+is provided, \*(FCgawk\*(FR
+uses \*(FCawkvars.out\*(FR.
+T}
+\*(FC\-\^\-exec \*(FIfile\*(FR%T{
+read program text from \*(FIfile\fP. No other
+options are processed. Useful with \*(FC#!\fP.
+Also disables command-line variable assignments.
+T}
+\*(FC\-\^\-gen\-po\*(FR%T{
+process the program and print a GNU \*(FCgettext\*(FR
+format \*(FC\&.po\*(FR format file on standard output,
+containing the text of all strings that were marked
+for localization.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-help\*(FR, \*(FC\-\^\-usage\*(FR
+%T{
+print a short summary of the available
+options on \*(FCstdout\*(FR, then exit zero.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-lint\*(FR[\*(FC=\*(FIvalue\*(FR]
+%T{
+warn about constructs that are dubious
+or non-portable to other \*(AKs.
+With an optional argument of \*(FCfatal\*(FR,
+lint warnings become fatal errors.
+With an optional argument of
+\*(FCinvalid\*(FR,
+only warnings about things that are
+actually invalid are issued. (This is not fully implemented yet.)
+T}
+.T&
+l lw(2.2i).
+\*(FC\-\^\-lint\-old\*(FR%T{
+warn about constructs that are not
+portable to the original version of
+Unix \*(AK.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-non\-decimal\-data\*(FR
+%T{
+recognize octal and hexadecimal values in input data.
+\*(FIUse this option with great caution!\*(FR
+T}
+.T&
+l lw(2.2i).
+\*(FC\-\^\-posix\*(FR%T{
+disable common and GNU extensions.
+Enable \*(FIinterval expressions\*(FR in regular
+expression matching (see \fHRegular
+Expressions\fP below).
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-profile\*(FR[\*(FC=\*(FIprof_file\*(FR]
+%T{
+send profiling data to \*(FIprof_file\*(FR
+(default: \*(FCawkprof.out\*(FR).
+With \*(GK,
+the profile is just a ``pretty printed'' version of the program.
+With \*(PK,
+the profile contains execution counts in the left margin
+of each statement in the program.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-re\-interval\*(FR
+%T{
+enable \*(FIinterval expressions\*(FR in regular
+expression matching (see \fHRegular
+Expressions\fP below). Useful if
+\*(FC\-\^\-posix\*(FR is not specified.
+T}
+.T&
+ls
+l lw(2.2i).
+\*(FC\-\^\-source '\*(FItext\*(FC'\*(FR
+%use \*(FItext\*(FR as AWK program source code.
+\*(FC\-\^\-version\*(FR%T{
+print version information on \*(FCstdout\fP
+and exit zero.
+T}
+.TE
+.sp .5
+.fi
+In compatibility mode,
+any other options are flagged as invalid, but are otherwise ignored.
+In normal operation, as long as program text has been supplied, unknown
+options are passed on to the AWK program in
+\*(FCARGV\*(FR
+for processing. This is most useful for running AWK
+programs via the \*(FC#!\*(FR executable interpreter mechanism.\*(CB
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(GK\f(HB)\*(FR\s0"
+
+.BT
+
+.\"
+.\"
+.\" --- Command Line Arguments (mawk)
+.ES
+.fi
+\*(CDThe following options are specific to \*(MK.
+.sp .5
+.fi
+.TS
+expand;
+l lw(1.8i).
+\*(FC\-W dump\*(FR T{
+print an assembly listing of the program to
+\*(FCstdout\fP and exit zero.
+T}
+\*(FC\-W exec \*(FIfile\*(FR T{
+read program text from \*(FIfile\fP. No other
+options are processed. Useful with \*(FC#!\fP.
+T}
+\*(FC\-W interactive\*(FR T{
+unbuffer \*(FCstdout\fP and line buffer \*(FCstdin\fP.
+Lines are always records, ignoring \*(FCRS\fP.
+T}
+\*(FC\-W posix_space\*(FR T{
+\*(FC\en\*(FR separates fields when \*(FCRS = "\^"\fP.
+T}
+\*(FC\-W sprintf=\*(FInum\*(FR T{
+adjust the size of \*(MK's internal
+\*(FCsprintf\*(FR buffer.
+T}
+\*(FC\-W version\*(FR T{
+print version and copyright on
+\*(FCstdout\fP and limit information on \*(FCstderr\fP
+and exit zero.
+T}
+.TE
+.sp .5
+.fi
+The options may be abbreviated using just the first letter, e.g.,
+\*(FC\-We\*(FR,
+\*(FC\-Wv\*(FR
+and so on.\*(CB
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(MK\f(HB)\*(FR\s0"
+.sp .7
+.\" --- Signals (pgawk)
+.ES
+.fi
+\*(CD\*(PK accepts two signals.
+\*(FCSIGUSR1\fP dumps a profile and function call stack to the
+profile file. It then continues to run.
+\*(FCSIGHUP\fP is similar, but exits.\*(CB
+.EB "\s+2\f(HBSIGNALS (\*(PK\f(HB)\*(FR\s0"
+.sp .7
+.\" --- Awk Program Execution
+.ES
+.fi
+\*(CDAWK programs are a sequence of pattern-action statements
+and optional function definitions.
+.sp .5
+ \*(FIpattern\*(FC { \*(FIaction statements\*(FC }\*(FR
+.br
+ \*(FCfunction \*(FIname\*(FC(\*(FIparameter list\*(FC) { \*(FIstatements\*(FC }\*(FR
+.sp .5
+\*(AK first reads the program source from the
+\*(FIprog-file\*(FR(s), if specified,
+\*(CBfrom arguments to \*(FC\-\^\-source\*(FR,\*(CD
+or from the first non-option argument on the command line.
+The program text is read as if all the \*(FIprog-file\*(FR(s)
+\*(CBand command line
+source texts\*(CD had been concatenated.
+.sp .5
+AWK programs execute in the following order.
+First, all variable assignments specified via the \*(FC\-v\fP
+option are performed.
+Next, \*(AK executes the code in the
+\*(FCBEGIN\fP rules(s), if any, and then proceeds to read
+the files \*(FC1\fP through \*(FCARGC \- 1\fP in the \*(FCARGV\fP array.
+(Adjusting \*(FCARGC\fP and \*(FCARGV\fP thus provides control over
+the input files that will be processed.)
+If there are no files named on the command line,
+\*(AK reads the standard input.
+.sp .5
+If a command line argument has the form
+\*(FIvar\*(FC=\*(FIval\*(FR,
+it is treated as a variable assignment. The variable
+\*(FIvar\fP will be assigned the value \*(FIval\*(FR.
+(This happens after any \*(FCBEGIN\fP rule(s) have been run.)
+... delete this paragraph if no space
+Command line variable assignment
+is most useful for dynamically assigning values to the variables
+\*(AK uses to control how input is broken into fields and records. It
+is also useful for controlling state if multiple passes are needed over
+a single data file.
+.sp .5
+If the value of a particular element of \*(FCARGV\fP is empty
+(\*(FC"\^"\*(FR), \*(AK skips over it.
+.sp .5
+For each record in the input, \*(AK tests to see if it matches any
+\*(FIpattern\fP in the AWK program.
+For each pattern that the record matches, the associated
+\*(FIaction\fP is executed.
+The patterns are tested in the order they occur in the program.
+.sp .5
+Finally, after all the input is exhausted,
+\*(AK executes the code in the \*(FCEND\fP rule(s), if any.
+.sp .5
+If a program only has a \*(FCBEGIN\fP rule, no input files are processed.
+If a program only has an \*(FCEND\fP rule, the input will be read.
+\*(CX
+.EB "\s+2\f(HBAWK PROGRAM EXECUTION\*(FR\s0"
+
+
+.BT
+
+.\" --- Lines And Statements
+.ES
+.fi
+\*(CDAWK is a line-oriented language. The pattern comes first, and then the
+action. Action statements are enclosed in \*(FC{\fP and \*(FC}\*(FR.
+Either the pattern or the action may be missing, but
+not both. If the pattern is missing, the action is
+executed for every input record.
+A missing action is equivalent to
+.sp .5
+ \*(FC{ print }\fP
+.sp .5
+which prints the entire record.
+.sp .5
+Comments begin with the \*(FC#\*(FR character, and continue until the
+end of the line.
+Normally, a statement ends with a newline, but lines ending in
+a ``,'',
+\*(FC{\*(FR,
+\*(CB\*(FC?\*(FR,
+\*(FC:\*(FR,\*(CD
+\*(FC&&\*(FR
+or
+\*(FC||\*(FR
+are automatically continued.
+Lines ending in \*(FCdo\fP or \*(FCelse\fP
+also have their statements automatically continued on the following line.
+In other cases, a line can be continued by ending it with a ``\e'',
+in which case the newline is ignored. However, a ``\e'' after a
+\*(FC#\*(FR is not special.
+.sp .5
+Multiple statements may be put on one line by separating them with a ``;''.
+This applies to both the statements within the action part of a
+pattern-action pair (the usual case)
+and to the pattern-action statements themselves.\*(CX
+.EB "\s+2\f(HBLINES AND STATEMENTS\*(FR\s0"
+
+
+
+.\" --- Regular Expressions
+.ES
+.fi
+\*(CDRegular expressions are the extended kind originally defined by
+\*(FCegrep\fP.
+\*(CBAdditional GNU regexp operators are supported by \*(GK.
+A \*(FIword-constituent\fP character is a letter, digit, or
+underscore (\*(FC_\fP).\*(CD
+.sp .5
+.TS
+center, tab(~);
+cp8 sp8
+cp8 sp8
+lp8|lp8.
+.\" .vs 10
+_
+Summary of Regular Expressions
+In Decreasing Precedence
+_
+\*(FC(\^\*(FIr\*(FC)\*(FR~regular expression (for grouping)
+\*(FIc\*(FR~if non-special char, matches itself
+\*(FC\e\*(FI\^c\*(FR~turn off special meaning of \*(FIc\fP
+\*(FC^\*(FR~beginning of string (note: \*(FInot\fP line)
+\*(FC$\*(FR~end of string (note: \*(FInot\fP line)
+\*(FC.\*(FR~any single character, including newline
+\*(FC[\*(FR...\*(FC]\*(FR~any one character in ... or range
+\*(FC[^\*(FR...\*(FC]\*(FR~any one character not in ... or range
+\*(CB\*(FC\ey\*(FR~word boundary
+\*(FC\eB\*(FR~middle of a word
+\*(FC\e<\*(FR~beginning of a word
+\*(FC\e>\*(FR~end of a word
+\*(FC\ew\*(FR~any word-constituent character
+\*(FC\eW\*(FR~any non-word-constituent character
+\*(FC\e`\*(FR~beginning of a string
+\*(FC\e'\*(FR~end of a string\*(CD
+\*(FIr\*(FC*\*(FR~zero or more occurrences of \*(FIr\*(FR
+\*(FIr\*(FC+\*(FR~one or more occurrences of \*(FIr\*(FR
+\*(FIr\*(FC?\*(FR~zero or one occurrences of \*(FIr\*(FR
+\*(FIr\*(FC{\*(FIn\*(FC,\*(FIm\*(FC}\*(FR~\*(FIn\fP to \*(FIm\fP occurrences of \*(FIr\*(FR \*(CR(POSIX: see note below)\*(CD
+\*(FIr1\*(FC|\|\*(FIr2\*(FR~\*(FIr1\*(FR or \*(FIr2\*(FR
+.TE
+.sp .5
+.fi
+\*(CRThe \*(FIr\*(FC{\*(FIn\*(FC,\*(FIm\*(FC}\*(FR notation is called an
+\*(FIinterval expression\fP. POSIX mandates it for AWK regexps, but
+most \*(AKs don't implement it. \*(CBUse \*(FC\-\^\-re\-interval\*(FR
+or \*(FC\-\^\-posix\*(FR to enable
+this feature in \*(GK.\*(CX
+.EB "\s+2\f(HBREGULAR EXPRESSIONS\*(FR\s0"
+
+
+.BT
+
+.\" --- POSIX Character Classes (gawk)
+.ES
+.fi
+\*(CDIn regular expressions, within character ranges
+(\*(FC[\*(FR...\*(FC]\*(FR),
+the notation \*(FC[[:\*(FIclass\*(FC:]]\*(FR defines character classes:
+.sp .5
+.TS
+center, tab(~);
+lp8 lp8 lp8 lp8.
+\*(FCalnum\*(FR~alphanumeric~\*(FClower\*(FR~lower-case
+\*(FCalpha\*(FR~alphabetic~\*(FCprint\*(FR~printable
+\*(FCblank\*(FR~space or tab~\*(FCpunct\*(FR~punctuation
+\*(FCcntrl\*(FR~control~\*(FCspace\*(FR~whitespace
+\*(FCdigit\*(FR~decimal~\*(FCupper\*(FR~upper-case
+\*(FCgraph\*(FR~non-spaces~\*(FCxdigit\*(FR~hexadecimal
+.TE
+.fi
+.sp .5
+Recognition of these character classes is disabled
+when \*(FC\-\-traditional\*(FR is supplied.\*(CB
+.EB "\s+2\f(HBPOSIX CHARACTER CLASSES (\*(GK\f(HB)\*(FR\s0"
+
+.\" --- Records
+.ES
+.fi
+\*(CDNormally, records are separated by newline characters.
+Assigning values to the built-in variable \*(FCRS\*(FR
+controls how records are separated.
+If \*(FCRS\fP is any single character, that character separates records.
+\*(CLOtherwise, \*(FCRS\fP is a regular expression.
+\*(CR(Not \*(NK.)\*(CL
+Text in the input that matches this
+regular expression separates the record.
+\*(CB\*(GK sets \*(FCRT\*(FR to the value of the
+input text that matched the regular expression.
+The value of \*(FCIGNORECASE\fP
+also affects how records are separated when
+\*(FCRS\fP is a regular expression.\*(CD
+If \*(FCRS\fP is set to the null string,
+then records are separated by one or more blank lines.
+When \*(FCRS\fP is set to the null string,
+the newline character always acts as
+a field separator, in addition to whatever value
+\*(FCFS\fP may have.
+\*(CB\*(MK does not apply exceptional rules to \*(FCFS\fP
+when \*(FCRS = "\^"\fP.\*(CX
+.EB "\s+2\f(HBRECORDS\*(FR\s0"
+
+.\" --- Fields
+.ES
+.fi
+\*(CDAs each input record is read, \*(AK splits the record into
+\*(FIfields\*(FR, using the value of the \*(FCFS\fP
+variable as the field separator.
+If \*(FCFS\fP is a single character,
+fields are separated by that character.
+\*(CLIf \*(FCFS\fP is the null string,
+then each individual character becomes a separate field.\*(CD
+Otherwise, \*(FCFS\fP is expected to be a full regular expression.
+In the special case that \*(FCFS\fP
+is a single space, fields are separated
+by runs of spaces and/or tabs
+\*(CLand/or newlines\*(CD.
+Leading and trailing whitespace are ignored.
+\*(CBThe value of \*(FCIGNORECASE\fP
+also affects how fields are split when
+\*(FCFS\fP is a regular expression.\*(CD
+.sp .5
+\*(CBIf the \*(FCFIELDWIDTHS\fP
+variable is set to a space-separated list of numbers, each field is
+expected to have a fixed width, and \*(GK
+splits up the record using the specified widths.
+The value of \*(FCFS\fP is ignored.
+Assigning a new value to \*(FCFS\fP
+overrides the use of \*(FCFIELDWIDTHS\*(FR,
+and restores the default behavior.\*(CD
+.sp .5
+Each field in the input record may be referenced by its position,
+\*(FC$1\*(FR, \*(FC$2\*(FR and so on.
+\*(FC$0\fP is the whole record.
+Fields may also be assigned new values.
+.sp .5
+The variable \*(FCNF\fP
+is set to the total number of fields in the input record.
+.sp .5
+References to non-existent fields (i.e., fields after \*(FC$NF\*(FR)
+produce the null-string. However, assigning to a non-existent field
+(e.g., \*(FC$(NF+2) = 5\*(FR) increases the value of
+\*(FCNF\*(FR, creates any intervening fields with the null string as their value,
+and causes the value of \*(FC$0\fP
+to be recomputed with the fields being separated by the
+value of \*(FCOFS\*(FR.
+References to negative numbered fields cause a fatal error.
+Decreasing the value of \*(FCNF\fP causes the trailing fields to be lost
+\*(CR(not \*(NK).\*(CX
+.EB "\s+2\f(HBFIELDS\*(FR\s0"
+
+.BT
+
+.\" --- Pattern Elements
+.ES
+.fi
+\*(CDAWK patterns may be one of the following.
+.sp .5
+.nf
+ \*(FCBEGIN
+ END
+ \*(FIexpression
+ pat1\*(FC,\*(FIpat2\*(FR
+.sp .5
+.fi
+\*(FCBEGIN\fP and \*(FCEND\fP are special patterns that provide start-up
+and clean-up actions respectively. They must have actions. There can
+be multiple \*(FCBEGIN\fP and \*(FCEND\fP rules; they are merged and
+executed as if there had just been one large rule. They may occur anywhere
+in a program, including different source files.
+.sp .5
+Expression patterns can be any expression, as described
+under \fHExpressions\fP.
+.sp .5
+The \*(FIpat1\*(FC,\*(FIpat2\*(FR pattern
+is called a \*(FIrange pattern\*(FR.
+It matches all input records starting with a record that matches
+\*(FIpat1\*(FR, and continuing until a record that matches
+\*(FIpat2\*(FR, inclusive.
+It does not combine with any other pattern expression.\*(CX
+.EB "\s+2\f(HBPATTERN ELEMENTS\*(FR\s0"
+
+
+.\" --- Action Statements
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CD\*(FCbreak\*(FR
+.br
+break out of the nearest enclosing \*(FCdo\*(FR, \*(FCfor\*(FR,
+or \*(FCwhile\*(FR loop.
+.ti -.2i
+\*(FCcontinue\*(FR
+.br
+skip the rest of the loop body.
+Evaluate the \*(FIcondition\*(FR
+part of the nearest enclosing \*(FCdo\*(FR or \*(FCwhile\*(FR loop,
+or go to the \*(FIincr\*(FR part of a \*(FCfor\*(FR loop.
+.ti -.2i
+\*(FCdelete \*(FIarray\^\*(FC[\^\*(FIindex\^\*(FC]\*(FR
+.br
+delete element \*(FIindex\*(FR from array \*(FIarray\*(FR.
+.ti -.2i
+\*(CL\*(FCdelete \*(FIarray\^\*(FR
+.br
+delete all elements from array \*(FIarray\*(FR.\*(CD
+.ti -.2i
+\*(FCdo \*(FIstatement \*(FCwhile (\*(FIcondition\*(FC)\*(FR
+.br
+execute \*(FIstatement\*(FR while \*(FIcondition\*(FR is true.
+The \*(FIstatement\*(FR is always executed at least once.
+.ti -.2i
+\*(FCexit\*(FR [ \*(FIexpression\*(FR ]
+.br
+terminate input record processing.
+Execute the \*(FCEND\*(FR rule(s) if present.
+If present, \*(FIexpression\*(FR becomes \*(AK's return value.
+.ti -.2i
+\*(FCfor (\*(FIinit\*(FC; \*(FIcond\*(FC; \*(FIincr\*(FC) \*(FIstatement\*(FR
+.br
+execute \*(FIinit\*(FR.
+Evaluate \*(FIcond\*(FR.
+If it is true, execute \*(FIstatement\*(FR.
+Execute \*(FIincr\*(FR before going back to the top to
+re-evaluate \*(FIcond\*(FR.
+Any of the three may be omitted.
+A missing \*(FIcond\*(FR is considered to be true.
+.ti -.2i
+\*(FCfor (\*(FIvar \*(FCin\*(FI array\*(FC) \*(FIstatement\*(FR
+.br
+execute \*(FIstatement\*(FR once for each subscript in \*(FIarray\*(FR,
+with \*(FIvar\*(FR set to a different subscript each time through
+the loop.
+.ti -.2i
+\*(CD\*(FCif (\*(FIcondition\*(FC) \*(FIstatement1\*(FR [ \*(FCelse\*(FI statement2\*(FR ]
+.br
+if \*(FIcondition\*(FR is true, execute \*(FIstatement1\*(FR,
+otherwise execute \*(FIstatement2\*(FR. Each \*(FCelse\*(FR
+matches the closest \*(FCif\*(FR.
+.ti -.2i
+\*(FCnext\*(FR see \fHInput Control.\fP
+.ti -.2i
+\*(CL\*(FCnextfile\*(FR \*(CR(not \*(MK) \*(CLsee \fHInput Control.\fP\*(CD
+.ti -.2i
+.\" --- Start switch statement
+\*(CB\*(FCswitch (\*(FIexpression\*(FC) {
+.br
+ case [\*(FIvalue\*(FC|\*(FIregular expression\*(FC] : \*(FIstatement(s)\*(FC
+.br
+ default: \*(FIstatement(s)\*(FC
+.br
+}\*(FR
+.br
+switch on \*(FIexpression\*(FR, execute \*(FIcase\*(FR if matched, default if not.
+For 3.1.x, requires \*(FC\-\^\-enable\-switch\*(FR option to \*(FCconfigure\*(FR.\*(CD
+.ti -.2i
+.\" --- End switch statement
+\*(FCwhile (\*(FIcondition\*(FC) \*(FIstatement \*(FR
+.br
+while \*(FIcondition\*(FR is true, execute \*(FIstatement\*(FR.
+.ti -.2i
+\*(FC{ \*(FIstatements \*(FC}\*(FR
+.br
+a list of statements enclosed in braces can be used anywhere
+that a single statement would otherwise be used.\*(CX
+.in -.2i
+.EB "\s+2\f(HBACTION STATEMENTS\*(FR\s0"
+
+
+.BT
+
+.\" --- Escape Sequences
+.ES
+.fi
+\*(CDWithin strings constants (\*(FC"..."\fP) and regexp
+constants (\*(FC/.../\fP), escape sequences may be used to
+generate otherwise unprintable characters. This table lists
+the available escape sequences.
+.sp .5
+.TS
+center, tab(~);
+lp8 lp8 lp8 lp8.
+\*(FC\ea\fP~alert (bell)~\*(FC\er\fP~carriage return
+\*(FC\eb\fP~backspace~\*(FC\et\fP~horizontal tab
+\*(FC\ef\fP~form feed~\*(FC\ev\fP~vertical tab
+\*(FC\en\fP~newline~\*(FC\e\e\fP~backslash
+\*(FC\e\*(FIddd\*(FR~octal value \*(FIddd\fP~\*(CL\*(FC\ex\*(FIhh\*(FR~hex value \*(FIhh\fP\*(CD
+\*(FC\e"\fP~double quote~\*(FC\e/\fP~forward slash\*(CX
+.TE
+.EB "\s+2\f(HBESCAPE SEQUENCES\*(FR\s0"
+.sp .7
+.\" --- Variables
+.ES
+.fi
+.TS
+expand;
+l lw(2i).
+\*(CD\*(FCARGC\fP T{
+number of command line arguments.
+T}
+\*(CB\*(FCARGIND\fP T{
+index in \*(FCARGV\fP of current data file.\*(CD
+T}
+\*(FCARGV\fP T{
+array of command line arguments. Indexed from
+0 to \*(FCARGC\fP \- 1. Dynamically changing the
+contents of \*(FCARGV\fP can control the files used
+for data.
+T}
+\*(CL\*(FCBINMODE\fP T{
+controls ``binary'' mode for all file I/O. Values of 1, 2, or 3,
+indicate input, output, or all files, respectively, should use binary
+I/O. \*(CR(Not \*(NK.) \*(CLApplies only to non-POSIX systems.
+\*(CBFor \*(GK, string values of \*(FC"r"\fP, or \*(FC"w"\fP specify
+that input files, or output files, respectively, should use binary I/O.
+String values of \*(FC"rw"\fP or \*(FC"wr"\fP specify that all files
+should use binary I/O. Any other string value is treated as \*(FC"rw"\fP,
+but generates a warning message.\*(CD
+T}
+\*(FCCONVFMT\fP T{
+conversion format for numbers, default value
+is \*(FC"%.6g"\*(FR.
+T}
+\*(FCENVIRON\fP T{
+array containing the current environment.
+The array is indexed by the environment
+variables, each element being the value of
+that variable.
+T}
+\*(CB\*(FCERRNO\fP T{
+string describing the error if a
+\*(FCgetline\*(FR
+redirection or read
+fails, or if
+\*(FCclose()\*(FR fails.
+T}
+\*(FCFIELDWIDTHS\fP T{
+white-space separated list of fieldwidths. Used
+to parse the input into fields of fixed width,
+instead of the value of \*(FCFS\fP.\*(CD
+T}
+\*(FCFILENAME\fP T{
+name of the current input file. If no files given
+on the command line, \*(FCFILENAME\fP is ``\-''.
+\*(FCFILENAME\fP is undefined inside the \*(FCBEGIN\fP rule
+(unless set by \*(FCgetline\fP).
+T}
+\*(FCFNR\fP T{
+record number in current input file.
+T}
+\*(FCFS\fP T{
+input field separator, a space by default
+(see \fHFields\fP above).
+T}
+\*(CB\*(FCIGNORECASE\fP T{
+if non-zero, all regular expression and string
+operations ignore case.
+Array subscripting
+is \*(FInot\*(FR affected.
+However, the
+\*(FCasort()\*(FR
+and
+\*(FCasorti()\*(FR
+function are affected.
+T}
+\*(CB\*(FCLINT\fP T{
+provides dynamic control of the \*(FC\-\^\-lint\fP
+option from within an AWK program.
+When true, \*(GK
+prints lint warnings.
+When assigned the string value \*(FC"fatal"\*(FR,
+lint warnings become fatal errors, exactly like
+\*(FC\-\-lint=fatal\*(FR.
+Any other true value just prints warnings.\*(CD
+T}
+\*(FCNF\fP T{
+number of fields in the current input record.
+T}
+\*(FCNR\fP T{
+total number of input records seen so far.\*(CX
+T}
+.TE
+.EB "\s+2\f(HBVARIABLES\*(FR\s0"
+.BT
+
+.\" --- Variables (continued)
+.ES
+.fi
+.TS
+expand;
+l lw(2i).
+\*(CD\*(FCOFMT\fP T{
+output format for numbers, \*(FC"%.6g"\*(FR, by default.
+\*(CROld versions of \*(AK used this for number
+to string conversion.\*(CD
+T}
+\*(FCOFS\fP T{
+output field separator, a space by default.
+T}
+\*(FCORS\fP T{
+output record separator, a newline by default.
+T}
+\*(CB\*(FCPROCINFO\fP T{
+elements of this array provide access to info
+about the running AWK program. See
+\*(AM for details.\*(CD
+T}
+\*(FCRLENGTH\fP T{
+length of the string matched by \*(FCmatch()\*(FR;
+\-1 if no match.
+T}
+\*(FCRS\fP T{
+input record separator, a newline by default
+(see \fHRecords\fP above).
+T}
+\*(FCRSTART\fP T{
+index of the first character matched by
+\*(FCmatch()\*(FR; 0 if no match.
+T}
+\*(CB\*(FCRT\fP T{
+record terminator. \*(GK sets \*(FCRT\fP to the input
+text that matched the character or regular
+expression specified by \*(FCRS\*(FR.\*(CD
+T}
+\*(FCSUBSEP\fP T{
+character(s) used to separate multiple subscripts
+in array elements, by default \*(FC"\e034"\*(FR. (See
+\fHArrays\fP below).
+T}
+\*(CB\*(FCTEXTDOMAIN\fP T{
+the application's text domain for internationalization;
+used to find the localized
+translations for the program's strings.\*(CX
+T}
+.TE
+.EB "\s+2\f(HBVARIABLES (continued)\*(FR\s0"
+
+.\" --- Conversions and Comparisons
+.ES
+.fi
+\*(CDVariables and fields may be (floating point) numbers, strings or both.
+Context determines how the value of a variable is interpreted. If used in
+a numeric expression, it will be treated as a number, if used as a string
+it will be treated as a string.
+.sp .5
+To force a variable to be treated as a number, add 0 to it; to force it
+to be treated as a string, concatenate it with the null string.
+.sp .5
+When a string must be converted to a number, the conversion is accomplished
+using \*(FIstrtod\*(FR(3).
+A number is converted to a string by using the value of \*(FCCONVFMT\fP
+as a format string for \*(FIsprintf\*(FR(3),
+with the numeric value of the variable as the argument.
+However, even though all numbers in AWK are floating-point,
+integral values are \*(FIalways\fP converted as integers.
+.sp .5
+Comparisons are performed as follows:
+If two variables are numeric, they are compared numerically.
+If one value is numeric and the other has a string value that is a
+``numeric string,'' then comparisons are also done numerically.
+Otherwise, the numeric value is converted to a string, and a string
+comparison is performed.
+Two strings are compared, of course, as strings.
+.sp .5
+Note that string constants, such as \*(FC"57"\fP, are \*(FInot\fP
+numeric strings, they are string constants. The idea of ``numeric string''
+only applies to fields, \*(FCgetline\fP input,
+\*(FCFILENAME\*(FR, \*(FCARGV\fP elements, \*(FCENVIRON\fP
+elements and the elements of an array created by
+\*(FCsplit()\fP that are numeric strings.
+The basic idea is that \*(FIuser input\*(FR,
+and only user input, that looks numeric,
+should be treated that way.
+\*(CRNote that the POSIX standard applies the concept of
+``numeric string'' everywhere, even to string constants.
+However, this is
+clearly incorrect, and none of the three free \*(AK\*(FRs do this.\*(CD
+(Fortunately, this is fixed in the next version of the standard.)
+.sp .5
+Uninitialized variables have the numeric value 0 and the string value
+\*(FC"\^"\fP
+(the null, or empty, string).\*(CX
+.EB "\s+2\f(HBCONVERSIONS AND COMPARISONS\*(FR\s0"
+
+.BT
+
+.\" --- Historical Features
+.ES
+.fi
+\*(CD1. It is possible to call the \*(FClength()\fP
+built-in function not only with no argument, but even without parentheses.
+This feature is marked as ``deprecated'' in the POSIX standard, and \*(GK
+issues a warning about its use if \*(FC\-\^\-lint\fP
+is specified on the command line.
+.sp .5
+2. The \*(FCcontinue\fP
+and \*(FCbreak\fP statements may be used outside the body of a
+\*(FCwhile\*(FR, \*(FCfor\*(FR, or \*(FCdo\fP loop.
+Historical AWK implementations have treated such usage as
+equivalent to the \*(FCnext\fP statement.
+\*(GK supports this usage if \*(FC\-\^\-traditional\fP
+is specified.\*(CB
+.EB "\s+2\f(HBHISTORICAL FEATURES (\*(GK\f(HB)\*(FR\s0"
+
+.ES
+\*(CX
+.sp 47
+.EB "\s+2\f(HBNOTES\*(FR\s0"
+
+.BT
+
+.\" --- Arrays
+.ES
+.fi
+\*(CDAn array subscript is an expression between square brackets
+(\*(FC[ \*(FRand \*(FC]\*(FR).
+If the expression is a list
+(\*(FIexpr\*(FC, \*(FIexpr \*(FR...),
+then the subscript is a string consisting of the
+concatenation of the (string) value of each expression,
+separated by the value of the \*(FCSUBSEP\fP variable.
+This simulates multi-dimensional
+arrays. For example:
+.nf
+.sp .5
+ \*(FCi = "A";\^ j = "B";\^ k = "C"
+ x[i, j, k] = "hello, world\en"\*(FR
+.sp .5
+.fi
+assigns \*(FC"hello, world\en"\*(FR to the element of the array
+\*(FCx\fP
+indexed by the string \*(FC"A\e034B\e034C"\*(FR. All arrays in AWK
+are associative, i.e., indexed by string values.
+.sp .5
+Use the special operator \*(FCin\fP in an \*(FCif\fP
+or \*(FCwhile\fP statement to see if a particular value is
+an array index.
+.sp .5
+.nf
+ \*(FCif (val in array)
+ print array[val]\*(FR
+.sp .5
+.fi
+If the array has multiple subscripts, use
+\*(FC(i, j) in array\*(FR.
+.sp .5
+Use the \*(FCin\fP construct in a \*(FCfor\fP
+loop to iterate over all the elements of an array.
+.sp .5
+Use the \*(FCdelete\fP statement to delete an
+element from an array.
+\*(CLSpecifying just the array name without a subscript in
+the \*(FCdelete\fP
+statement deletes the entire contents of an array.\*(CX
+.EB "\s+2\f(HBARRAYS\*(FR\s0"
+
+.\" --- Expressions
+.ES
+.fi
+\*(CDExpressions are used as patterns, for controlling conditional action
+statements, and to produce parameter values when calling functions.
+Expressions may also be used as simple statements,
+particularly if they have side-effects such as assignment.
+Expressions mix \*(FIoperands\fP and \*(FIoperators\fP. Operands are
+constants, fields, variables, array elements, and the return
+values from function calls (both built-in and user-defined).
+.sp .5
+Regexp constants (\*(FC/\*(FIpat\*(FC/\*(FR), when used as simple expressions,
+i.e., not used on the right-hand side of
+\*(FC~\fP and \*(FC!~\fP, or as arguments to the
+\*(CB\*(FCgensub()\fP,\*(CD
+\*(FCgsub()\fP,
+\*(FCmatch()\fP,
+\*(FCsplit()\fP,
+and
+\*(FCsub()\fP,
+functions, mean \*(FC$0 ~ /\*(FIpat\*(FC/\*(FR.
+.sp .5
+The AWK operators, in order of decreasing precedence, are:
+.sp .5
+.fi
+.TS
+expand;
+l lw(1.8i).
+\*(FC(\&...)\*(FR grouping
+\*(FC$\fP field reference
+\*(FC++ \-\^\-\fP T{
+increment and decrement,
+prefix and postfix
+T}
+\*(FC^\fP \*(CL\*(FC**\*(FR\*(CD exponentiation
+\*(FC+ \- !\fP unary plus, unary minus, and logical negation
+\*(FC* / %\fP multiplication, division, and modulus
+\*(FC+ \-\fP addition and subtraction
+\*(FIspace\fP string concatenation
+\*(FC< >\fP less than, greater than
+\*(FC<= >=\fP less than or equal, greater than or equal
+\*(FC!= ==\fP not equal, equal
+\*(FC~ !~\fP regular expression match, negated match
+\*(FCin\fP array membership
+\*(FC&&\fP logical AND, short circuit
+\*(FC||\fP logical OR, short circuit
+\*(FC?\^:\fP in-line conditional expression
+.T&
+l s
+l lw(1.8i).
+\*(FC=\0+=\0\-=\0*=\0/=\0%=\0^=\0\*(CL**=\*(CD\fP
+ assignment operators\*(CX
+.TE
+.EB "\s+2\f(HBEXPRESSIONS\*(FR\s0"
+
+.BT
+
+.\" --- Input Control
+.ES
+.fi
+.TS
+expand;
+l lw(1.8i).
+\*(FCgetline\fP T{
+set \*(FC$0\fP from next record;
+set \*(FCNF\*(FR, \*(FCNR\*(FR, \*(FCFNR\*(FR.
+T}
+\*(FCgetline < \*(FIfile\*(FR set \*(FC$0\fP from next record of \*(FIfile\*(FR; set \*(FCNF\*(FR.
+\*(FCgetline \*(FIv\*(FR T{
+set \*(FIv\fP from next input record;
+set \*(FCNR\*(FR, \*(FCFNR\*(FR.
+T}
+\*(FCgetline \*(FIv \*(FC< \*(FIfile\*(FR set \*(FIv\fP from next record of \*(FIfile\*(FR.
+\*(FIcmd \*(FC| getline\*(FR pipe into \*(FCgetline\*(FR; set \*(FC$0\*(FR, \*(FCNF\*(FR.
+\*(FIcmd \*(FC| getline \*(FIv\*(FR pipe into \*(FCgetline\*(FR; set \*(FIv\*(FR.
+\*(CB\*(FIcmd \*(FC|& getline\*(FR co-process pipe into \*(FCgetline\*(FR; set \*(FC$0\*(FR, \*(FCNF\*(FR.
+.TE
+.fi
+.in +.2i
+.ti -.2i
+\*(FIcmd \*(FC|& getline \*(FIv\*(FR
+.br
+co-process pipe into \*(FCgetline\*(FR; set \*(FIv\*(FR.
+.ti -.2i
+\*(FCnext\fP
+.br
+stop processing the current input
+record. Read next input record and
+start over with the first pattern in the
+program. Upon end of the input data,
+execute any \*(FCEND\fP rule(s).
+.br
+.ti -.2i
+\*(CL\*(FCnextfile\fP
+.br
+stop processing the current input file.
+The next input record comes from the
+next input file. \*(FCFILENAME\fP \*(CBand
+\*(FCARGIND\fP\*(CL are updated, \*(FCFNR\fP is reset to 1,
+and processing starts over with the first
+pattern in the AWK program. Upon end
+of input data, execute any \*(FCEND\fP rule(s).
+\*(CREarlier versions of \*(GK used
+\*(FCnext file\*(FR, as two words.
+This usage is no longer supported.
+\*(CR\*(MK does not currently support \*(FCnextfile\*(FR.\*(CD
+.in -.2i
+.sp .5
+.fi
+\*(FCgetline\*(FR returns 0 on end of file and \-1 on an error.
+\*(CBUpon an error, \*(FCERRNO\*(FR contains a string describing
+the problem.\*(CX
+.EB "\s+2\f(HBINPUT CONTROL\*(FR\s0"
+
+.\" --- Output Control
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CL\*(FCfflush(\*(FR[\*(FIfile\^\*(FR]\*(FC)\*(FR
+.br
+flush any buffers associated
+with the open output file or pipe \*(FIfile\*(FR.\*(CD
+\*(CBIf no \*(FIfile\fP, then flush standard output.
+If \*(FIfile\fP is null, then flush all open output files and pipes
+\*(CR(not \*(NK)\*(CD.
+.ti -.2i
+\*(FCprint\fP
+.br
+print the current record. Terminate output record
+with \*(FCORS\fP.
+.ti -.2i
+\*(FCprint \*(FIexpr-list\*(FR
+.br
+print expressions. Each expression is separated
+by the value of \*(FCOFS\fP. Terminate the output record
+with \*(FCORS\fP.
+.ti -.2i
+\*(FCprintf \*(FIfmt\*(FC, \*(FIexpr-list\*(FR
+.br
+format and print (see \fHPrintf Formats\fP below).
+.ti -.2i
+\*(FCsystem(\*(FIcmd\*(FC)\*(FR
+.br
+execute the command \*(FIcmd\*(FR,
+and return the exit status
+\*(CR(may not be available on non-POSIX systems)\*(CD.
+.sp .5
+.in -.2i
+I/O redirections may be used with both \*(FCprint\fP and \*(FCprintf\fP.
+.sp .5
+.in +.2i
+.ti -.2i
+\*(CD\*(FCprint "hello" > \*(FIfile\*(FR
+.br
+print data to \*(FIfile\fP. The first time the file is written to, it
+is truncated. Subsequent commands append data.
+.ti -.2i
+\*(FCprint "hello" >> \*(FIfile\*(FR
+.br
+append data to \*(FIfile\fP. The previous contents of \*(FIfile\*(FR are not lost.
+.ti -.2i
+\*(FCprint "hello" | \*(FIcmd\*(FR
+.br
+print data down a pipeline to \*(FIcmd\*(FR.
+.ti -.2i
+\*(CB\*(FCprint "hello" |& \*(FIcmd\*(FR
+.br
+print data down a pipeline to co-process \*(FIcmd\*(FR.\*(CX
+.in -.2i
+.EB "\s+2\f(HBOUTPUT CONTROL\*(FR\s0"
+
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CD\*(FCclose(\*(FIfile\*(FC)\*(FR
+.br
+close input or output file, pipe \*(CBor co-process.\*(CD
+.ti -.2i
+\*(CB\*(FCclose(\*(FIcommand\*(FC, \*(FIhow\*(FC)\*(FR
+.br
+close one end of co-process pipe.
+Use \*(FC"to"\*(FR for the write end, or
+\*(FC"from"\*(FR for the read end.\*(CD
+.in -.2i
+.sp .5
+On success, \*(FCclose()\*(FR returns zero for a file, or the exit status for a process.
+It returns \-1 if \*(FIfile\*(FR
+was never opened, or
+if there was a system problem.
+\*(CB\*(FCERRNO\*(FR describes
+the error.\*(CX
+.EB "\s+2\f(HBCLOSING REDIRECTIONS\*(FR\s0"
+
+.BT
+
+.\" --- Printf Formats
+.ES
+.fi
+\*(CDThe \*(FCprintf\fP statement and
+\*(FCsprintf()\fP function
+accept the following conversion specification formats:
+.sp .5
+.nf
+\*(FC%c\fP an \s-1ASCII\s+1 character
+\*(FC%d\fP a decimal number (the integer part)
+\*(FC%i\fP a decimal number (the integer part)
+\*(FC%e\fP a floating point number of the form
+ \*(FC[\-]d.dddddde[+\^\-]dd\*(FR
+\*(FC%E\fP like \*(FC%e\fP, but use \*(FCE\fP instead of \*(FCe\*(FR
+\*(FC%f\fP a floating point number of the form
+ \*(FC[\-]ddd.dddddd\*(FR
+\*(FC%g\fP use \*(FC%e\fP or \*(FC%f\fP, whichever is shorter, with
+ nonsignificant zeros suppressed
+\*(FC%G\fP like \*(FC%g\fP, but use \*(FC%E\fP instead of \*(FC%e\*(FR
+\*(FC%o\fP an unsigned octal integer
+\*(FC%u\fP an unsigned decimal integer
+\*(FC%s\fP a character string
+\*(FC%x\fP an unsigned hexadecimal integer
+\*(FC%X\fP like \*(FC%x\fP, but use \*(FCABCDEF\fP for 10\(en15
+\*(FC%%\fP A literal \*(FC%\fP; no argument is converted
+.sp .5
+.fi
+Optional, additional parameters may lie between the \*(FC%\fP
+and the control letter:
+.sp .5
+.TS
+expand;
+l lw(2.2i).
+\*(CB\*(FIcount\*(FC$\*(FR T{
+use the
+\*(FIcount\*(FR'th
+argument at this point in the formatting
+(a \*(FIpositional specifier\*(FR).
+Use in translated versions of
+format strings, not in the original text of an AWK program.\*(CD
+T}
+\*(FC\-\fP T{
+left-justify the expression within its field.
+T}
+\*(FIspace\fP T{
+for numeric conversions, prefix positive values
+with a space and negative values with a
+minus sign.
+T}
+\*(FC+\fP T{
+used before the \*(FIwidth\fP modifier means to always
+supply a sign for numeric conversions, even if
+the data to be formatted is positive. The \*(FC+\fP
+overrides the space modifier.
+T}
+\*(FC#\fP T{
+use an ``alternate form'' for some control letters.
+T}
+ \*(FC%o\*(FR T{
+supply a leading zero.
+T}
+ \*(FC%x\*(FR, \*(FC%X\*(FR T{
+supply a leading \*(FC0x\*(FR or \*(FC0X\*(FR for a nonzero result.
+T}
+ \*(FC%e\*(FR, \*(FC%E\*(FR, \*(FC%f\*(FR T{
+the result always has a decimal point.
+T}
+ \*(FC%g\*(FR, \*(FC%G\*(FR T{
+trailing zeros are not removed.
+T}
+\*(FC0\fP T{
+a leading zero acts as a flag, indicating output
+should be padded with zeros instead of spaces.
+This applies even to non-numeric output formats.
+Only has an effect when the field width is wider
+than the value to be printed.
+T}
+\*(FIwidth\fP T{
+pad the field to this width. The field is normally
+padded with spaces. If the \*(FC0\fP flag has been used,
+pad with zeros.
+T}
+\*(FC.\*(FIprec\*(FR T{
+precision.
+The meaning of the \*(FIprec\*(FR varies by control letter:
+T}
+ \*(FC%d\*(FR, \*(FC%o\*(FR, \*(FC%i\*(FR,
+ \*(FC%u\*(FR, \*(FC%x\*(FR, \*(FC%X\fP T{
+the minimum number of digits to print.
+T}
+ \*(FC%e\*(FR, \*(FC%E\*(FR, \*(FC%f\*(FR T{
+the number of digits to print to the right of the decimal point.
+T}
+ \*(FC%g\*(FR, \*(FC%G\fP T{
+the maximum number of significant digits.
+T}
+ \*(FC%s\fP T{
+the maximum number of characters to print.
+T}
+.TE
+.sp .5
+.fi
+The dynamic \*(FIwidth\fP and \*(FIprec\fP capabilities of the ANSI C
+\*(FCprintf()\fP routines are supported.
+A \*(FC*\fP in place of either the \*(FIwidth\fP or \*(FIprec\fP
+specifications causes their values to be taken from
+the argument list to \*(FCprintf\fP or \*(FCsprintf()\*(FR.
+\*(CBUse \*(FC*\*(FIn\*(FC$\*(FR to use positional specifiers
+with a dynamic width or precision.\*(CX
+.EB "\s+2\f(HBPRINTF FORMATS\*(FR\s0"
+
+
+.BT
+
+.\" --- Special Filenames
+.ES
+.fi
+\*(CDWhen doing I/O redirection from either \*(FCprint\fP
+or \*(FCprintf\fP into a file or via \*(FCgetline\fP
+from a file, all three implementations of \*(FCawk\fP
+recognize certain special filenames internally. These filenames
+allow access to open file descriptors inherited from the
+parent process (usually the shell).
+These filenames may also be used on the command line to name data files.
+The filenames are:
+.sp .5
+.TS
+expand;
+l lw(2i).
+\*(FC"\-"\fP standard input
+\*(FC/dev/stdin\fP standard input \*(CR(not \*(MK)\*(CD
+\*(FC/dev/stdout\fP standard output
+\*(FC/dev/stderr\fP standard error output
+.TE
+.sp .5
+.fi
+\*(CBThe following names are specific to \*(GK.
+.sp .5
+.in +.2i
+.ti -.2i
+\*(FC/dev/fd/\^\*(FIn\*(FR
+.br
+File associated with the open file descriptor \*(FIn\*(FR.
+.ti -.2i
+\*(FC/inet/tcp/\*(FIlport\*(FC/\*(FIrhost\*(FC/\*(FIrport\*(FR
+.br
+File for TCP/IP connection on local port \*(FIlport\*(FR to
+remote host \*(FIrhost\*(FR on remote port \*(FIrport\*(FR.
+Use a port of \*(FC0\*(FR to have the system pick a port.
+Usable only with the \*(FC|&\*(FR two-way I/O operator.
+.ti -.2i
+\*(FC/inet/udp/\*(FIlport\*(FC/\*(FIrhost\*(FC/\*(FIrport\*(FR
+.br
+Similar, but use UDP/IP instead of TCP/IP.
+.ti -.2i
+\*(CR\*(FC/inet/raw/\*(FIlport\*(FC/\*(FIrhost\*(FC/\*(FIrport\*(FR
+.br
+.\" Similar, but use raw IP sockets.
+Reserved for future use.\*(CB
+.in -.2i
+.sp .5
+.fi
+Other special filenames provide access to information about the running
+\*(FCgawk\fP process.
+Reading from these files returns a single record.
+The filenames and what they return are:\*(FR
+.sp .5
+.TS
+expand;
+l lw(2i).
+\*(FC/dev/pid\fP process ID of current process
+\*(FC/dev/ppid\fP parent process ID of current process
+\*(FC/dev/pgrpid\fP process group ID of current process
+\*(FC/dev/user\fP T{
+.nf
+a single newline-terminated record.
+The fields are separated with spaces.
+\*(FC$1\fP is the return value of \*(FIgetuid\*(FR(2),
+\*(FC$2\fP is the return value of \*(FIgeteuid\*(FR(2),
+\*(FC$3\fP is the return value of \*(FIgetgid\*(FR(2) , and
+\*(FC$4\fP is the return value of \*(FIgetegid\*(FR(2).
+.fi
+Any additional fields are the group IDs returned
+by \*(FIgetgroups\*(FR(2). Multiple groups may not be
+supported on all systems.
+T}
+.TE
+.sp .5
+.fi
+\*(CRThese filenames are now obsolete.
+Use the \*(FCPROCINFO\fP array to obtain the information they provide.\*(CL
+.EB "\s+2\f(HBSPECIAL FILENAMES\*(FR\s0"
+.sp .5
+.\" --- Builtin Numeric Functions
+.ES
+.fi
+.TS
+expand;
+l lw(2i).
+\*(CD\*(FCatan2(\*(FIy\*(FC, \*(FIx\*(FC)\*(FR the arctangent of \*(FIy/x\fP in radians.
+\*(FCcos(\*(FIexpr\*(FC)\*(FR the cosine of \*(FIexpr\fP, which is in radians.
+\*(FCexp(\*(FIexpr\*(FC)\*(FR the exponential function (\*(FIe \*(FC^ \*(FIx\*(FR).
+\*(FCint(\*(FIexpr\*(FC)\*(FR truncates to integer.
+\*(FClog(\*(FIexpr\*(FC)\*(FR the natural logarithm function (base \*(FIe\^\*(FR).
+\*(FCrand()\fP a random number between 0 and 1 (0 \(<= \*(FIN\fP < 1).
+\*(FCsin(\*(FIexpr\*(FC)\*(FR the sine of \*(FIexpr\fP, which is in radians.
+\*(FCsqrt(\*(FIexpr\*(FC)\*(FR the square root function.
+\&\*(FCsrand(\*(FR[\*(FIexpr\^\*(FR]\*(FC)\*(FR T{
+uses \*(FIexpr\fP as a new seed for the random number
+generator. If no \*(FIexpr\fP, the time of day is used.
+Returns previous seed for the random number
+generator.\*(CX
+T}
+.TE
+.EB "\s+2\f(HBNUMERIC FUNCTIONS\*(FR\s0"
+.sp .5
+.\" --- Extensions
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CD\*(FCextension(\*(FIlib\*(FC, \*(FIfunc\*(FC)\*(FR
+.br
+dynamically load the shared library
+\*(FIlib\*(FR
+and call
+\*(FIfunc\*(FR
+in it to initialize the library.
+This adds new built-in functions to \*(GK.
+It returns the value returned by
+\*(FIfunc\*(FR.\*(CB
+.in -.2i
+.EB "\s+2\f(HBDYNAMIC EXTENSIONS (\*(GK\f(HB)\*(FR\s0"
+
+
+.BT
+
+.\" --- Builtin String Functions
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CB\*(FCasort(\*(FIs\*(FC \*(FR[\*(FC, \*(FId\*(FR]\*(FC)\*(FR
+.br
+sorts the source array \*(FIs\*(FR, replacing the indices with numeric
+values 1 through \*(FIn\*(FR (the number of elements in the array),
+and returns the number of elements.
+If destination \*(FId\*(FR is supplied, \*(FIs\*(FR is copied to \*(FId\*(FR,
+\*(FId\*(FR is sorted, and \*(FIs\*(FR is unchanged.\*(CD
+.ti -.2i
+\*(CB\*(FCasorti(\*(FIs\*(FC \*(FR[\*(FC, \*(FId\*(FR]\*(FC)\*(FR
+.br
+like \*(FCasort()\*(FR, but sorting is done on the indices, not
+the values. The original values are thrown array, so provide a
+second array to preserve the first.\*(CD
+.ti -.2i
+\*(CB\*(FCgensub(\*(FIr\*(FC, \*(FIs\*(FC, \*(FIh \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+search the target string
+\*(FIt\fP for matches of the regular expression \*(FIr\*(FR. If
+\*(FIh\fP is a string beginning with \*(FCg\fP or \*(FCG\*(FR,
+replace all matches of \*(FIr\fP with \*(FIs\*(FR. Otherwise, \*(FIh\fP
+is a number indicating which match of \*(FIr\fP to replace.
+If \*(FIt\fP is not supplied, \*(FC$0\fP is used instead. Within the
+replacement text \*(FIs\*(FR, the sequence \*(FC\e\*(FIn\*(FR,
+where \*(FIn\fP is a digit from 1 to 9, may be used to indicate just
+the text that matched the \*(FIn\*(FRth parenthesized subexpression.
+The sequence \*(FC\e0\fP represents the entire matched text, as does
+the character \*(FC&\*(FR. Unlike \*(FCsub()\fP and \*(FCgsub()\*(FR,
+the modified string is returned as the result of the function,
+and the original target string is \*(FInot\fP changed.\*(CD
+.ti -.2i
+\*(FCgsub(\*(FIr\*(FC, \*(FIs \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+for each substring matching the
+regular expression \*(FIr\fP in the string \*(FIt\*(FR, substitute the
+string \*(FIs\*(FR, and return the number of substitutions. If
+\*(FIt\fP is not supplied, use \*(FC$0\*(FR. An \*(FC&\fP in the
+replacement text is replaced with the text that was actually matched.
+Use \*(FC\e&\fP to get a literal \*(FC&\*(FR. See \*(AM
+for a fuller discussion of the rules for \*(FC&\*(FR's and backslashes
+in the replacement text of \*(CB\*(FCgensub()\*(FR,\*(CD \*(FCsub()\*(FR
+and \*(FCgsub()\*(FR
+.ti -.2i
+\*(FCindex(\*(FIs\*(FC, \*(FIt\*(FC)\*(FR
+.br
+returns the index of the string
+\*(FIt\fP in the string \*(FIs\*(FR, or 0 if \*(FIt\fP is not present.
+.ti -.2i
+\*(FClength(\*(FR[\*(FIs\*(FR]\*(FC)\*(FR
+.br
+returns the length of the string
+\*(FIs\*(FR, or the length of \*(FC$0\fP if \*(FIs\fP is not supplied.
+\*(CBWith an array argument, returns the number of elements
+in the array.\*(CD
+.ti -.2i
+\*(FCmatch(\*(FIs\*(FC, \*(FIr \*(CB\*(FR[\*(FC, \*(FIa\*(FR]\*(CD\*(FC)\*(FR
+.br
+returns the position in
+\*(FIs\fP where the regular expression \*(FIr\fP occurs, or 0 if
+\*(FIr\fP is not present, and sets the values of variables
+\*(FCRSTART\fP
+and \*(FCRLENGTH\*(FR.
+\*(CBIf \*(FIa\*(FR is supplied, the text matching all of \*(FIr\*(FR
+is placed in \*(FIa\*(FC[0]\*(FR. If there were parenthesized
+subexpressions, the matching texts are placed
+in \*(FIa\*(FC[1]\*(FR, \*(FIa\*(FC[2]\*(FR, and so on.
+Subscripts
+\*(FCa[\*(FIn\^\*(FC, "start"]\*(FR,
+and
+\*(FCa[\*(FIn\^\*(FC, "length"]\*(FR
+provide the starting index in the string and length
+respectively, of each matching substring.\*(CD
+.ti -.2i
+\*(FCsplit(\*(FIs\*(FC, \*(FIa \*(FR[\*(FC, \*(FIr\*(FR]\*(FC)\*(FR
+.br
+splits the string
+\*(FIs\fP into the array \*(FIa\fP using the regular expression \*(FIr\*(FR,
+and returns the number of fields. If \*(FIr\fP is omitted, \*(FCFS\fP
+is used instead. The array \*(FIa\fP is cleared first.
+Splitting behaves identically to field splitting.
+(See \fHFields\fP, above.)
+.ti -.2i
+\*(FCsprintf(\*(FIfmt\*(FC, \*(FIexpr-list\*(FC)\*(FR
+.br
+prints \*(FIexpr-list\fP
+according to \*(FIfmt\*(FR, and returns the resulting string.
+.ti -.2i
+\*(CB\*(FCstrtonum(\*(FIs\*(FC)\*(FR
+.br
+examines \*(FIs\*(FR, and returns its numeric value.
+If \*(FIs\*(FR begins with a leading \*(FC0\*(FR,
+\*(FCstrtonum()\*(FR assumes that \*(FIs\*(FR
+is an octal number.
+If \*(FIs\*(FR begins with a leading \*(FC0x\*(FR
+or \*(FC0X\*(FR, \*(FCstrtonum()\*(FR assumes that
+\*(FIs\*(FR is a hexadecimal number.\*(CD
+.ti -.2i
+\*(FCsub(\*(FIr\*(FC, \*(FIs \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+just like
+\*(FCgsub()\*(FR, but only the first matching substring is replaced.\*(CX
+.in -.2i
+.EB "\s+2\f(HBSTRING FUNCTIONS\*(FR\s0"
+
+.BT
+
+.\" --- Builtin String Functions
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CD\*(FCsubstr(\*(FIs\*(FC, \*(FIi \*(FR[\*(FC, \*(FIn\*(FR]\*(FC)\*(FR
+.br
+returns the at most
+\*(FIn\*(FR-character substring of \*(FIs\fP starting at \*(FIi\*(FR.
+If \*(FIn\fP is omitted, the rest of \*(FIs\fP is used.
+.ti -.2i
+\*(FCtolower(\*(FIstr\*(FC)\*(FR
+.br
+returns a copy of the string \*(FIstr\*(FR,
+with all the upper-case characters in \*(FIstr\fP translated to their
+corresponding lower-case counterparts. Non-alphabetic characters are
+left unchanged.
+.ti -.2i
+\*(FCtoupper(\*(FIstr\*(FC)\*(FR
+.br
+returns a copy of the string \*(FIstr\*(FR,
+with all the lower-case characters in \*(FIstr\fP translated to their
+corresponding upper-case counterparts. Non-alphabetic characters are
+left unchanged.\*(CX
+.in -.2i
+.EB "\s+2\f(HBSTRING FUNCTIONS (continued)\*(FR\s0"
+
+.\" --- Builtin Time Functions
+.ES
+.fi
+\*(CD\*(GK
+provides the following functions for obtaining time stamps and
+formatting them.
+.sp .5
+.fi
+.in +.2i
+.ti -.2i
+\*(FCmktime(\*(FIdatespec\*(FC)\*(FR
+.br
+turns \*(FIdatespec\fP into a time
+stamp of the same form as returned by \*(FCsystime()\*(FR.
+The \*(FIdatespec\fP is a string of the form
+\*(FC"\*(FIYYYY MM DD HH MM SS[ DST]\*(FC"\*(FR.
+.ti -.2i
+\*(FCstrftime(\*(FR[\*(FIformat \*(FR[\*(FC, \*(FItimestamp\*(FR]]\*(FC)\*(FR
+.br
+formats \*(FItimestamp\fP
+according to the specification in \*(FIformat\*(FR. The
+\*(FItimestamp\fP should be of the same form as returned by
+\*(FCsystime()\*(FR.
+If \*(FItimestamp\fP is missing, the current time of day is used. If
+\*(FIformat\fP is missing, a default format equivalent to the output
+of \*(FIdate\*(FR(1) is used.
+.ti -.2i
+\*(FCsystime()\fP
+.br
+returns the current time of day as the number of
+seconds since the Epoch.\*(CB
+.in -.2i
+.EB "\s+2\f(HBTIME FUNCTIONS (\*(GK\f(HB)\*(FR\s0"
+
+.\" --- Builtin Bit Manipulation Functions
+.ES
+.fi
+\*(CD\*(GK
+provides the following functions for doing bitwise operations.
+.sp .5
+.fi
+.in +.2i
+.ti -.2i
+\*(FCand(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+.br
+returns the bitwise AND of the values provided by
+\*(FIv1\*(FR and \*(FIv2\*(FR.
+.ti -.2i
+\*(FCcompl(\*(FIval\*(FC)\*(FR
+.br
+returns the bitwise complement of
+\*(FIval\*(FR.
+.ti -.2i
+\*(FClshift(\*(FIval\*(FC, \*(FIcount\*(FC)\*(FR
+.br
+returns the value of \*(FIval\*(FR,
+shifted left by \*(FIcount\*(FR bits.
+.ti -.2i
+\*(FCor(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+.br
+returns the bitwise OR of the values provided by
+\*(FIv1\*(FR and \*(FIv2\*(FR.
+.ti -.2i
+\*(FCrshift(\*(FIval\*(FC, \*(FIcount\*(FC)\*(FR
+.br
+returns the value of \*(FIval\*(FR,
+shifted right by \*(FIcount\*(FR bits.
+.ti -.2i
+\*(FCxor(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+.br
+teturns the bitwise XOR of the values provided by
+\*(FIv1\*(FR and \*(FIv2\*(FR.\*(CB
+.in -.2i
+.EB "\s+2\f(HBBIT MANIPULATION FUNCTIONS (\*(GK\f(HB)\*(FR\s0"
+
+.\" --- Environment Variables
+.ES
+.fi
+\*(CDThe environment variable \*(FCAWKPATH\fP specifies a search path to use
+when finding source files named with the \*(FC\-f\fP
+option.
+The default path is
+\*(FC".:/usr/local/share/awk"\*(FR.
+.\" if this variable does not exist.
+.\" (The actual directory may vary,
+.\" depending upon how \*(GK was built and installed.)
+If a file name given to the \*(FC\-f\fP option contains a ``/'' character,
+no path search is performed.
+.sp .5
+If \*(FCPOSIXLY_CORRECT\fP exists
+.\" in the environment,
+then \*(GK
+behaves exactly as if the \*(FC\-\^\-posix\fP option had been given.\*(CB
+.EB "\s+2\f(HBENVIRONMENT VARIABLES (\*(GK\f(HB)\*(FR\s0"
+
+.BT
+
+.\" --- User-defined Functions
+.ES
+.fi
+\*(CDFunctions in AWK are defined as follows:
+.sp .5
+.nf
+ \*(FCfunction \*(FIname\*(FC(\*(FIparameter list\*(FC)
+ {
+ \*(FIstatements
+ \*(FC}\*(FR
+.sp .5
+.fi
+Functions are executed when they are called from within expressions
+in either patterns or actions. Actual parameters supplied in the function
+call instantiate the formal parameters declared in the function.
+Arrays are passed by reference, other variables are passed by value.
+.sp .5
+Local variables are declared as extra parameters
+in the parameter list. The convention is to separate local variables from
+real parameters by extra spaces in the parameter list. For example:
+.sp .5
+.nf
+ \*(FC# a and b are local
+ function f(p, q, a, b)
+ {
+ \&.....
+ }
+.sp .3
+ /abc/ { ... ; f(1, 2) ; ... }\*(FR
+.fi
+.sp .5
+The left parenthesis in a function call is required
+to immediately follow the function name
+without any intervening white space.
+This is to avoid a syntactic ambiguity with the concatenation operator.
+This restriction does not apply to the built-in functions.
+.sp .5
+Functions may call each other and may be recursive.
+Function parameters used as local variables are initialized
+to the null string and the number zero upon function invocation.
+.sp .5
+Use \*(FCreturn\fP to return a value from a function. The return value
+is undefined if no value is provided, or if the function returns by
+``falling off'' the end.
+.sp .5
+\*(CLThe word
+\*(FCfunc\fP
+may be used in place of
+\*(FCfunction\*(FR.
+\*(CRNote: This usage is deprecated.\*(CX
+.EB "\s+2\f(HBUSER-DEFINED FUNCTIONS\*(FR\s0"
+
+.\" --- Localization
+.ES
+.fi
+\*(CDThere are several steps involved in producing and running a localizable
+\*(AK program.
+.sp .5
+1. Add a \*(FCBEGIN\*(FR action to assign a value to the
+\*(FCTEXTDOMAIN\*(FR variable to set the text domain for
+your program.
+.sp .5
+.ti +5n
+\*(FCBEGIN { TEXTDOMAIN = "myprog" }\*(FR
+.sp .5
+This allows \*(GK to find the \*(FC\&.mo\*(FR
+file associated with your program.
+Without this step, \*(GK uses the \*(FCmessages\*(FR text domain,
+which probably won't work.
+.sp .5
+2. Mark all strings that should be translated with leading underscores.
+.sp .5
+3. Use the
+\*(FCbindtextdomain()\*(FR,
+\*(FCdcgettext()\*(FR,
+and/or
+\*(FCdcngettext()\*(FR
+functions in your program, as appropriate.
+.sp .5
+4. Run
+.sp .5
+.ti +5n
+\*(FCgawk \-\^\-gen\-po \-f myprog.awk > myprog.po\*(FR
+.sp .5
+to generate a \*(FC\&.po\*(FR
+file for your program.
+.sp .5
+5. Provide appropriate translations, and build and install a corresponding
+\*(FC\&.mo\*(FR file.
+.sp .5
+The internationalization features are described in full detail in \*(AM.\*(CB
+.EB "\s+2\f(HBLOCALIZATION (\*(GK\f(HB)\*(FR\s0"
+
+
+.BT
+
+.\" --- Builtin Internationalization Functions
+.ES
+.fi
+\*(CD\*(GK
+provides the following functions for runtime message translation.
+.in +.2i
+.sp .5
+.ti -.2i
+\*(FCbindtextdomain(\*(FIdirectory \*(FR[\*(FC, \*(FIdomain\*(FR]\*(FC)\*(FR
+.br
+specifies the directory where \*(GK looks for the \*(FC\&.mo\*(FR
+files, in case they
+will not or cannot be placed in the ``standard'' locations
+(e.g., during testing.)
+It returns the directory where \*(FIdomain\*(FR is ``bound.''
+.sp .5
+The default \*(FIdomain\*(FR is the value of \*(FCTEXTDOMAIN\*(FR.
+When \*(FIdirectory\*(FR is the null string (\*(FC"\^"\*(FR),
+\*(FCbindtextdomain()\*(FR returns the current binding for the
+given \*(FIdomain\*(FR.
+.ti -.2i
+\*(FCdcgettext(\*(FIstring \*(FR[\*(FC, \*(FIdomain \*(FR[\*(FC, \*(FIcategory\*(FR]]\*(FC)\*(FR
+.br
+returns the translation of \*(FIstring\*(FR in text domain
+\*(FIdomain\*(FR for locale category \*(FIcategory\*(FR.
+The default value for \*(FIdomain\*(FR is the current value of \*(FCTEXTDOMAIN\*(FR.
+The default value for \*(FIcategory\*(FR is \*(FC"LC_MESSAGES"\*(FR.
+.sp .5
+If you supply a value for \*(FIcategory\*(FR, it must be a string equal to
+one of the known locale categories.
+You must also supply a text domain. Use \*(FCTEXTDOMAIN\*(FR
+to use the current domain.
+.ti -.2i
+\*(FCdcngettext(\*(FIstring1\*(FC, \*(FIstring2\*(FC, \*(FInumber\*(FR [\*(FC, \*(FIdom \*(FR[\*(FC, \*(FIcat\*(FR]]\*(FC)\*(FR
+.br
+returns the plural form used for \*(FInumber\*(FR of the translation of
+\*(FIstring1\*(FR and \*(FIstring2\*(FR in text domain
+\*(FIdom\*(FR for locale category \*(FIcat\*(FR.
+The default value for \*(FIdom\*(FR is the current value of \*(FCTEXTDOMAIN\*(FR.
+\*(FC"LC_MESSAGES"\*(FR
+is the default value for \*(FIcat\*(FR.
+.sp .5
+If you supply a value for \*(FIcat\*(FR, it must be a string equal to
+one of the known locale categories.
+You must also supply a text domain. Use \*(FCTEXTDOMAIN\*(FR
+to use the current domain.\*(CB
+.in -.2i
+.EB "\s+2\f(HBINTERNATIONALIZATION (\*(GK\f(HB)\*(FR\s0"
+
+
+.\" --- FTP/HTTP Information
+.ES
+.nf
+\*(CDHost: \*(FCftp.gnu.org\*(FR
+File: \*(FC/gnu/gawk/gawk-3.1.5.tar.gz\fP
+.in +.2i
+.fi
+GNU \*(AK (\*(GK). There may be a later version.
+.in -.2i
+.nf
+.sp .5
+\*(FChttp://cm.bell-labs.com/who/bwk/awk.tar.gz\fP
+.in +.2i
+.fi
+\*(NK. This version requires an ANSI C compiler;
+GCC (the GNU Compiler Collection) works well.
+.in -.2i
+.nf
+.sp .5
+Host: \*(FCftp.whidbey.net\*(FR
+File: \*(FC/pub/brennan/mawk1.3.3.tar.gz\fP
+.in +.2i
+.fi
+Michael Brennan's \*(MK. There may be a newer version.\*(CX
+.in -.2i
+.EB "\s+2\f(HBFTP/HTTP INFORMATION\*(FR\s0"
+
+
+.\" --- Copying Permissions
+.ES
+.fi
+\*(CDCopyright \(co 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+.sp .5
+Permission is granted to make and distribute verbatim copies of this
+reference card provided the copyright notice and this permission notice
+are preserved on all copies.
+.sp .5
+Permission is granted to copy and distribute modified versions of this
+reference card under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.sp .5
+Permission is granted to copy and distribute translations of this
+reference card into another language, under the above conditions for
+modified versions, except that this permission notice may be stated in a
+translation approved by the Foundation.\*(CX
+.EB "\s+2\f(HBCOPYING PERMISSIONS\*(FR\s0"
+.BT
--- /dev/null
+Draft for ACM SIGPLAN Patterns (Language Trends)
+
+1996
+
+Why GAWK for AI?
+
+Ronald P. Loui
+
+Most people are surprised when I tell them what language we use in our
+undergraduate AI programming class. That's understandable. We use
+GAWK. GAWK, Gnu's version of Aho, Weinberger, and Kernighan's old
+pattern scanning language isn't even viewed as a programming language by
+most people. Like PERL and TCL, most prefer to view it as a "scripting
+language." It has no objects; it is not functional; it does no built-in
+logic programming. Their surprise turns to puzzlement when I confide
+that (a) while the students are allowed to use any language they want;
+(b) with a single exception, the best work consistently results from
+those working in GAWK. (footnote: The exception was a PASCAL
+programmer who is now an NSF graduate fellow getting a Ph.D. in
+mathematics at Harvard.) Programmers in C, C++, and LISP haven't even
+been close (we have not seen work in PROLOG or JAVA).
+
+Why GAWK?
+
+There are some quick answers that have to do with the pragmatics of
+undergraduate programming. Then there are more instructive answers that
+might be valuable to those who debate programming paradigms or to those
+who study the history of AI languages. And there are some deep
+philosophical answers that expose the nature of reasoning and symbolic
+AI. I think the answers, especially the last ones, can be even more
+surprising than the observed effectiveness of GAWK for AI.
+
+First it must be confessed that PERL programmers can cobble together AI
+projects well, too. Most of GAWK's attractiveness is reproduced in
+PERL, and the success of PERL forebodes some of the success of GAWK.
+Both are powerful string-processing languages that allow the programmer
+to exploit many of the features of a UNIX environment. Both provide
+powerful constructions for manipulating a wide variety of data in
+reasonably efficient ways. Both are interpreted, which can reduce
+development time. Both have short learning curves. The GAWK manual can
+be consumed in a single lab session and the language can be mastered by
+the next morning by the average student. GAWK's automatic
+initialization, implicit coercion, I/O support and lack of pointers
+forgive many of the mistakes that young programmers are likely to make.
+Those who have seen C but not mastered it are happy to see that GAWK
+retains some of the same sensibilities while adding what must be
+regarded as spoonsful of syntactic sugar. Some will argue that
+PERL has superior functionality, but for quick AI applications, the
+additional functionality is rarely missed. In fact, PERL's terse syntax
+is not friendly when regular expressions begin to proliferate and
+strings contain fragments of HTML, WWW addresses, or shell commands.
+PERL provides new ways of doing things, but not necessarily ways of
+doing new things.
+
+In the end, despite minor difference, both PERL and GAWK minimize
+programmer time. Neither really provides the programmer the setting in
+which to worry about minimizing run-time.
+
+There are further simple answers. Probably the best is the fact that
+increasingly, undergraduate AI programming is involving the Web. Oren
+Etzioni (University of Washington, Seattle) has for a while been arguing
+that the "softbot" is replacing the mechanical engineers' robot as the
+most glamorous AI testbed. If the artifact whose behavior needs to be
+controlled in an intelligent way is the software agent, then a language
+that is well-suited to controlling the software environment is the
+appropriate language. That would imply a scripting language. If the
+robot is KAREL, then the right language is "turn left; turn right." If
+the robot is Netscape, then the right language is something that can
+generate "netscape -remote 'openURL(http://cs.wustl.edu/~loui)'" with
+elan.
+
+Of course, there are deeper answers. Jon Bentley found two pearls in
+GAWK: its regular expressions and its associative arrays. GAWK asks
+the programmer to use the file system for data organization and the
+operating system for debugging tools and subroutine libraries. There is
+no issue of user-interface. This forces the programmer to return to the
+question of what the program does, not how it looks. There is no time
+spent programming a binsort when the data can be shipped to /bin/sort
+in no time. (footnote: I am reminded of my IBM colleague Ben Grosof's
+advice for Palo Alto: Don't worry about whether it's highway 101 or 280.
+Don't worry if you have to head south for an entrance to go north. Just
+get on the highway as quickly as possible.)
+
+There are some similarities between GAWK and LISP that are illuminating.
+Both provided a powerful uniform data structure (the associative array
+implemented as a hash table for GAWK and the S-expression, or list of
+lists, for LISP). Both were well-supported in their environments (GAWK
+being a child of UNIX, and LISP being the heart of lisp machines). Both
+have trivial syntax and find their power in the programmer's willingness
+to use the simple blocks to build a complex approach.
+
+Deeper still, is the nature of AI programming. AI is about
+functionality and exploratory programming. It is about bottom-up design
+and the building of ambitions as greater behaviors can be demonstrated.
+Woe be to the top-down AI programmer who finds that the bottom-level
+refinements, "this subroutine parses the sentence," cannot actually be
+implemented. Woe be to the programmer who perfects the data structures
+for that heapsort when the whole approach to the high-level problem
+needs to be rethought, and the code is sent to the junkheap the next day.
+
+AI programming requires high-level thinking. There have always been a few
+gifted programmers who can write high-level programs in assembly language.
+Most however need the ambient abstraction to have a higher floor.
+
+Now for the surprising philosophical answers. First, AI has discovered
+that brute-force combinatorics, as an approach to generating intelligent
+behavior, does not often provide the solution. Chess, neural nets, and
+genetic programming show the limits of brute computation. The
+alternative is clever program organization. (footnote: One might add
+that the former are the AI approaches that work, but that is easily
+dismissed: those are the AI approaches that work in general, precisely
+because cleverness is problem-specific.) So AI programmers always want
+to maximize the content of their program, not optimize the efficiency
+of an approach. They want minds, not insects. Instead of enumerating
+large search spaces, they define ways of reducing search, ways of
+bringing different knowledge to the task. A language that maximizes
+what the programmer can attempt rather than one that provides tremendous
+control over how to attempt it, will be the AI choice in the end.
+
+Second, inference is merely the expansion of notation. No matter whether
+the logic that underlies an AI program is fuzzy, probabilistic, deontic,
+defeasible, or deductive, the logic merely defines how strings can be
+transformed into other strings. A language that provides the best
+support for string processing in the end provides the best support for
+logic, for the exploration of various logics, and for most forms of
+symbolic processing that AI might choose to call "reasoning" instead of
+"logic." The implication is that PROLOG, which saves the AI programmer
+from having to write a unifier, saves perhaps two dozen lines of GAWK
+code at the expense of strongly biasing the logic and representational
+expressiveness of any approach.
+
+I view these last two points as news not only to the programming language
+community, but also to much of the AI community that has not reflected on
+the past decade's lessons.
+
+In the puny language, GAWK, which Aho, Weinberger, and Kernighan thought
+not much more important than grep or sed, I find lessons in AI's trends,
+AI's history, and the foundations of AI. What I have found not only
+surprising but also hopeful, is that when I have approached the AI
+people who still enjoy programming, some of them are not the least bit
+surprised.
+
+
+R. Loui (loui@ai.wustl.edu) is Associate Professor of Computer Science,
+at Washington University in St. Louis. He has published in AI Journal,
+Computational Intelligence, ACM SIGART, AI Magazine, AI and Law, the ACM
+Computing Surveys Symposium on AI, Cognitive Science, Minds and
+Machines, Journal of Philosophy, and is on this year's program
+committees for AAAI (National AI conference) and KR (Knowledge
+Representation and Reasoning).
--- /dev/null
+.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
+.\" cardfonts --- this file sets the fonts to use for the reference card
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ig
+Strings for inline font change.
+FR - font roman
+FI - font italic
+FC - font courier
+..
+.ds FR \fR
+.ds FI \fI
+.ds FC \f(CB
+.ds RN Times Roman
+.ds IN Times Italic
+.ds CN Courier Bold
+.ds AM \fIGAWK: Effective AWK Programming\fP
--- /dev/null
+.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
+.\" This file sets the colors to use.
+.\"
+.\" Copyright (C) 1996,97,99 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ig
+Strings for inline color change.
+CR - color red
+CG - color green
+CL - color light blue
+CB - color blue
+CD - color dark, i.e. black
+CX - color boX, i.e. for the surrounding boxes (red for now)
+..
+.ds CR \X'ps: exec 0 .96 .65 0 setcmykcolor'
+.ds CG \X'ps: exec 1.0 0 .51 .43 setcmykcolor'
+.ds CL \X'ps: exec .69 .34 0 0 setcmykcolor'
+.ds CB \X'ps: exec 1 .72 0 .06 setcmykcolor'
+.ds CD \X'ps: exec 1 1 1 1 setcmykcolor'
+.ds CX \*(CG
--- /dev/null
+.ds PX \s-1POSIX\s+1
+.ds UX \s-1UNIX\s+1
+.ds AN \s-1ANSI\s+1
+.ds GN \s-1GNU\s+1
+.ds AK \s-1AWK\s+1
+.ds EP \fIGAWK: Effective AWK Programming\fP
+.if !\n(.g \{\
+. if !\w|\*(lq| \{\
+. ds lq ``
+. if \w'\(lq' .ds lq "\(lq
+. \}
+. if !\w|\*(rq| \{\
+. ds rq ''
+. if \w'\(rq' .ds rq "\(rq
+. \}
+.\}
+.TH GAWK 1 "June 26 2005" "Free Software Foundation" "Utility Commands"
+.SH NAME
+gawk \- pattern scanning and processing language
+.SH SYNOPSIS
+.B gawk
+[ \*(PX or \*(GN style options ]
+.B \-f
+.I program-file
+[
+.B \-\^\-
+] file .\|.\|.
+.br
+.B gawk
+[ \*(PX or \*(GN style options ]
+[
+.B \-\^\-
+]
+.I program-text
+file .\|.\|.
+.sp
+.B pgawk
+[ \*(PX or \*(GN style options ]
+.B \-f
+.I program-file
+[
+.B \-\^\-
+] file .\|.\|.
+.br
+.B pgawk
+[ \*(PX or \*(GN style options ]
+[
+.B \-\^\-
+]
+.I program-text
+file .\|.\|.
+.SH DESCRIPTION
+.I Gawk
+is the \*(GN Project's implementation of the \*(AK programming language.
+It conforms to the definition of the language in
+the \*(PX 1003.2 Command Language And Utilities Standard.
+This version in turn is based on the description in
+.IR "The AWK Programming Language" ,
+by Aho, Kernighan, and Weinberger,
+with the additional features found in the System V Release 4 version
+of \*(UX
+.IR awk .
+.I Gawk
+also provides more recent Bell Laboratories
+.I awk
+extensions, and a number of \*(GN-specific extensions.
+.PP
+.I Pgawk
+is the profiling version of
+.IR gawk .
+It is identical in every way to
+.IR gawk ,
+except that programs run more slowly,
+and it automatically produces an execution profile in the file
+.B awkprof.out
+when done.
+See the
+.B \-\^\-profile
+option, below.
+.PP
+The command line consists of options to
+.I gawk
+itself, the \*(AK program text (if not supplied via the
+.B \-f
+or
+.B \-\^\-file
+options), and values to be made
+available in the
+.B ARGC
+and
+.B ARGV
+pre-defined \*(AK variables.
+.SH OPTION FORMAT
+.PP
+.I Gawk
+options may be either traditional \*(PX one letter options,
+or \*(GN style long options. \*(PX options start with a single \*(lq\-\*(rq,
+while long options start with \*(lq\-\^\-\*(rq.
+Long options are provided for both \*(GN-specific features and
+for \*(PX-mandated features.
+.PP
+Following the \*(PX standard,
+.IR gawk -specific
+options are supplied via arguments to the
+.B \-W
+option. Multiple
+.B \-W
+options may be supplied
+Each
+.B \-W
+option has a corresponding long option, as detailed below.
+Arguments to long options are either joined with the option
+by an
+.B =
+sign, with no intervening spaces, or they may be provided in the
+next command line argument.
+Long options may be abbreviated, as long as the abbreviation
+remains unique.
+.SH OPTIONS
+.PP
+.I Gawk
+accepts the following options, listed alphabetically.
+.TP
+.PD 0
+.BI \-F " fs"
+.TP
+.PD
+.BI \-\^\-field-separator " fs"
+Use
+.I fs
+for the input field separator (the value of the
+.B FS
+predefined
+variable).
+.TP
+.PD 0
+\fB\-v\fI var\fB\^=\^\fIval\fR
+.TP
+.PD
+\fB\-\^\-assign \fIvar\fB\^=\^\fIval\fR
+Assign the value
+.I val
+to the variable
+.IR var ,
+before execution of the program begins.
+Such variable values are available to the
+.B BEGIN
+block of an \*(AK program.
+.TP
+.PD 0
+.BI \-f " program-file"
+.TP
+.PD
+.BI \-\^\-file " program-file"
+Read the \*(AK program source from the file
+.IR program-file ,
+instead of from the first command line argument.
+Multiple
+.B \-f
+(or
+.BR \-\^\-file )
+options may be used.
+.TP
+.PD 0
+.BI \-mf " NNN"
+.TP
+.PD
+.BI \-mr " NNN"
+Set various memory limits to the value
+.IR NNN .
+The
+.B f
+flag sets the maximum number of fields, and the
+.B r
+flag sets the maximum record size. These two flags and the
+.B \-m
+option are from the Bell Laboratories research version of \*(UX
+.IR awk .
+They are ignored by
+.IR gawk ,
+since
+.I gawk
+has no pre-defined limits.
+.TP
+.PD 0
+.B "\-W compat"
+.TP
+.PD 0
+.B "\-W traditional"
+.TP
+.PD 0
+.B \-\^\-compat
+.TP
+.PD
+.B \-\^\-traditional
+Run in
+.I compatibility
+mode. In compatibility mode,
+.I gawk
+behaves identically to \*(UX
+.IR awk ;
+none of the \*(GN-specific extensions are recognized.
+The use of
+.B \-\^\-traditional
+is preferred over the other forms of this option.
+See
+.BR "GNU EXTENSIONS" ,
+below, for more information.
+.TP
+.PD 0
+.B "\-W copyleft"
+.TP
+.PD 0
+.B "\-W copyright"
+.TP
+.PD 0
+.B \-\^\-copyleft
+.TP
+.PD
+.B \-\^\-copyright
+Print the short version of the \*(GN copyright information message on
+the standard output and exit successfully.
+.TP
+.PD 0
+\fB\-W dump-variables\fR[\fB=\fIfile\fR]
+.TP
+.PD
+\fB\-\^\-dump-variables\fR[\fB=\fIfile\fR]
+Print a sorted list of global variables, their types and final values to
+.IR file .
+If no
+.I file
+is provided,
+.I gawk
+uses a file named
+.I awkvars.out
+in the current directory.
+.sp .5
+Having a list of all the global variables is a good way to look for
+typographical errors in your programs.
+You would also use this option if you have a large program with a lot of
+functions, and you want to be sure that your functions don't
+inadvertently use global variables that you meant to be local.
+(This is a particularly easy mistake to make with simple variable
+names like
+.BR i ,
+.BR j ,
+and so on.)
+.TP
+.PD 0
+.BI "\-W exec " file
+.TP
+.PD
+.BI \-\^\-exec " file"
+Similar to
+.BR \-f ,
+however, this is option is the last one processed.
+This should be used with
+.B #!
+scripts, particularly for CGI applications, to avoid
+passing in options or source code (!) on the command line
+from a URL.
+This option disables command-line variable assignments.
+.TP
+.PD 0
+.B "\-W gen\-po"
+.TP
+.PD
+.B \-\^\-gen\-po
+Scan and parse the \*(AK program, and generate a \*(GN
+.B \&.po
+format file on standard output with entries for all localizable
+strings in the program. The program itself is not executed.
+See the \*(GN
+.I gettext
+distribution for more information on
+.B \&.po
+files.
+.TP
+.PD 0
+.B "\-W help"
+.TP
+.PD 0
+.B "\-W usage"
+.TP
+.PD 0
+.B \-\^\-help
+.TP
+.PD
+.B \-\^\-usage
+Print a relatively short summary of the available options on
+the standard output.
+(Per the
+.IR "GNU Coding Standards" ,
+these options cause an immediate, successful exit.)
+.TP
+.PD 0
+.BR "\-W lint" [ =\fIvalue\fR ]
+.TP
+.PD
+.BR \-\^\-lint [ =\fIvalue\fR ]
+Provide warnings about constructs that are
+dubious or non-portable to other \*(AK implementations.
+With an optional argument of
+.BR fatal ,
+lint warnings become fatal errors.
+This may be drastic, but its use will certainly encourage the
+development of cleaner \*(AK programs.
+With an optional argument of
+.BR invalid ,
+only warnings about things that are
+actually invalid are issued. (This is not fully implemented yet.)
+.TP
+.PD 0
+.B "\-W lint\-old"
+.TP
+.PD
+.B \-\^\-lint\-old
+Provide warnings about constructs that are
+not portable to the original version of Unix
+.IR awk .
+.TP
+.PD 0
+.B "\-W non\-decimal\-data"
+.TP
+.PD
+.B "\-\^\-non\-decimal\-data"
+Recognize octal and hexadecimal values in input data.
+.I "Use this option with great caution!"
+.ig
+.\" This option is left undocumented, on purpose.
+.TP
+.PD 0
+.B "\-W nostalgia"
+.TP
+.PD
+.B \-\^\-nostalgia
+Provide a moment of nostalgia for long time
+.I awk
+users.
+..
+.TP
+.PD 0
+.B "\-W posix"
+.TP
+.PD
+.B \-\^\-posix
+This turns on
+.I compatibility
+mode, with the following additional restrictions:
+.RS
+.TP "\w'\(bu'u+1n"
+\(bu
+.B \ex
+escape sequences are not recognized.
+.TP
+\(bu
+Only space and tab act as field separators when
+.B FS
+is set to a single space, newline does not.
+.TP
+\(bu
+You cannot continue lines after
+.B ?
+and
+.BR : .
+.TP
+\(bu
+The synonym
+.B func
+for the keyword
+.B function
+is not recognized.
+.TP
+\(bu
+The operators
+.B **
+and
+.B **=
+cannot be used in place of
+.B ^
+and
+.BR ^= .
+.TP
+\(bu
+The
+.B fflush()
+function is not available.
+.RE
+.TP
+.PD 0
+\fB\-W profile\fR[\fB=\fIprof_file\fR]
+.TP
+.PD
+\fB\-\^\-profile\fR[\fB=\fIprof_file\fR]
+Send profiling data to
+.IR prof_file .
+The default is
+.BR awkprof.out .
+When run with
+.IR gawk ,
+the profile is just a \*(lqpretty printed\*(rq version of the program.
+When run with
+.IR pgawk ,
+the profile contains execution counts of each statement in the program
+in the left margin and function call counts for each user-defined function.
+.TP
+.PD 0
+.B "\-W re\-interval"
+.TP
+.PD
+.B \-\^\-re\-interval
+Enable the use of
+.I "interval expressions"
+in regular expression matching
+(see
+.BR "Regular Expressions" ,
+below).
+Interval expressions were not traditionally available in the
+\*(AK language. The \*(PX standard added them, to make
+.I awk
+and
+.I egrep
+consistent with each other.
+However, their use is likely
+to break old \*(AK programs, so
+.I gawk
+only provides them if they are requested with this option, or when
+.B \-\^\-posix
+is specified.
+.TP
+.PD 0
+.BI "\-W source " program-text
+.TP
+.PD
+.BI \-\^\-source " program-text"
+Use
+.I program-text
+as \*(AK program source code.
+This option allows the easy intermixing of library functions (used via the
+.B \-f
+and
+.B \-\^\-file
+options) with source code entered on the command line.
+It is intended primarily for medium to large \*(AK programs used
+in shell scripts.
+.TP
+.PD 0
+.B "\-W version"
+.TP
+.PD
+.B \-\^\-version
+Print version information for this particular copy of
+.I gawk
+on the standard output.
+This is useful mainly for knowing if the current copy of
+.I gawk
+on your system
+is up to date with respect to whatever the Free Software Foundation
+is distributing.
+This is also useful when reporting bugs.
+(Per the
+.IR "GNU Coding Standards" ,
+these options cause an immediate, successful exit.)
+.TP
+.PD 0
+.B \-\^\-
+Signal the end of options. This is useful to allow further arguments to the
+\*(AK program itself to start with a \*(lq\-\*(rq.
+This is mainly for consistency with the argument parsing convention used
+by most other \*(PX programs.
+.PP
+In compatibility mode,
+any other options are flagged as invalid, but are otherwise ignored.
+In normal operation, as long as program text has been supplied, unknown
+options are passed on to the \*(AK program in the
+.B ARGV
+array for processing. This is particularly useful for running \*(AK
+programs via the \*(lq#!\*(rq executable interpreter mechanism.
+.SH AWK PROGRAM EXECUTION
+.PP
+An \*(AK program consists of a sequence of pattern-action statements
+and optional function definitions.
+.RS
+.PP
+\fIpattern\fB { \fIaction statements\fB }\fR
+.br
+\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements\fB }\fR
+.RE
+.PP
+.I Gawk
+first reads the program source from the
+.IR program-file (s)
+if specified,
+from arguments to
+.BR \-\^\-source ,
+or from the first non-option argument on the command line.
+The
+.B \-f
+and
+.B \-\^\-source
+options may be used multiple times on the command line.
+.I Gawk
+reads the program text as if all the
+.IR program-file s
+and command line source texts
+had been concatenated together. This is useful for building libraries
+of \*(AK functions, without having to include them in each new \*(AK
+program that uses them. It also provides the ability to mix library
+functions with command line programs.
+.PP
+The environment variable
+.B AWKPATH
+specifies a search path to use when finding source files named with
+the
+.B \-f
+option. If this variable does not exist, the default path is
+\fB".:/usr/local/share/awk"\fR.
+(The actual directory may vary, depending upon how
+.I gawk
+was built and installed.)
+If a file name given to the
+.B \-f
+option contains a \*(lq/\*(rq character, no path search is performed.
+.PP
+.I Gawk
+executes \*(AK programs in the following order.
+First,
+all variable assignments specified via the
+.B \-v
+option are performed.
+Next,
+.I gawk
+compiles the program into an internal form.
+Then,
+.I gawk
+executes the code in the
+.B BEGIN
+block(s) (if any),
+and then proceeds to read
+each file named in the
+.B ARGV
+array.
+If there are no files named on the command line,
+.I gawk
+reads the standard input.
+.PP
+If a filename on the command line has the form
+.IB var = val
+it is treated as a variable assignment. The variable
+.I var
+will be assigned the value
+.IR val .
+(This happens after any
+.B BEGIN
+block(s) have been run.)
+Command line variable assignment
+is most useful for dynamically assigning values to the variables
+\*(AK uses to control how input is broken into fields and records.
+It is also useful for controlling state if multiple passes are needed over
+a single data file.
+.PP
+If the value of a particular element of
+.B ARGV
+is empty (\fB""\fR),
+.I gawk
+skips over it.
+.PP
+For each record in the input,
+.I gawk
+tests to see if it matches any
+.I pattern
+in the \*(AK program.
+For each pattern that the record matches, the associated
+.I action
+is executed.
+The patterns are tested in the order they occur in the program.
+.PP
+Finally, after all the input is exhausted,
+.I gawk
+executes the code in the
+.B END
+block(s) (if any).
+.SH VARIABLES, RECORDS AND FIELDS
+\*(AK variables are dynamic; they come into existence when they are
+first used. Their values are either floating-point numbers or strings,
+or both,
+depending upon how they are used. \*(AK also has one dimensional
+arrays; arrays with multiple dimensions may be simulated.
+Several pre-defined variables are set as a program
+runs; these will be described as needed and summarized below.
+.SS Records
+Normally, records are separated by newline characters. You can control how
+records are separated by assigning values to the built-in variable
+.BR RS .
+If
+.B RS
+is any single character, that character separates records.
+Otherwise,
+.B RS
+is a regular expression. Text in the input that matches this
+regular expression separates the record.
+However, in compatibility mode,
+only the first character of its string
+value is used for separating records.
+If
+.B RS
+is set to the null string, then records are separated by
+blank lines.
+When
+.B RS
+is set to the null string, the newline character always acts as
+a field separator, in addition to whatever value
+.B FS
+may have.
+.SS Fields
+.PP
+As each input record is read,
+.I gawk
+splits the record into
+.IR fields ,
+using the value of the
+.B FS
+variable as the field separator.
+If
+.B FS
+is a single character, fields are separated by that character.
+If
+.B FS
+is the null string, then each individual character becomes a
+separate field.
+Otherwise,
+.B FS
+is expected to be a full regular expression.
+In the special case that
+.B FS
+is a single space, fields are separated
+by runs of spaces and/or tabs and/or newlines.
+(But see the discussion of
+.BR \-\^\-posix ,
+below).
+.B NOTE:
+The value of
+.B IGNORECASE
+(see below) also affects how fields are split when
+.B FS
+is a regular expression, and how records are separated when
+.B RS
+is a regular expression.
+.PP
+If the
+.B FIELDWIDTHS
+variable is set to a space separated list of numbers, each field is
+expected to have fixed width, and
+.I gawk
+splits up the record using the specified widths. The value of
+.B FS
+is ignored.
+Assigning a new value to
+.B FS
+overrides the use of
+.BR FIELDWIDTHS ,
+and restores the default behavior.
+.PP
+Each field in the input record may be referenced by its position,
+.BR $1 ,
+.BR $2 ,
+and so on.
+.B $0
+is the whole record.
+Fields need not be referenced by constants:
+.RS
+.PP
+.ft B
+n = 5
+.br
+print $n
+.ft R
+.RE
+.PP
+prints the fifth field in the input record.
+.PP
+The variable
+.B NF
+is set to the total number of fields in the input record.
+.PP
+References to non-existent fields (i.e. fields after
+.BR $NF )
+produce the null-string. However, assigning to a non-existent field
+(e.g.,
+.BR "$(NF+2) = 5" )
+increases the value of
+.BR NF ,
+creates any intervening fields with the null string as their value, and
+causes the value of
+.B $0
+to be recomputed, with the fields being separated by the value of
+.BR OFS .
+References to negative numbered fields cause a fatal error.
+Decrementing
+.B NF
+causes the values of fields past the new value to be lost, and the value of
+.B $0
+to be recomputed, with the fields being separated by the value of
+.BR OFS .
+.PP
+Assigning a value to an existing field
+causes the whole record to be rebuilt when
+.B $0
+is referenced.
+Similarly, assigning a value to
+.B $0
+causes the record to be resplit, creating new
+values for the fields.
+.SS Built-in Variables
+.PP
+.IR Gawk\^ "'s"
+built-in variables are:
+.PP
+.TP "\w'\fBFIELDWIDTHS\fR'u+1n"
+.B ARGC
+The number of command line arguments (does not include options to
+.IR gawk ,
+or the program source).
+.TP
+.B ARGIND
+The index in
+.B ARGV
+of the current file being processed.
+.TP
+.B ARGV
+Array of command line arguments. The array is indexed from
+0 to
+.B ARGC
+\- 1.
+Dynamically changing the contents of
+.B ARGV
+can control the files used for data.
+.TP
+.B BINMODE
+On non-POSIX systems, specifies use of \*(lqbinary\*(rq mode for all file I/O.
+Numeric values of 1, 2, or 3, specify that input files, output files, or
+all files, respectively, should use binary I/O.
+String values of \fB"r"\fR, or \fB"w"\fR specify that input files, or output files,
+respectively, should use binary I/O.
+String values of \fB"rw"\fR or \fB"wr"\fR specify that all files
+should use binary I/O.
+Any other string value is treated as \fB"rw"\fR, but generates a warning message.
+.TP
+.B CONVFMT
+The conversion format for numbers, \fB"%.6g"\fR, by default.
+.TP
+.B ENVIRON
+An array containing the values of the current environment.
+The array is indexed by the environment variables, each element being
+the value of that variable (e.g., \fBENVIRON["HOME"]\fP might be
+.BR /home/arnold ).
+Changing this array does not affect the environment seen by programs which
+.I gawk
+spawns via redirection or the
+.B system()
+function.
+.TP
+.B ERRNO
+If a system error occurs either doing a redirection for
+.BR getline ,
+during a read for
+.BR getline ,
+or during a
+.BR close() ,
+then
+.B ERRNO
+will contain
+a string describing the error.
+The value is subject to translation in non-English locales.
+.TP
+.B FIELDWIDTHS
+A white-space separated list of fieldwidths. When set,
+.I gawk
+parses the input into fields of fixed width, instead of using the
+value of the
+.B FS
+variable as the field separator.
+.TP
+.B FILENAME
+The name of the current input file.
+If no files are specified on the command line, the value of
+.B FILENAME
+is \*(lq\-\*(rq.
+However,
+.B FILENAME
+is undefined inside the
+.B BEGIN
+block
+(unless set by
+.BR getline ).
+.TP
+.B FNR
+The input record number in the current input file.
+.TP
+.B FS
+The input field separator, a space by default. See
+.BR Fields ,
+above.
+.TP
+.B IGNORECASE
+Controls the case-sensitivity of all regular expression
+and string operations. If
+.B IGNORECASE
+has a non-zero value, then string comparisons and
+pattern matching in rules,
+field splitting with
+.BR FS ,
+record separating with
+.BR RS ,
+regular expression
+matching with
+.B ~
+and
+.BR !~ ,
+and the
+.BR gensub() ,
+.BR gsub() ,
+.BR index() ,
+.BR match() ,
+.BR split() ,
+and
+.B sub()
+built-in functions all ignore case when doing regular expression
+operations.
+.B NOTE:
+Array subscripting is
+.I not
+affected.
+However, the
+.B asort()
+and
+.B asorti()
+functions are affected.
+.sp .5
+Thus, if
+.B IGNORECASE
+is not equal to zero,
+.B /aB/
+matches all of the strings \fB"ab"\fP, \fB"aB"\fP, \fB"Ab"\fP,
+and \fB"AB"\fP.
+As with all \*(AK variables, the initial value of
+.B IGNORECASE
+is zero, so all regular expression and string
+operations are normally case-sensitive.
+Under Unix, the full ISO 8859-1 Latin-1 character set is used
+when ignoring case.
+As of
+.I gawk
+3.1.4, the case equivalencies are fully locale-aware, based on
+the C
+.B <ctype.h>
+facilities such as
+.BR isalpha() ,
+and
+.BR tolupper() .
+.TP
+.B LINT
+Provides dynamic control of the
+.B \-\^\-lint
+option from within an \*(AK program.
+When true,
+.I gawk
+prints lint warnings. When false, it does not.
+When assigned the string value \fB"fatal"\fP,
+lint warnings become fatal errors, exactly like
+.BR \-\^\-lint=fatal .
+Any other true value just prints warnings.
+.TP
+.B NF
+The number of fields in the current input record.
+.TP
+.B NR
+The total number of input records seen so far.
+.TP
+.B OFMT
+The output format for numbers, \fB"%.6g"\fR, by default.
+.TP
+.B OFS
+The output field separator, a space by default.
+.TP
+.B ORS
+The output record separator, by default a newline.
+.TP
+.B PROCINFO
+The elements of this array provide access to information about the
+running \*(AK program.
+On some systems,
+there may be elements in the array, \fB"group1"\fP through
+\fB"group\fIn\fB"\fR for some
+.IR n ,
+which is the number of supplementary groups that the process has.
+Use the
+.B in
+operator to test for these elements.
+The following elements are guaranteed to be available:
+.RS
+.TP \w'\fBPROCINFO["pgrpid"]\fR'u+1n
+\fBPROCINFO["egid"]\fP
+the value of the
+.IR getegid (2)
+system call.
+.TP
+\fBPROCINFO["euid"]\fP
+the value of the
+.IR geteuid (2)
+system call.
+.TP
+\fBPROCINFO["FS"]\fP
+\fB"FS"\fP if field splitting with
+.B FS
+is in effect, or \fB"FIELDWIDTHS"\fP if field splitting with
+.B FIELDWIDTHS
+is in effect.
+.TP
+\fBPROCINFO["gid"]\fP
+the value of the
+.IR getgid (2)
+system call.
+.TP
+\fBPROCINFO["pgrpid"]\fP
+the process group ID of the current process.
+.TP
+\fBPROCINFO["pid"]\fP
+the process ID of the current process.
+.TP
+\fBPROCINFO["ppid"]\fP
+the parent process ID of the current process.
+.TP
+\fBPROCINFO["uid"]\fP
+the value of the
+.IR getuid (2)
+system call.
+.TP
+\fBPROCINFO["version"]\fP
+The version of
+.IR gawk .
+This is available from
+version 3.1.4 and later.
+.RE
+.TP
+.B RS
+The input record separator, by default a newline.
+.TP
+.B RT
+The record terminator.
+.I Gawk
+sets
+.B RT
+to the input text that matched the character or regular expression
+specified by
+.BR RS .
+.TP
+.B RSTART
+The index of the first character matched by
+.BR match() ;
+0 if no match.
+(This implies that character indices start at one.)
+.TP
+.B RLENGTH
+The length of the string matched by
+.BR match() ;
+\-1 if no match.
+.TP
+.B SUBSEP
+The character used to separate multiple subscripts in array
+elements, by default \fB"\e034"\fR.
+.TP
+.B TEXTDOMAIN
+The text domain of the \*(AK program; used to find the localized
+translations for the program's strings.
+.SS Arrays
+.PP
+Arrays are subscripted with an expression between square brackets
+.RB ( [ " and " ] ).
+If the expression is an expression list
+.RI ( expr ", " expr " .\|.\|.)"
+then the array subscript is a string consisting of the
+concatenation of the (string) value of each expression,
+separated by the value of the
+.B SUBSEP
+variable.
+This facility is used to simulate multiply dimensioned
+arrays. For example:
+.PP
+.RS
+.ft B
+i = "A";\^ j = "B";\^ k = "C"
+.br
+x[i, j, k] = "hello, world\en"
+.ft R
+.RE
+.PP
+assigns the string \fB"hello, world\en"\fR to the element of the array
+.B x
+which is indexed by the string \fB"A\e034B\e034C"\fR. All arrays in \*(AK
+are associative, i.e. indexed by string values.
+.PP
+The special operator
+.B in
+may be used in an
+.B if
+or
+.B while
+statement to see if an array has an index consisting of a particular
+value.
+.PP
+.RS
+.ft B
+.nf
+if (val in array)
+ print array[val]
+.fi
+.ft
+.RE
+.PP
+If the array has multiple subscripts, use
+.BR "(i, j) in array" .
+.PP
+The
+.B in
+construct may also be used in a
+.B for
+loop to iterate over all the elements of an array.
+.PP
+An element may be deleted from an array using the
+.B delete
+statement.
+The
+.B delete
+statement may also be used to delete the entire contents of an array,
+just by specifying the array name without a subscript.
+.SS Variable Typing And Conversion
+.PP
+Variables and fields
+may be (floating point) numbers, or strings, or both. How the
+value of a variable is interpreted depends upon its context. If used in
+a numeric expression, it will be treated as a number, if used as a string
+it will be treated as a string.
+.PP
+To force a variable to be treated as a number, add 0 to it; to force it
+to be treated as a string, concatenate it with the null string.
+.PP
+When a string must be converted to a number, the conversion is accomplished
+using
+.IR strtod (3).
+A number is converted to a string by using the value of
+.B CONVFMT
+as a format string for
+.IR sprintf (3),
+with the numeric value of the variable as the argument.
+However, even though all numbers in \*(AK are floating-point,
+integral values are
+.I always
+converted as integers. Thus, given
+.PP
+.RS
+.ft B
+.nf
+CONVFMT = "%2.2f"
+a = 12
+b = a ""
+.fi
+.ft R
+.RE
+.PP
+the variable
+.B b
+has a string value of \fB"12"\fR and not \fB"12.00"\fR.
+.PP
+.I Gawk
+performs comparisons as follows:
+If two variables are numeric, they are compared numerically.
+If one value is numeric and the other has a string value that is a
+\*(lqnumeric string,\*(rq then comparisons are also done numerically.
+Otherwise, the numeric value is converted to a string and a string
+comparison is performed.
+Two strings are compared, of course, as strings.
+Note that the POSIX standard applies the concept of
+\*(lqnumeric string\*(rq everywhere, even to string constants.
+However, this is
+clearly incorrect, and
+.I gawk
+does not do this.
+(Fortunately, this is fixed in the next version of the standard.)
+.PP
+Note that string constants, such as \fB"57"\fP, are
+.I not
+numeric strings, they are string constants.
+The idea of \*(lqnumeric string\*(rq
+only applies to fields,
+.B getline
+input,
+.BR FILENAME ,
+.B ARGV
+elements,
+.B ENVIRON
+elements and the elements of an array created by
+.B split()
+that are numeric strings.
+The basic idea is that
+.IR "user input" ,
+and only user input, that looks numeric,
+should be treated that way.
+.PP
+Uninitialized variables have the numeric value 0 and the string value ""
+(the null, or empty, string).
+.SS Octal and Hexadecimal Constants
+Starting with version 3.1 of
+.I gawk ,
+you may use C-style octal and hexadecimal constants in your AWK
+program source code.
+For example, the octal value
+.B 011
+is equal to decimal
+.BR 9 ,
+and the hexadecimal value
+.B 0x11
+is equal to decimal 17.
+.SS String Constants
+.PP
+String constants in \*(AK are sequences of characters enclosed
+between double quotes (\fB"\fR). Within strings, certain
+.I "escape sequences"
+are recognized, as in C. These are:
+.PP
+.TP "\w'\fB\e\^\fIddd\fR'u+1n"
+.B \e\e
+A literal backslash.
+.TP
+.B \ea
+The \*(lqalert\*(rq character; usually the \s-1ASCII\s+1 \s-1BEL\s+1 character.
+.TP
+.B \eb
+backspace.
+.TP
+.B \ef
+form-feed.
+.TP
+.B \en
+newline.
+.TP
+.B \er
+carriage return.
+.TP
+.B \et
+horizontal tab.
+.TP
+.B \ev
+vertical tab.
+.TP
+.BI \ex "\^hex digits"
+The character represented by the string of hexadecimal digits following
+the
+.BR \ex .
+As in \*(AN C, all following hexadecimal digits are considered part of
+the escape sequence.
+(This feature should tell us something about language design by committee.)
+E.g., \fB"\ex1B"\fR is the \s-1ASCII\s+1 \s-1ESC\s+1 (escape) character.
+.TP
+.BI \e ddd
+The character represented by the 1-, 2-, or 3-digit sequence of octal
+digits.
+E.g., \fB"\e033"\fR is the \s-1ASCII\s+1 \s-1ESC\s+1 (escape) character.
+.TP
+.BI \e c
+The literal character
+.IR c\^ .
+.PP
+The escape sequences may also be used inside constant regular expressions
+(e.g.,
+.B "/[\ \et\ef\en\er\ev]/"
+matches whitespace characters).
+.PP
+In compatibility mode, the characters represented by octal and
+hexadecimal escape sequences are treated literally when used in
+regular expression constants. Thus,
+.B /a\e52b/
+is equivalent to
+.BR /a\e*b/ .
+.SH PATTERNS AND ACTIONS
+\*(AK is a line-oriented language. The pattern comes first, and then the
+action. Action statements are enclosed in
+.B {
+and
+.BR } .
+Either the pattern may be missing, or the action may be missing, but,
+of course, not both. If the pattern is missing, the action is
+executed for every single record of input.
+A missing action is equivalent to
+.RS
+.PP
+.B "{ print }"
+.RE
+.PP
+which prints the entire record.
+.PP
+Comments begin with the \*(lq#\*(rq character, and continue until the
+end of the line.
+Blank lines may be used to separate statements.
+Normally, a statement ends with a newline, however, this is not the
+case for lines ending in
+a \*(lq,\*(rq,
+.BR { ,
+.BR ? ,
+.BR : ,
+.BR && ,
+or
+.BR || .
+Lines ending in
+.B do
+or
+.B else
+also have their statements automatically continued on the following line.
+In other cases, a line can be continued by ending it with a \*(lq\e\*(rq,
+in which case the newline will be ignored.
+.PP
+Multiple statements may
+be put on one line by separating them with a \*(lq;\*(rq.
+This applies to both the statements within the action part of a
+pattern-action pair (the usual case),
+and to the pattern-action statements themselves.
+.SS Patterns
+\*(AK patterns may be one of the following:
+.PP
+.RS
+.nf
+.B BEGIN
+.B END
+.BI / "regular expression" /
+.I "relational expression"
+.IB pattern " && " pattern
+.IB pattern " || " pattern
+.IB pattern " ? " pattern " : " pattern
+.BI ( pattern )
+.BI ! " pattern"
+.IB pattern1 ", " pattern2
+.fi
+.RE
+.PP
+.B BEGIN
+and
+.B END
+are two special kinds of patterns which are not tested against
+the input.
+The action parts of all
+.B BEGIN
+patterns are merged as if all the statements had
+been written in a single
+.B BEGIN
+block. They are executed before any
+of the input is read. Similarly, all the
+.B END
+blocks are merged,
+and executed when all the input is exhausted (or when an
+.B exit
+statement is executed).
+.B BEGIN
+and
+.B END
+patterns cannot be combined with other patterns in pattern expressions.
+.B BEGIN
+and
+.B END
+patterns cannot have missing action parts.
+.PP
+For
+.BI / "regular expression" /
+patterns, the associated statement is executed for each input record that matches
+the regular expression.
+Regular expressions are the same as those in
+.IR egrep (1),
+and are summarized below.
+.PP
+A
+.I "relational expression"
+may use any of the operators defined below in the section on actions.
+These generally test whether certain fields match certain regular expressions.
+.PP
+The
+.BR && ,
+.BR || ,
+and
+.B !
+operators are logical AND, logical OR, and logical NOT, respectively, as in C.
+They do short-circuit evaluation, also as in C, and are used for combining
+more primitive pattern expressions. As in most languages, parentheses
+may be used to change the order of evaluation.
+.PP
+The
+.B ?\^:
+operator is like the same operator in C. If the first pattern is true
+then the pattern used for testing is the second pattern, otherwise it is
+the third. Only one of the second and third patterns is evaluated.
+.PP
+The
+.IB pattern1 ", " pattern2
+form of an expression is called a
+.IR "range pattern" .
+It matches all input records starting with a record that matches
+.IR pattern1 ,
+and continuing until a record that matches
+.IR pattern2 ,
+inclusive. It does not combine with any other sort of pattern expression.
+.SS Regular Expressions
+Regular expressions are the extended kind found in
+.IR egrep .
+They are composed of characters as follows:
+.TP "\w'\fB[^\fIabc.\|.\|.\fB]\fR'u+2n"
+.I c
+matches the non-metacharacter
+.IR c .
+.TP
+.I \ec
+matches the literal character
+.IR c .
+.TP
+.B .
+matches any character
+.I including
+newline.
+.TP
+.B ^
+matches the beginning of a string.
+.TP
+.B $
+matches the end of a string.
+.TP
+.BI [ abc.\|.\|. ]
+character list, matches any of the characters
+.IR abc.\|.\|. .
+.TP
+.BI [^ abc.\|.\|. ]
+negated character list, matches any character except
+.IR abc.\|.\|. .
+.TP
+.IB r1 | r2
+alternation: matches either
+.I r1
+or
+.IR r2 .
+.TP
+.I r1r2
+concatenation: matches
+.IR r1 ,
+and then
+.IR r2 .
+.TP
+.IB r\^ +
+matches one or more
+.IR r\^ "'s."
+.TP
+.IB r *
+matches zero or more
+.IR r\^ "'s."
+.TP
+.IB r\^ ?
+matches zero or one
+.IR r\^ "'s."
+.TP
+.BI ( r )
+grouping: matches
+.IR r .
+.TP
+.PD 0
+.IB r { n }
+.TP
+.PD 0
+.IB r { n ,}
+.TP
+.PD
+.IB r { n , m }
+One or two numbers inside braces denote an
+.IR "interval expression" .
+If there is one number in the braces, the preceding regular expression
+.I r
+is repeated
+.I n
+times. If there are two numbers separated by a comma,
+.I r
+is repeated
+.I n
+to
+.I m
+times.
+If there is one number followed by a comma, then
+.I r
+is repeated at least
+.I n
+times.
+.sp .5
+Interval expressions are only available if either
+.B \-\^\-posix
+or
+.B \-\^\-re\-interval
+is specified on the command line.
+.TP
+.B \ey
+matches the empty string at either the beginning or the
+end of a word.
+.TP
+.B \eB
+matches the empty string within a word.
+.TP
+.B \e<
+matches the empty string at the beginning of a word.
+.TP
+.B \e>
+matches the empty string at the end of a word.
+.TP
+.B \ew
+matches any word-constituent character (letter, digit, or underscore).
+.TP
+.B \eW
+matches any character that is not word-constituent.
+.TP
+.B \e`
+matches the empty string at the beginning of a buffer (string).
+.TP
+.B \e'
+matches the empty string at the end of a buffer.
+.PP
+The escape sequences that are valid in string constants (see below)
+are also valid in regular expressions.
+.PP
+.I "Character classes"
+are a new feature introduced in the \*(PX standard.
+A character class is a special notation for describing
+lists of characters that have a specific attribute, but where the
+actual characters themselves can vary from country to country and/or
+from character set to character set. For example, the notion of what
+is an alphabetic character differs in the USA and in France.
+.PP
+A character class is only valid in a regular expression
+.I inside
+the brackets of a character list. Character classes consist of
+.BR [: ,
+a keyword denoting the class, and
+.BR :] .
+The character
+classes defined by the \*(PX standard are:
+.TP "\w'\fB[:alnum:]\fR'u+2n"
+.B [:alnum:]
+Alphanumeric characters.
+.TP
+.B [:alpha:]
+Alphabetic characters.
+.TP
+.B [:blank:]
+Space or tab characters.
+.TP
+.B [:cntrl:]
+Control characters.
+.TP
+.B [:digit:]
+Numeric characters.
+.TP
+.B [:graph:]
+Characters that are both printable and visible.
+(A space is printable, but not visible, while an
+.B a
+is both.)
+.TP
+.B [:lower:]
+Lower-case alphabetic characters.
+.TP
+.B [:print:]
+Printable characters (characters that are not control characters.)
+.TP
+.B [:punct:]
+Punctuation characters (characters that are not letter, digits,
+control characters, or space characters).
+.TP
+.B [:space:]
+Space characters (such as space, tab, and formfeed, to name a few).
+.TP
+.B [:upper:]
+Upper-case alphabetic characters.
+.TP
+.B [:xdigit:]
+Characters that are hexadecimal digits.
+.PP
+For example, before the \*(PX standard, to match alphanumeric
+characters, you would have had to write
+.BR /[A\-Za\-z0\-9]/ .
+If your character set had other alphabetic characters in it, this would not
+match them, and if your character set collated differently from
+\s-1ASCII\s+1, this might not even match the
+\s-1ASCII\s+1 alphanumeric characters.
+With the \*(PX character classes, you can write
+.BR /[[:alnum:]]/ ,
+and this matches
+the alphabetic and numeric characters in your character set.
+.PP
+Two additional special sequences can appear in character lists.
+These apply to non-\s-1ASCII\s+1 character sets, which can have single symbols
+(called
+.IR "collating elements" )
+that are represented with more than one
+character, as well as several characters that are equivalent for
+.IR collating ,
+or sorting, purposes. (E.g., in French, a plain \*(lqe\*(rq
+and a grave-accented e\` are equivalent.)
+.TP
+Collating Symbols
+A collating symbol is a multi-character collating element enclosed in
+.B [.
+and
+.BR .] .
+For example, if
+.B ch
+is a collating element, then
+.B [[.ch.]]
+is a regular expression that matches this collating element, while
+.B [ch]
+is a regular expression that matches either
+.B c
+or
+.BR h .
+.TP
+Equivalence Classes
+An equivalence class is a locale-specific name for a list of
+characters that are equivalent. The name is enclosed in
+.B [=
+and
+.BR =] .
+For example, the name
+.B e
+might be used to represent all of
+\*(lqe,\*(rq \*(lqe\h'-\w:e:u'\',\*(rq and \*(lqe\h'-\w:e:u'\`.\*(rq
+In this case,
+.B [[=e=]]
+is a regular expression
+that matches any of
+.BR e ,
+.BR "e\h'-\w:e:u'\'" ,
+or
+.BR "e\h'-\w:e:u'\`" .
+.PP
+These features are very valuable in non-English speaking locales.
+The library functions that
+.I gawk
+uses for regular expression matching
+currently only recognize \*(PX character classes; they do not recognize
+collating symbols or equivalence classes.
+.PP
+The
+.BR \ey ,
+.BR \eB ,
+.BR \e< ,
+.BR \e> ,
+.BR \ew ,
+.BR \eW ,
+.BR \e` ,
+and
+.B \e'
+operators are specific to
+.IR gawk ;
+they are extensions based on facilities in the \*(GN regular expression libraries.
+.PP
+The various command line options
+control how
+.I gawk
+interprets characters in regular expressions.
+.TP
+No options
+In the default case,
+.I gawk
+provide all the facilities of
+\*(PX regular expressions and the \*(GN regular expression operators described above.
+However, interval expressions are not supported.
+.TP
+.B \-\^\-posix
+Only \*(PX regular expressions are supported, the \*(GN operators are not special.
+(E.g.,
+.B \ew
+matches a literal
+.BR w ).
+Interval expressions are allowed.
+.TP
+.B \-\^\-traditional
+Traditional Unix
+.I awk
+regular expressions are matched. The \*(GN operators
+are not special, interval expressions are not available, and neither
+are the \*(PX character classes
+.RB ( [[:alnum:]]
+and so on).
+Characters described by octal and hexadecimal escape sequences are
+treated literally, even if they represent regular expression metacharacters.
+.TP
+.B \-\^\-re\-interval
+Allow interval expressions in regular expressions, even if
+.B \-\^\-traditional
+has been provided.
+.SS Actions
+Action statements are enclosed in braces,
+.B {
+and
+.BR } .
+Action statements consist of the usual assignment, conditional, and looping
+statements found in most languages. The operators, control statements,
+and input/output statements
+available are patterned after those in C.
+.SS Operators
+.PP
+The operators in \*(AK, in order of decreasing precedence, are
+.PP
+.TP "\w'\fB*= /= %= ^=\fR'u+1n"
+.BR ( \&.\|.\|. )
+Grouping
+.TP
+.B $
+Field reference.
+.TP
+.B "++ \-\^\-"
+Increment and decrement, both prefix and postfix.
+.TP
+.B ^
+Exponentiation (\fB**\fR may also be used, and \fB**=\fR for
+the assignment operator).
+.TP
+.B "+ \- !"
+Unary plus, unary minus, and logical negation.
+.TP
+.B "* / %"
+Multiplication, division, and modulus.
+.TP
+.B "+ \-"
+Addition and subtraction.
+.TP
+.I space
+String concatenation.
+.TP
+.PD 0
+.B "< >"
+.TP
+.PD 0
+.B "<= >="
+.TP
+.PD
+.B "!= =="
+The regular relational operators.
+.TP
+.B "~ !~"
+Regular expression match, negated match.
+.B NOTE:
+Do not use a constant regular expression
+.RB ( /foo/ )
+on the left-hand side of a
+.B ~
+or
+.BR !~ .
+Only use one on the right-hand side. The expression
+.BI "/foo/ ~ " exp
+has the same meaning as \fB(($0 ~ /foo/) ~ \fIexp\fB)\fR.
+This is usually
+.I not
+what was intended.
+.TP
+.B in
+Array membership.
+.TP
+.B &&
+Logical AND.
+.TP
+.B ||
+Logical OR.
+.TP
+.B ?:
+The C conditional expression. This has the form
+.IB expr1 " ? " expr2 " : " expr3\c
+\&.
+If
+.I expr1
+is true, the value of the expression is
+.IR expr2 ,
+otherwise it is
+.IR expr3 .
+Only one of
+.I expr2
+and
+.I expr3
+is evaluated.
+.TP
+.PD 0
+.B "= += \-="
+.TP
+.PD
+.B "*= /= %= ^="
+Assignment. Both absolute assignment
+.BI ( var " = " value )
+and operator-assignment (the other forms) are supported.
+.SS Control Statements
+.PP
+The control statements are
+as follows:
+.PP
+.RS
+.nf
+\fBif (\fIcondition\fB) \fIstatement\fR [ \fBelse\fI statement \fR]
+\fBwhile (\fIcondition\fB) \fIstatement \fR
+\fBdo \fIstatement \fBwhile (\fIcondition\fB)\fR
+\fBfor (\fIexpr1\fB; \fIexpr2\fB; \fIexpr3\fB) \fIstatement\fR
+\fBfor (\fIvar \fBin\fI array\fB) \fIstatement\fR
+\fBbreak\fR
+\fBcontinue\fR
+\fBdelete \fIarray\^\fB[\^\fIindex\^\fB]\fR
+\fBdelete \fIarray\^\fR
+\fBexit\fR [ \fIexpression\fR ]
+\fB{ \fIstatements \fB}\fR
+.fi
+.RE
+.SS "I/O Statements"
+.PP
+The input/output statements are as follows:
+.PP
+.TP "\w'\fBprintf \fIfmt, expr-list\fR'u+1n"
+\fBclose(\fIfile \fR[\fB, \fIhow\fR]\fB)\fR
+Close file, pipe or co-process.
+The optional
+.I how
+should only be used when closing one end of a
+two-way pipe to a co-process.
+It must be a string value, either
+\fB"to"\fR or \fB"from"\fR.
+.TP
+.B getline
+Set
+.B $0
+from next input record; set
+.BR NF ,
+.BR NR ,
+.BR FNR .
+.TP
+.BI "getline <" file
+Set
+.B $0
+from next record of
+.IR file ;
+set
+.BR NF .
+.TP
+.BI getline " var"
+Set
+.I var
+from next input record; set
+.BR NR ,
+.BR FNR .
+.TP
+.BI getline " var" " <" file
+Set
+.I var
+from next record of
+.IR file .
+.TP
+\fIcommand\fB | getline \fR[\fIvar\fR]
+Run
+.I command
+piping the output either into
+.B $0
+or
+.IR var ,
+as above.
+.TP
+\fIcommand\fB |& getline \fR[\fIvar\fR]
+Run
+.I command
+as a co-process
+piping the output either into
+.B $0
+or
+.IR var ,
+as above.
+Co-processes are a
+.I gawk
+extension.
+.TP
+.B next
+Stop processing the current input record. The next input record
+is read and processing starts over with the first pattern in the
+\*(AK program. If the end of the input data is reached, the
+.B END
+block(s), if any, are executed.
+.TP
+.B "nextfile"
+Stop processing the current input file. The next input record read
+comes from the next input file.
+.B FILENAME
+and
+.B ARGIND
+are updated,
+.B FNR
+is reset to 1, and processing starts over with the first pattern in the
+\*(AK program. If the end of the input data is reached, the
+.B END
+block(s), if any, are executed.
+.TP
+.B print
+Prints the current record.
+The output record is terminated with the value of the
+.B ORS
+variable.
+.TP
+.BI print " expr-list"
+Prints expressions.
+Each expression is separated by the value of the
+.B OFS
+variable.
+The output record is terminated with the value of the
+.B ORS
+variable.
+.TP
+.BI print " expr-list" " >" file
+Prints expressions on
+.IR file .
+Each expression is separated by the value of the
+.B OFS
+variable. The output record is terminated with the value of the
+.B ORS
+variable.
+.TP
+.BI printf " fmt, expr-list"
+Format and print.
+.TP
+.BI printf " fmt, expr-list" " >" file
+Format and print on
+.IR file .
+.TP
+.BI system( cmd-line )
+Execute the command
+.IR cmd-line ,
+and return the exit status.
+(This may not be available on non-\*(PX systems.)
+.TP
+\&\fBfflush(\fR[\fIfile\^\fR]\fB)\fR
+Flush any buffers associated with the open output file or pipe
+.IR file .
+If
+.I file
+is missing, then standard output is flushed.
+If
+.I file
+is the null string,
+then all open output files and pipes
+have their buffers flushed.
+.PP
+Additional output redirections are allowed for
+.B print
+and
+.BR printf .
+.TP
+.BI "print .\|.\|. >>" " file"
+appends output to the
+.IR file .
+.TP
+.BI "print .\|.\|. |" " command"
+writes on a pipe.
+.TP
+.BI "print .\|.\|. |&" " command"
+sends data to a co-process.
+.PP
+The
+.BR getline
+command returns 0 on end of file and \-1 on an error.
+Upon an error,
+.B ERRNO
+contains a string describing the problem.
+.PP
+.B NOTE:
+If using a pipe or co-process to
+.BR getline ,
+or from
+.B print
+or
+.B printf
+within a loop, you
+.I must
+use
+.B close()
+to create new instances of the command.
+\*(AK does not automatically close pipes or co-processes when
+they return EOF.
+.SS The \fIprintf\fP\^ Statement
+.PP
+The \*(AK versions of the
+.B printf
+statement and
+.B sprintf()
+function
+(see below)
+accept the following conversion specification formats:
+.TP "\w'\fB%g\fR, \fB%G\fR'u+2n"
+.B %c
+An \s-1ASCII\s+1 character.
+If the argument used for
+.B %c
+is numeric, it is treated as a character and printed.
+Otherwise, the argument is assumed to be a string, and the only first
+character of that string is printed.
+.TP
+.BR "%d" "," " %i"
+A decimal number (the integer part).
+.TP
+.B %e , " %E"
+A floating point number of the form
+.BR [\-]d.dddddde[+\^\-]dd .
+The
+.B %E
+format uses
+.B E
+instead of
+.BR e .
+.TP
+.B %f
+A floating point number of the form
+.BR [\-]ddd.dddddd .
+.TP
+.B %g , " %G"
+Use
+.B %e
+or
+.B %f
+conversion, whichever is shorter, with nonsignificant zeros suppressed.
+The
+.B %G
+format uses
+.B %E
+instead of
+.BR %e .
+.TP
+.B %o
+An unsigned octal number (also an integer).
+.TP
+.PD
+.B %u
+An unsigned decimal number (again, an integer).
+.TP
+.B %s
+A character string.
+.TP
+.B %x , " %X"
+An unsigned hexadecimal number (an integer).
+The
+.B %X
+format uses
+.B ABCDEF
+instead of
+.BR abcdef .
+.TP
+.B %%
+A single
+.B %
+character; no argument is converted.
+.PP
+.BR NOTE :
+When using the integer format-control letters for values that are
+outside the range of a C
+.B long
+integer,
+.I gawk
+switches to the
+.B %g
+format specifier. If
+.B \-\^\-lint
+is provided on the command line
+.I gawk
+warns about this. Other versions of
+.I awk
+may print invalid values or do something else entirely.
+.PP
+Optional, additional parameters may lie between the
+.B %
+and the control letter:
+.TP
+.IB count $
+Use the
+.IR count "'th"
+argument at this point in the formatting.
+This is called a
+.I "positional specifier"
+and
+is intended primarily for use in translated versions of
+format strings, not in the original text of an AWK program.
+It is a
+.I gawk
+extension.
+.TP
+.B \-
+The expression should be left-justified within its field.
+.TP
+.I space
+For numeric conversions, prefix positive values with a space, and
+negative values with a minus sign.
+.TP
+.B +
+The plus sign, used before the width modifier (see below),
+says to always supply a sign for numeric conversions, even if the data
+to be formatted is positive. The
+.B +
+overrides the space modifier.
+.TP
+.B #
+Use an \*(lqalternate form\*(rq for certain control letters.
+For
+.BR %o ,
+supply a leading zero.
+For
+.BR %x ,
+and
+.BR %X ,
+supply a leading
+.BR 0x
+or
+.BR 0X
+for
+a nonzero result.
+For
+.BR %e ,
+.BR %E ,
+and
+.BR %f ,
+the result always contains a
+decimal point.
+For
+.BR %g ,
+and
+.BR %G ,
+trailing zeros are not removed from the result.
+.TP
+.B 0
+A leading
+.B 0
+(zero) acts as a flag, that indicates output should be
+padded with zeroes instead of spaces.
+This applies even to non-numeric output formats.
+This flag only has an effect when the field width is wider than the
+value to be printed.
+.TP
+.I width
+The field should be padded to this width. The field is normally padded
+with spaces. If the
+.B 0
+flag has been used, it is padded with zeroes.
+.TP
+.BI \&. prec
+A number that specifies the precision to use when printing.
+For the
+.BR %e ,
+.BR %E ,
+and
+.BR %f
+formats, this specifies the
+number of digits you want printed to the right of the decimal point.
+For the
+.BR %g ,
+and
+.B %G
+formats, it specifies the maximum number
+of significant digits. For the
+.BR %d ,
+.BR %o ,
+.BR %i ,
+.BR %u ,
+.BR %x ,
+and
+.B %X
+formats, it specifies the minimum number of
+digits to print. For
+.BR %s ,
+it specifies the maximum number of
+characters from the string that should be printed.
+.PP
+The dynamic
+.I width
+and
+.I prec
+capabilities of the \*(AN C
+.B printf()
+routines are supported.
+A
+.B *
+in place of either the
+.B width
+or
+.B prec
+specifications causes their values to be taken from
+the argument list to
+.B printf
+or
+.BR sprintf() .
+To use a positional specifier with a dynamic width or precision,
+supply the
+.IB count $
+after the
+.B *
+in the format string.
+For example, \fB"%3$*2$.*1$s"\fP.
+.SS Special File Names
+.PP
+When doing I/O redirection from either
+.B print
+or
+.B printf
+into a file,
+or via
+.B getline
+from a file,
+.I gawk
+recognizes certain special filenames internally. These filenames
+allow access to open file descriptors inherited from
+.IR gawk\^ "'s"
+parent process (usually the shell).
+These file names may also be used on the command line to name data files.
+The filenames are:
+.TP "\w'\fB/dev/stdout\fR'u+1n"
+.B /dev/stdin
+The standard input.
+.TP
+.B /dev/stdout
+The standard output.
+.TP
+.B /dev/stderr
+The standard error output.
+.TP
+.BI /dev/fd/\^ n
+The file associated with the open file descriptor
+.IR n .
+.PP
+These are particularly useful for error messages. For example:
+.PP
+.RS
+.ft B
+print "You blew it!" > "/dev/stderr"
+.ft R
+.RE
+.PP
+whereas you would otherwise have to use
+.PP
+.RS
+.ft B
+print "You blew it!" | "cat 1>&2"
+.ft R
+.RE
+.PP
+The following special filenames may be used with the
+.B |&
+co-process operator for creating TCP/IP network connections.
+.TP "\w'\fB/inet/tcp/\fIlport\fB/\fIrhost\fB/\fIrport\fR'u+2n"
+.BI /inet/tcp/ lport / rhost / rport
+File for TCP/IP connection on local port
+.I lport
+to
+remote host
+.I rhost
+on remote port
+.IR rport .
+Use a port of
+.B 0
+to have the system pick a port.
+.TP
+.BI /inet/udp/ lport / rhost / rport
+Similar, but use UDP/IP instead of TCP/IP.
+.TP
+.BI /inet/raw/ lport / rhost / rport
+.\" Similar, but use raw IP sockets.
+Reserved for future use.
+.PP
+Other special filenames provide access to information about the running
+.I gawk
+process.
+.B "These filenames are now obsolete."
+Use the
+.B PROCINFO
+array to obtain the information they provide.
+The filenames are:
+.TP "\w'\fB/dev/stdout\fR'u+1n"
+.B /dev/pid
+Reading this file returns the process ID of the current process,
+in decimal, terminated with a newline.
+.TP
+.B /dev/ppid
+Reading this file returns the parent process ID of the current process,
+in decimal, terminated with a newline.
+.TP
+.B /dev/pgrpid
+Reading this file returns the process group ID of the current process,
+in decimal, terminated with a newline.
+.TP
+.B /dev/user
+Reading this file returns a single record terminated with a newline.
+The fields are separated with spaces.
+.B $1
+is the value of the
+.IR getuid (2)
+system call,
+.B $2
+is the value of the
+.IR geteuid (2)
+system call,
+.B $3
+is the value of the
+.IR getgid (2)
+system call, and
+.B $4
+is the value of the
+.IR getegid (2)
+system call.
+If there are any additional fields, they are the group IDs returned by
+.IR getgroups (2).
+Multiple groups may not be supported on all systems.
+.SS Numeric Functions
+.PP
+\*(AK has the following built-in arithmetic functions:
+.PP
+.TP "\w'\fBsrand(\fR[\fIexpr\^\fR]\fB)\fR'u+1n"
+.BI atan2( y , " x" )
+Returns the arctangent of
+.I y/x
+in radians.
+.TP
+.BI cos( expr )
+Returns the cosine of
+.IR expr ,
+which is in radians.
+.TP
+.BI exp( expr )
+The exponential function.
+.TP
+.BI int( expr )
+Truncates to integer.
+.TP
+.BI log( expr )
+The natural logarithm function.
+.TP
+.B rand()
+Returns a random number
+.IR N ,
+between 0 and 1,
+such that 0 \(<= \fIN\fP < 1.
+.TP
+.BI sin( expr )
+Returns the sine of
+.IR expr ,
+which is in radians.
+.TP
+.BI sqrt( expr )
+The square root function.
+.TP
+\&\fBsrand(\fR[\fIexpr\^\fR]\fB)\fR
+Uses
+.I expr
+as a new seed for the random number generator. If no
+.I expr
+is provided, the time of day is used.
+The return value is the previous seed for the random
+number generator.
+.SS String Functions
+.PP
+.I Gawk
+has the following built-in string functions:
+.PP
+.TP "\w'\fBsprintf(\^\fIfmt\fB\^, \fIexpr-list\^\fB)\fR'u+1n"
+\fBasort(\fIs \fR[\fB, \fId\fR]\fB)\fR
+Returns the number of elements in the source
+array
+.IR s .
+The contents of
+.I s
+are sorted using
+.IR gawk\^ "'s"
+normal rules for
+comparing values, and the indexes of the
+sorted values of
+.I s
+are replaced with sequential
+integers starting with 1. If the optional
+destination array
+.I d
+is specified, then
+.I s
+is first duplicated into
+.IR d ,
+and then
+.I d
+is sorted, leaving the indexes of the
+source array
+.I s
+unchanged.
+.TP "\w'\fBsprintf(\^\fIfmt\fB\^, \fIexpr-list\^\fB)\fR'u+1n"
+\fBasorti(\fIs \fR[\fB, \fId\fR]\fB)\fR
+Returns the number of elements in the source
+array
+.IR s .
+The behavior is the same as that of
+.BR asort() ,
+except that the array
+.I indices
+are used for sorting, not the array values.
+When done, the array is indexed numerically, and
+the values are those of the original indices.
+The original values are lost; thus provide
+a second array if you wish to preserve the original.
+.TP
+\fBgensub(\fIr\fB, \fIs\fB, \fIh \fR[\fB, \fIt\fR]\fB)\fR
+Search the target string
+.I t
+for matches of the regular expression
+.IR r .
+If
+.I h
+is a string beginning with
+.B g
+or
+.BR G ,
+then replace all matches of
+.I r
+with
+.IR s .
+Otherwise,
+.I h
+is a number indicating which match of
+.I r
+to replace.
+If
+.I t
+is not supplied,
+.B $0
+is used instead.
+Within the replacement text
+.IR s ,
+the sequence
+.BI \e n\fR,
+where
+.I n
+is a digit from 1 to 9, may be used to indicate just the text that
+matched the
+.IR n 'th
+parenthesized subexpression. The sequence
+.B \e0
+represents the entire matched text, as does the character
+.BR & .
+Unlike
+.B sub()
+and
+.BR gsub() ,
+the modified string is returned as the result of the function,
+and the original target string is
+.I not
+changed.
+.TP "\w'\fBsprintf(\^\fIfmt\fB\^, \fIexpr-list\^\fB)\fR'u+1n"
+\fBgsub(\fIr\fB, \fIs \fR[\fB, \fIt\fR]\fB)\fR
+For each substring matching the regular expression
+.I r
+in the string
+.IR t ,
+substitute the string
+.IR s ,
+and return the number of substitutions.
+If
+.I t
+is not supplied, use
+.BR $0 .
+An
+.B &
+in the replacement text is replaced with the text that was actually matched.
+Use
+.B \e&
+to get a literal
+.BR & .
+(This must be typed as \fB"\e\e&"\fP;
+see \*(EP
+for a fuller discussion of the rules for
+.BR &'s
+and backslashes in the replacement text of
+.BR sub() ,
+.BR gsub() ,
+and
+.BR gensub() .)
+.TP
+.BI index( s , " t" )
+Returns the index of the string
+.I t
+in the string
+.IR s ,
+or 0 if
+.I t
+is not present.
+(This implies that character indices start at one.)
+.TP
+\fBlength(\fR[\fIs\fR]\fB)
+Returns the length of the string
+.IR s ,
+or the length of
+.B $0
+if
+.I s
+is not supplied.
+Starting with version 3.1.5,
+as a non-standard extension, with an array argument,
+.B length()
+returns the number of elements in the array.
+.TP
+\fBmatch(\fIs\fB, \fIr \fR[\fB, \fIa\fR]\fB)\fR
+Returns the position in
+.I s
+where the regular expression
+.I r
+occurs, or 0 if
+.I r
+is not present, and sets the values of
+.B RSTART
+and
+.BR RLENGTH .
+Note that the argument order is the same as for the
+.B ~
+operator:
+.IB str " ~"
+.IR re .
+.ft R
+If array
+.I a
+is provided,
+.I a
+is cleared and then elements 1 through
+.I n
+are filled with the portions of
+.I s
+that match the corresponding parenthesized
+subexpression in
+.IR r .
+The 0'th element of
+.I a
+contains the portion
+of
+.I s
+matched by the entire regular expression
+.IR r .
+Subscripts
+\fBa[\fIn\^\fB, "start"]\fR,
+and
+\fBa[\fIn\^\fB, "length"]\fR
+provide the starting index in the string and length
+respectively, of each matching substring.
+.TP
+\fBsplit(\fIs\fB, \fIa \fR[\fB, \fIr\fR]\fB)\fR
+Splits the string
+.I s
+into the array
+.I a
+on the regular expression
+.IR r ,
+and returns the number of fields. If
+.I r
+is omitted,
+.B FS
+is used instead.
+The array
+.I a
+is cleared first.
+Splitting behaves identically to field splitting, described above.
+.TP
+.BI sprintf( fmt , " expr-list" )
+Prints
+.I expr-list
+according to
+.IR fmt ,
+and returns the resulting string.
+.TP
+.BI strtonum( str )
+Examines
+.IR str ,
+and returns its numeric value.
+If
+.I str
+begins
+with a leading
+.BR 0 ,
+.B strtonum()
+assumes that
+.I str
+is an octal number.
+If
+.I str
+begins
+with a leading
+.B 0x
+or
+.BR 0X ,
+.B strtonum()
+assumes that
+.I str
+is a hexadecimal number.
+.TP
+\fBsub(\fIr\fB, \fIs \fR[\fB, \fIt\fR]\fB)\fR
+Just like
+.BR gsub() ,
+but only the first matching substring is replaced.
+.TP
+\fBsubstr(\fIs\fB, \fIi \fR[\fB, \fIn\fR]\fB)\fR
+Returns the at most
+.IR n -character
+substring of
+.I s
+starting at
+.IR i .
+If
+.I n
+is omitted, the rest of
+.I s
+is used.
+.TP
+.BI tolower( str )
+Returns a copy of the string
+.IR str ,
+with all the upper-case characters in
+.I str
+translated to their corresponding lower-case counterparts.
+Non-alphabetic characters are left unchanged.
+.TP
+.BI toupper( str )
+Returns a copy of the string
+.IR str ,
+with all the lower-case characters in
+.I str
+translated to their corresponding upper-case counterparts.
+Non-alphabetic characters are left unchanged.
+.SS Time Functions
+Since one of the primary uses of \*(AK programs is processing log files
+that contain time stamp information,
+.I gawk
+provides the following functions for obtaining time stamps and
+formatting them.
+.PP
+.TP "\w'\fBsystime()\fR'u+1n"
+\fBmktime(\fIdatespec\fB)\fR
+Turns
+.I datespec
+into a time stamp of the same form as returned by
+.BR systime() .
+The
+.I datespec
+is a string of the form
+.IR "YYYY MM DD HH MM SS[ DST]" .
+The contents of the string are six or seven numbers representing respectively
+the full year including century,
+the month from 1 to 12,
+the day of the month from 1 to 31,
+the hour of the day from 0 to 23,
+the minute from 0 to 59,
+and the second from 0 to 60,
+and an optional daylight saving flag.
+The values of these numbers need not be within the ranges specified;
+for example, an hour of \-1 means 1 hour before midnight.
+The origin-zero Gregorian calendar is assumed,
+with year 0 preceding year 1 and year \-1 preceding year 0.
+The time is assumed to be in the local timezone.
+If the daylight saving flag is positive,
+the time is assumed to be daylight saving time;
+if zero, the time is assumed to be standard time;
+and if negative (the default),
+.B mktime()
+attempts to determine whether daylight saving time is in effect
+for the specified time.
+If
+.I datespec
+does not contain enough elements or if the resulting time
+is out of range,
+.B mktime()
+returns \-1.
+.TP
+\fBstrftime(\fR[\fIformat \fR[\fB, \fItimestamp\fR]]\fB)\fR
+Formats
+.I timestamp
+according to the specification in
+.IR format.
+The
+.I timestamp
+should be of the same form as returned by
+.BR systime() .
+If
+.I timestamp
+is missing, the current time of day is used.
+If
+.I format
+is missing, a default format equivalent to the output of
+.IR date (1)
+is used.
+See the specification for the
+.B strftime()
+function in \*(AN C for the format conversions that are
+guaranteed to be available.
+A public-domain version of
+.IR strftime (3)
+and a man page for it come with
+.IR gawk ;
+if that version was used to build
+.IR gawk ,
+then all of the conversions described in that man page are available to
+.IR gawk.
+.TP
+.B systime()
+Returns the current time of day as the number of seconds since the Epoch
+(1970-01-01 00:00:00 UTC on \*(PX systems).
+.SS Bit Manipulations Functions
+Starting with version 3.1 of
+.IR gawk ,
+the following bit manipulation functions are available.
+They work by converting double-precision floating point
+values to
+.B "unsigned long"
+integers, doing the operation, and then converting the
+result back to floating point.
+The functions are:
+.TP "\w'\fBrshift(\fIval\fB, \fIcount\fB)\fR'u+2n"
+\fBand(\fIv1\fB, \fIv2\fB)\fR
+Return the bitwise AND of the values provided by
+.I v1
+and
+.IR v2 .
+.TP
+\fBcompl(\fIval\fB)\fR
+Return the bitwise complement of
+.IR val .
+.TP
+\fBlshift(\fIval\fB, \fIcount\fB)\fR
+Return the value of
+.IR val ,
+shifted left by
+.I count
+bits.
+.TP
+\fBor(\fIv1\fB, \fIv2\fB)\fR
+Return the bitwise OR of the values provided by
+.I v1
+and
+.IR v2 .
+.TP
+\fBrshift(\fIval\fB, \fIcount\fB)\fR
+Return the value of
+.IR val ,
+shifted right by
+.I count
+bits.
+.TP
+\fBxor(\fIv1\fB, \fIv2\fB)\fR
+Return the bitwise XOR of the values provided by
+.I v1
+and
+.IR v2 .
+.PP
+.SS Internationalization Functions
+Starting with version 3.1 of
+.IR gawk ,
+the following functions may be used from within your AWK program for
+translating strings at run-time.
+For full details, see \*(EP.
+.TP
+\fBbindtextdomain(\fIdirectory \fR[\fB, \fIdomain\fR]\fB)\fR
+Specifies the directory where
+.I gawk
+looks for the
+.B \&.mo
+files, in case they
+will not or cannot be placed in the ``standard'' locations
+(e.g., during testing).
+It returns the directory where
+.I domain
+is ``bound.''
+.sp .5
+The default
+.I domain
+is the value of
+.BR TEXTDOMAIN .
+If
+.I directory
+is the null string (\fB""\fR), then
+.B bindtextdomain()
+returns the current binding for the
+given
+.IR domain .
+.TP
+\fBdcgettext(\fIstring \fR[\fB, \fIdomain \fR[\fB, \fIcategory\fR]]\fB)\fR
+Returns the translation of
+.I string
+in
+text domain
+.I domain
+for locale category
+.IR category .
+The default value for
+.I domain
+is the current value of
+.BR TEXTDOMAIN .
+The default value for
+.I category
+is \fB"LC_MESSAGES"\fR.
+.sp .5
+If you supply a value for
+.IR category ,
+it must be a string equal to
+one of the known locale categories described
+in \*(EP.
+You must also supply a text domain. Use
+.B TEXTDOMAIN
+if you want to use the current domain.
+.TP
+\fBdcngettext(\fIstring1 \fR, \fIstring2 \fR, \fInumber \fR[\fB, \fIdomain \fR[\fB, \fIcategory\fR]]\fB)\fR
+Returns the plural form used for
+.I number
+of the translation of
+.I string1
+and
+.I string2
+in
+text domain
+.I domain
+for locale category
+.IR category .
+The default value for
+.I domain
+is the current value of
+.BR TEXTDOMAIN .
+The default value for
+.I category
+is \fB"LC_MESSAGES"\fR.
+.sp .5
+If you supply a value for
+.IR category ,
+it must be a string equal to
+one of the known locale categories described
+in \*(EP.
+You must also supply a text domain. Use
+.B TEXTDOMAIN
+if you want to use the current domain.
+.SH USER-DEFINED FUNCTIONS
+Functions in \*(AK are defined as follows:
+.PP
+.RS
+\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements \fB}\fR
+.RE
+.PP
+Functions are executed when they are called from within expressions
+in either patterns or actions. Actual parameters supplied in the function
+call are used to instantiate the formal parameters declared in the function.
+Arrays are passed by reference, other variables are passed by value.
+.PP
+Since functions were not originally part of the \*(AK language, the provision
+for local variables is rather clumsy: They are declared as extra parameters
+in the parameter list. The convention is to separate local variables from
+real parameters by extra spaces in the parameter list. For example:
+.PP
+.RS
+.ft B
+.nf
+function f(p, q, a, b) # a and b are local
+{
+ \&.\|.\|.
+}
+
+/abc/ { .\|.\|. ; f(1, 2) ; .\|.\|. }
+.fi
+.ft R
+.RE
+.PP
+The left parenthesis in a function call is required
+to immediately follow the function name,
+without any intervening white space.
+This is to avoid a syntactic ambiguity with the concatenation operator.
+This restriction does not apply to the built-in functions listed above.
+.PP
+Functions may call each other and may be recursive.
+Function parameters used as local variables are initialized
+to the null string and the number zero upon function invocation.
+.PP
+Use
+.BI return " expr"
+to return a value from a function. The return value is undefined if no
+value is provided, or if the function returns by \*(lqfalling off\*(rq the
+end.
+.PP
+If
+.B \-\^\-lint
+has been provided,
+.I gawk
+warns about calls to undefined functions at parse time,
+instead of at run time.
+Calling an undefined function at run time is a fatal error.
+.PP
+The word
+.B func
+may be used in place of
+.BR function .
+.SH DYNAMICALLY LOADING NEW FUNCTIONS
+Beginning with version 3.1 of
+.IR gawk ,
+you can dynamically add new built-in functions to the running
+.I gawk
+interpreter.
+The full details are beyond the scope of this manual page;
+see \*(EP for the details.
+.PP
+.TP 8
+\fBextension(\fIobject\fB, \fIfunction\fB)\fR
+Dynamically link the shared object file named by
+.IR object ,
+and invoke
+.I function
+in that object, to perform initialization.
+These should both be provided as strings.
+Returns the value returned by
+.IR function .
+.PP
+.ft B
+This function is provided and documented in \*(EP,
+but everything about this feature is likely to change
+in the next release.
+We STRONGLY recommend that you do not use this feature
+for anything that you aren't willing to redo.
+.ft R
+.SH SIGNALS
+.I pgawk
+accepts two signals.
+.B SIGUSR1
+causes it to dump a profile and function call stack to the
+profile file, which is either
+.BR awkprof.out ,
+or whatever file was named with the
+.B \-\^\-profile
+option. It then continues to run.
+.B SIGHUP
+causes it to dump the profile and function call stack and then exit.
+.SH EXAMPLES
+.nf
+Print and sort the login names of all users:
+
+.ft B
+ BEGIN { FS = ":" }
+ { print $1 | "sort" }
+
+.ft R
+Count lines in a file:
+
+.ft B
+ { nlines++ }
+ END { print nlines }
+
+.ft R
+Precede each line by its number in the file:
+
+.ft B
+ { print FNR, $0 }
+
+.ft R
+Concatenate and line number (a variation on a theme):
+
+.ft B
+ { print NR, $0 }
+.ft R
+Run an external command for particular lines of data:
+
+.ft B
+ tail -f access_log |
+ awk '/myhome.html/ { system("nmap " $1 ">> logdir/myhome.html") }'
+.ft R
+.fi
+.SH INTERNATIONALIZATION
+.PP
+String constants are sequences of characters enclosed in double
+quotes. In non-English speaking environments, it is possible to mark
+strings in the \*(AK program as requiring translation to the native
+natural language. Such strings are marked in the \*(AK program with
+a leading underscore (\*(lq_\*(rq). For example,
+.sp
+.RS
+.ft B
+gawk 'BEGIN { print "hello, world" }'
+.RE
+.sp
+.ft R
+always prints
+.BR "hello, world" .
+But,
+.sp
+.RS
+.ft B
+gawk 'BEGIN { print _"hello, world" }'
+.RE
+.sp
+.ft R
+might print
+.B "bonjour, monde"
+in France.
+.PP
+There are several steps involved in producing and running a localizable
+\*(AK program.
+.TP "\w'4.'u+2n"
+1.
+Add a
+.B BEGIN
+action to assign a value to the
+.B TEXTDOMAIN
+variable to set the text domain to a name associated with your program.
+.sp
+.ti +5n
+.ft B
+BEGIN { TEXTDOMAIN = "myprog" }
+.ft R
+.sp
+This allows
+.I gawk
+to find the
+.B \&.mo
+file associated with your program.
+Without this step,
+.I gawk
+uses the
+.B messages
+text domain,
+which likely does not contain translations for your program.
+.TP
+2.
+Mark all strings that should be translated with leading underscores.
+.TP
+3.
+If necessary, use the
+.B dcgettext()
+and/or
+.B bindtextdomain()
+functions in your program, as appropriate.
+.TP
+4.
+Run
+.B "gawk \-\^\-gen\-po \-f myprog.awk > myprog.po"
+to generate a
+.B \&.po
+file for your program.
+.TP
+5.
+Provide appropriate translations, and build and install a corresponding
+.B \&.mo
+file.
+.PP
+The internationalization features are described in full detail in \*(EP.
+.SH POSIX COMPATIBILITY
+A primary goal for
+.I gawk
+is compatibility with the \*(PX standard, as well as with the
+latest version of \*(UX
+.IR awk .
+To this end,
+.I gawk
+incorporates the following user visible
+features which are not described in the \*(AK book,
+but are part of the Bell Laboratories version of
+.IR awk ,
+and are in the \*(PX standard.
+.PP
+The book indicates that command line variable assignment happens when
+.I awk
+would otherwise open the argument as a file, which is after the
+.B BEGIN
+block is executed. However, in earlier implementations, when such an
+assignment appeared before any file names, the assignment would happen
+.I before
+the
+.B BEGIN
+block was run. Applications came to depend on this \*(lqfeature.\*(rq
+When
+.I awk
+was changed to match its documentation, the
+.B \-v
+option for assigning variables before program execution was added to
+accommodate applications that depended upon the old behavior.
+(This feature was agreed upon by both the Bell Laboratories and the \*(GN developers.)
+.PP
+The
+.B \-W
+option for implementation specific features is from the \*(PX standard.
+.PP
+When processing arguments,
+.I gawk
+uses the special option \*(lq\-\^\-\*(rq to signal the end of
+arguments.
+In compatibility mode, it warns about but otherwise ignores
+undefined options.
+In normal operation, such arguments are passed on to the \*(AK program for
+it to process.
+.PP
+The \*(AK book does not define the return value of
+.BR srand() .
+The \*(PX standard
+has it return the seed it was using, to allow keeping track
+of random number sequences. Therefore
+.B srand()
+in
+.I gawk
+also returns its current seed.
+.PP
+Other new features are:
+The use of multiple
+.B \-f
+options (from MKS
+.IR awk );
+the
+.B ENVIRON
+array; the
+.BR \ea ,
+and
+.BR \ev
+escape sequences (done originally in
+.I gawk
+and fed back into the Bell Laboratories version); the
+.B tolower()
+and
+.B toupper()
+built-in functions (from the Bell Laboratories version); and the \*(AN C conversion specifications in
+.B printf
+(done first in the Bell Laboratories version).
+.SH HISTORICAL FEATURES
+There are two features of historical \*(AK implementations that
+.I gawk
+supports.
+First, it is possible to call the
+.B length()
+built-in function not only with no argument, but even without parentheses!
+Thus,
+.RS
+.PP
+.ft B
+a = length # Holy Algol 60, Batman!
+.ft R
+.RE
+.PP
+is the same as either of
+.RS
+.PP
+.ft B
+a = length()
+.br
+a = length($0)
+.ft R
+.RE
+.PP
+This feature is marked as \*(lqdeprecated\*(rq in the \*(PX standard, and
+.I gawk
+issues a warning about its use if
+.B \-\^\-lint
+is specified on the command line.
+.PP
+The other feature is the use of either the
+.B continue
+or the
+.B break
+statements outside the body of a
+.BR while ,
+.BR for ,
+or
+.B do
+loop. Traditional \*(AK implementations have treated such usage as
+equivalent to the
+.B next
+statement.
+.I Gawk
+supports this usage if
+.B \-\^\-traditional
+has been specified.
+.SH GNU EXTENSIONS
+.I Gawk
+has a number of extensions to \*(PX
+.IR awk .
+They are described in this section. All the extensions described here
+can be disabled by
+invoking
+.I gawk
+with the
+.B \-\^\-traditional
+option.
+.PP
+The following features of
+.I gawk
+are not available in
+\*(PX
+.IR awk .
+.\" Environment vars and startup stuff
+.TP "\w'\(bu'u+1n"
+\(bu
+No path search is performed for files named via the
+.B \-f
+option. Therefore the
+.B AWKPATH
+environment variable is not special.
+.\" POSIX and language recognition issues
+.TP
+\(bu
+The
+.B \ex
+escape sequence.
+(Disabled with
+.BR \-\^\-posix .)
+.TP
+\(bu
+The
+.B fflush()
+function.
+(Disabled with
+.BR \-\^\-posix .)
+.TP
+\(bu
+The ability to continue lines after
+.B ?
+and
+.BR : .
+(Disabled with
+.BR \-\^\-posix .)
+.TP
+\(bu
+Octal and hexadecimal constants in AWK programs.
+.\" Special variables
+.TP
+\(bu
+The
+.BR ARGIND ,
+.BR BINMODE ,
+.BR ERRNO ,
+.BR LINT ,
+.B RT
+and
+.B TEXTDOMAIN
+variables are not special.
+.TP
+\(bu
+The
+.B IGNORECASE
+variable and its side-effects are not available.
+.TP
+\(bu
+The
+.B FIELDWIDTHS
+variable and fixed-width field splitting.
+.TP
+\(bu
+The
+.B PROCINFO
+array is not available.
+.\" I/O stuff
+.TP
+\(bu
+The use of
+.B RS
+as a regular expression.
+.TP
+\(bu
+The special file names available for I/O redirection are not recognized.
+.TP
+\(bu
+The
+.B |&
+operator for creating co-processes.
+.\" Changes to standard awk functions
+.TP
+\(bu
+The ability to split out individual characters using the null string
+as the value of
+.BR FS ,
+and as the third argument to
+.BR split() .
+.TP
+\(bu
+The optional second argument to the
+.B close()
+function.
+.TP
+\(bu
+The optional third argument to the
+.B match()
+function.
+.TP
+\(bu
+The ability to use positional specifiers with
+.B printf
+and
+.BR sprintf() .
+.\" New keywords or changes to keywords
+.TP
+\(bu
+The use of
+.BI delete " array"
+to delete the entire contents of an array.
+.TP
+\(bu
+The use of
+.B "nextfile"
+to abandon processing of the current input file.
+.\" New functions
+.TP
+\(bu
+The
+.BR and() ,
+.BR asort() ,
+.BR asorti() ,
+.BR bindtextdomain() ,
+.BR compl() ,
+.BR dcgettext() ,
+.BR dcngettext() ,
+.BR gensub() ,
+.BR lshift() ,
+.BR mktime() ,
+.BR or() ,
+.BR rshift() ,
+.BR strftime() ,
+.BR strtonum() ,
+.B systime()
+and
+.B xor()
+functions.
+.\" I18N stuff
+.TP
+\(bu
+Localizable strings.
+.\" Extending gawk
+.TP
+\(bu
+Adding new built-in functions dynamically with the
+.B extension()
+function.
+.PP
+The \*(AK book does not define the return value of the
+.B close()
+function.
+.IR Gawk\^ "'s"
+.B close()
+returns the value from
+.IR fclose (3),
+or
+.IR pclose (3),
+when closing an output file or pipe, respectively.
+It returns the process's exit status when closing an input pipe.
+The return value is \-1 if the named file, pipe
+or co-process was not opened with a redirection.
+.PP
+When
+.I gawk
+is invoked with the
+.B \-\^\-traditional
+option,
+if the
+.I fs
+argument to the
+.B \-F
+option is \*(lqt\*(rq, then
+.B FS
+is set to the tab character.
+Note that typing
+.B "gawk \-F\et \&.\|.\|."
+simply causes the shell to quote the \*(lqt,\*(rq, and does not pass
+\*(lq\et\*(rq to the
+.B \-F
+option.
+Since this is a rather ugly special case, it is not the default behavior.
+This behavior also does not occur if
+.B \-\^\-posix
+has been specified.
+To really get a tab character as the field separator, it is best to use
+single quotes:
+.BR "gawk \-F'\et' \&.\|.\|." .
+.ig
+.PP
+If
+.I gawk
+was compiled for debugging, it
+accepts the following additional options:
+.TP
+.PD 0
+.B \-Wparsedebug
+.TP
+.PD
+.B \-\^\-parsedebug
+Turn on
+.IR yacc (1)
+or
+.IR bison (1)
+debugging output during program parsing.
+This option should only be of interest to the
+.I gawk
+maintainers, and may not even be compiled into
+.IR gawk .
+..
+.PP
+If
+.I gawk
+is
+.I configured
+with the
+.B \-\^\-enable\-switch
+option to the
+.I configure
+command, then it accepts an additional control-flow statement:
+.RS
+.nf
+\fBswitch (\fIexpression\fB) {
+\fBcase \fIvalue\fB|\fIregex\fB : \fIstatement
+\&.\^.\^.
+\fR[ \fBdefault: \fIstatement \fR]
+\fB}\fR
+.fi
+.RE
+.SH ENVIRONMENT VARIABLES
+The
+.B AWKPATH
+environment variable can be used to provide a list of directories that
+.I gawk
+searches when looking for files named via the
+.B \-f
+and
+.B \-\^\-file
+options.
+.PP
+If
+.B POSIXLY_CORRECT
+exists in the environment, then
+.I gawk
+behaves exactly as if
+.B \-\^\-posix
+had been specified on the command line.
+If
+.B \-\^\-lint
+has been specified,
+.I gawk
+issues a warning message to this effect.
+.SH SEE ALSO
+.IR egrep (1),
+.IR getpid (2),
+.IR getppid (2),
+.IR getpgrp (2),
+.IR getuid (2),
+.IR geteuid (2),
+.IR getgid (2),
+.IR getegid (2),
+.IR getgroups (2)
+.PP
+.IR "The AWK Programming Language" ,
+Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger,
+Addison-Wesley, 1988. ISBN 0-201-07981-X.
+.PP
+\*(EP,
+Edition 3.0, published by the Free Software Foundation, 2001.
+.SH BUGS
+The
+.B \-F
+option is not necessary given the command line variable assignment feature;
+it remains only for backwards compatibility.
+.PP
+Syntactically invalid single character programs tend to overflow
+the parse stack, generating a rather unhelpful message. Such programs
+are surprisingly difficult to diagnose in the completely general case,
+and the effort to do so really is not worth it.
+.SH AUTHORS
+The original version of \*(UX
+.I awk
+was designed and implemented by Alfred Aho,
+Peter Weinberger, and Brian Kernighan of Bell Laboratories. Brian Kernighan
+continues to maintain and enhance it.
+.PP
+Paul Rubin and Jay Fenlason,
+of the Free Software Foundation, wrote
+.IR gawk ,
+to be compatible with the original version of
+.I awk
+distributed in Seventh Edition \*(UX.
+John Woods contributed a number of bug fixes.
+David Trueman, with contributions
+from Arnold Robbins, made
+.I gawk
+compatible with the new version of \*(UX
+.IR awk .
+Arnold Robbins is the current maintainer.
+.PP
+The initial DOS port was done by Conrad Kwok and Scott Garfinkle.
+Scott Deifik is the current DOS maintainer. Pat Rankin did the
+port to VMS, and Michal Jaegermann did the port to the Atari ST.
+The port to OS/2 was done by Kai Uwe Rommel, with contributions and
+help from Darrel Hankerson. Fred Fish supplied support for the Amiga,
+Stephen Davies provided the Tandem port,
+and Martin Brown provided the BeOS port.
+.SH VERSION INFORMATION
+This man page documents
+.IR gawk ,
+version 3.1.5.
+.SH BUG REPORTS
+If you find a bug in
+.IR gawk ,
+please send electronic mail to
+.BR bug-gawk@gnu.org .
+Please include your operating system and its revision, the version of
+.I gawk
+(from
+.BR "gawk \-\^\-version" ),
+what C compiler you used to compile it, and a test program
+and data that are as small as possible for reproducing the problem.
+.PP
+Before sending a bug report, please do two things. First, verify that
+you have the latest version of
+.IR gawk .
+Many bugs (usually subtle ones) are fixed at each release, and if
+yours is out of date, the problem may already have been solved.
+Second, please read this man page and the reference manual carefully to
+be sure that what you think is a bug really is, instead of just a quirk
+in the language.
+.PP
+Whatever you do, do
+.B NOT
+post a bug report in
+.BR comp.lang.awk .
+While the
+.I gawk
+developers occasionally read this newsgroup, posting bug reports there
+is an unreliable way to report bugs. Instead, please use the electronic mail
+addresses given above.
+.PP
+If you're using a GNU/Linux system or BSD-based system,
+you may wish to submit a bug report to the vendor of your distribution.
+That's fine, but please send a copy to the official email address as well,
+since there's no guarantee that the bug will be forwarded to the
+.I gawk
+maintainer.
+.SH ACKNOWLEDGEMENTS
+Brian Kernighan of Bell Laboratories
+provided valuable assistance during testing and debugging.
+We thank him.
+.SH COPYING PERMISSIONS
+Copyright \(co 1989, 1991, 1992, 1993, 1994, 1995, 1996,
+1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual page provided the copyright notice and this permission
+notice are preserved on all copies.
+.ig
+Permission is granted to process this file through troff and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual page).
+..
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual page under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual page into another language, under the above conditions for
+modified versions, except that this permission notice may be stated in
+a translation approved by the Foundation.
--- /dev/null
+This is gawk.info, produced by makeinfo version 4.6 from gawk.texi.
+
+INFO-DIR-SECTION Text creation and manipulation
+START-INFO-DIR-ENTRY
+* Gawk: (gawk). A text scanning and processing language.
+END-INFO-DIR-ENTRY
+INFO-DIR-SECTION Individual utilities
+START-INFO-DIR-ENTRY
+* awk: (gawk)Invoking gawk. Text scanning and processing.
+END-INFO-DIR-ENTRY
+
+Copyright (C) 1989, 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+
+ This is Edition 3 of `GAWK: Effective AWK Programming: A User's
+Guide for GNU Awk', for the 3.1.5 (or later) version of the GNU
+implementation of AWK.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License", the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+ a. "A GNU Manual"
+
+ b. "You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development."
+
+\1f
+File: gawk.info, Node: Top, Next: Foreword, Up: (dir)
+
+General Introduction
+********************
+
+This file documents `awk', a program that you can use to select
+particular records in a file and perform operations upon them.
+
+Copyright (C) 1989, 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+
+ This is Edition 3 of `GAWK: Effective AWK Programming: A User's
+Guide for GNU Awk', for the 3.1.5 (or later) version of the GNU
+implementation of AWK.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License", the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+ a. "A GNU Manual"
+
+ b. "You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development."
+
+* Menu:
+
+* Foreword:: Some nice words about this
+ Info file.
+* Preface:: What this Info file is about; brief
+ history and acknowledgments.
+* Getting Started:: A basic introduction to using
+ `awk'. How to run an `awk'
+ program. Command-line syntax.
+* Regexp:: All about matching things using regular
+ expressions.
+* Reading Files:: How to read files and manipulate fields.
+* Printing:: How to print using `awk'. Describes
+ the `print' and `printf'
+ statements. Also describes redirection of
+ output.
+* Expressions:: Expressions are the basic building blocks
+ of statements.
+* Patterns and Actions:: Overviews of patterns and actions.
+* Arrays:: The description and use of arrays. Also
+ includes array-oriented control statements.
+* Functions:: Built-in and user-defined functions.
+* Internationalization:: Getting `gawk' to speak your
+ language.
+* Advanced Features:: Stuff for advanced users, specific to
+ `gawk'.
+* Invoking Gawk:: How to run `gawk'.
+* Library Functions:: A Library of `awk' Functions.
+* Sample Programs:: Many `awk' programs with complete
+ explanations.
+* Language History:: The evolution of the `awk'
+ language.
+* Installation:: Installing `gawk' under various
+ operating systems.
+* Notes:: Notes about `gawk' extensions and
+ possible future work.
+* Basic Concepts:: A very quick intoduction to programming
+ concepts.
+* Glossary:: An explanation of some unfamiliar terms.
+* Copying:: Your right to copy and distribute
+ `gawk'.
+* GNU Free Documentation License:: The license for this Info file.
+* Index:: Concept and Variable Index.
+
+* History:: The history of `gawk' and
+ `awk'.
+* Names:: What name to use to find `awk'.
+* This Manual:: Using this Info file. Includes
+ sample input files that you can use.
+* Conventions:: Typographical Conventions.
+* Manual History:: Brief history of the GNU project and this
+ Info file.
+* How To Contribute:: Helping to save the world.
+* Acknowledgments:: Acknowledgments.
+* Running gawk:: How to run `gawk' programs;
+ includes command-line syntax.
+* One-shot:: Running a short throwaway `awk'
+ program.
+* Read Terminal:: Using no input files (input from terminal
+ instead).
+* Long:: Putting permanent `awk' programs in
+ files.
+* Executable Scripts:: Making self-contained `awk'
+ programs.
+* Comments:: Adding documentation to `gawk'
+ programs.
+* Quoting:: More discussion of shell quoting issues.
+* Sample Data Files:: Sample data files for use in the
+ `awk' programs illustrated in this
+ Info file.
+* Very Simple:: A very simple example.
+* Two Rules:: A less simple one-line example using two
+ rules.
+* More Complex:: A more complex example.
+* Statements/Lines:: Subdividing or combining statements into
+ lines.
+* Other Features:: Other Features of `awk'.
+* When:: When to use `gawk' and when to use
+ other things.
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Character Lists:: What can go between `[...]'.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* Locales:: How the locale affects things.
+* Records:: Controlling how data is split into records.
+* Fields:: An introduction to fields.
+* Nonconstant Fields:: Nonconstant Field Numbers.
+* Changing Fields:: Changing the Contents of a Field.
+* Field Separators:: The field separator and how to change it.
+* Regexp Field Splitting:: Using regexps as the field separator.
+* Single Character Fields:: Making each character a separate field.
+* Command Line Field Separator:: Setting `FS' from the command-line.
+* Field Splitting Summary:: Some final points and a summary table.
+* Constant Size:: Reading constant width data.
+* Multiple Line:: Reading multi-line records.
+* Getline:: Reading files under explicit program
+ control using the `getline' function.
+* Plain Getline:: Using `getline' with no arguments.
+* Getline/Variable:: Using `getline' into a variable.
+* Getline/File:: Using `getline' from a file.
+* Getline/Variable/File:: Using `getline' into a variable from a
+ file.
+* Getline/Pipe:: Using `getline' from a pipe.
+* Getline/Variable/Pipe:: Using `getline' into a variable from a
+ pipe.
+* Getline/Coprocess:: Using `getline' from a coprocess.
+* Getline/Variable/Coprocess:: Using `getline' into a variable from a
+ coprocess.
+* Getline Notes:: Important things to know about
+ `getline'.
+* Getline Summary:: Summary of `getline' Variants.
+* Print:: The `print' statement.
+* Print Examples:: Simple examples of `print' statements.
+* Output Separators:: The output separators and how to change
+ them.
+* OFMT:: Controlling Numeric Output With
+ `print'.
+* Printf:: The `printf' statement.
+* Basic Printf:: Syntax of the `printf' statement.
+* Control Letters:: Format-control letters.
+* Format Modifiers:: Format-specification modifiers.
+* Printf Examples:: Several examples.
+* Redirection:: How to redirect output to multiple files
+ and pipes.
+* Special Files:: File name interpretation in `gawk'.
+ `gawk' allows access to inherited
+ file descriptors.
+* Special FD:: Special files for I/O.
+* Special Process:: Special files for process information.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+* Close Files And Pipes:: Closing Input and Output Files and Pipes.
+* Constants:: String, numeric and regexp constants.
+* Scalar Constants:: Numeric and string constants.
+* Nondecimal-numbers:: What are octal and hex numbers.
+* Regexp Constants:: Regular Expression constants.
+* Using Constant Regexps:: When and how to use a regexp constant.
+* Variables:: Variables give names to values for later
+ use.
+* Using Variables:: Using variables in your programs.
+* Assignment Options:: Setting variables on the command-line and a
+ summary of command-line syntax. This is an
+ advanced method of input.
+* Conversion:: The conversion of strings to numbers and
+ vice versa.
+* Arithmetic Ops:: Arithmetic operations (`+', `-',
+ etc.)
+* Concatenation:: Concatenating strings.
+* Assignment Ops:: Changing the value of a variable or a
+ field.
+* Increment Ops:: Incrementing the numeric value of a
+ variable.
+* Truth Values:: What is ``true'' and what is ``false''.
+* Typing and Comparison:: How variables acquire types and how this
+ affects comparison of numbers and strings
+ with `<', etc.
+* Boolean Ops:: Combining comparison expressions using
+ boolean operators `||' (``or''),
+ `&&' (``and'') and `!' (``not'').
+* Conditional Exp:: Conditional expressions select between two
+ subexpressions under control of a third
+ subexpression.
+* Function Calls:: A function call is an expression.
+* Precedence:: How various operators nest.
+* Pattern Overview:: What goes into a pattern.
+* Regexp Patterns:: Using regexps as patterns.
+* Expression Patterns:: Any expression can be used as a pattern.
+* Ranges:: Pairs of patterns specify record ranges.
+* BEGIN/END:: Specifying initialization and cleanup
+ rules.
+* Using BEGIN/END:: How and why to use BEGIN/END rules.
+* I/O And BEGIN/END:: I/O issues in BEGIN/END rules.
+* Empty:: The empty pattern, which matches every
+ record.
+* Using Shell Variables:: How to use shell variables with
+ `awk'.
+* Action Overview:: What goes into an action.
+* Statements:: Describes the various control statements in
+ detail.
+* If Statement:: Conditionally execute some `awk'
+ statements.
+* While Statement:: Loop until some condition is satisfied.
+* Do Statement:: Do specified action while looping until
+ some condition is satisfied.
+* For Statement:: Another looping statement, that provides
+ initialization and increment clauses.
+* Switch Statement:: Switch/case evaluation for conditional
+ execution of statements based on a value.
+* Break Statement:: Immediately exit the innermost enclosing
+ loop.
+* Continue Statement:: Skip to the end of the innermost enclosing
+ loop.
+* Next Statement:: Stop processing the current input record.
+* Nextfile Statement:: Stop processing the current file.
+* Exit Statement:: Stop execution of `awk'.
+* Built-in Variables:: Summarizes the built-in variables.
+* User-modified:: Built-in variables that you change to
+ control `awk'.
+* Auto-set:: Built-in variables where `awk'
+ gives you information.
+* ARGC and ARGV:: Ways to use `ARGC' and `ARGV'.
+* Array Intro:: Introduction to Arrays
+* Reference to Elements:: How to examine one element of an array.
+* Assigning Elements:: How to change an element of an array.
+* Array Example:: Basic Example of an Array
+* Scanning an Array:: A variation of the `for' statement. It
+ loops through the indices of an array's
+ existing elements.
+* Delete:: The `delete' statement removes an
+ element from an array.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ `awk'.
+* Uninitialized Subscripts:: Using Uninitialized variables as
+ subscripts.
+* Multi-dimensional:: Emulating multidimensional arrays in
+ `awk'.
+* Multi-scanning:: Scanning multidimensional arrays.
+* Array Sorting:: Sorting array values and indices.
+* Built-in:: Summarizes the built-in functions.
+* Calling Built-in:: How to call built-in functions.
+* Numeric Functions:: Functions that work with numbers, including
+ `int', `sin' and `rand'.
+* String Functions:: Functions for string manipulation, such as
+ `split', `match' and
+ `sprintf'.
+* Gory Details:: More than you want to know about `\'
+ and `&' with `sub', `gsub',
+ and `gensub'.
+* I/O Functions:: Functions for files and shell commands.
+* Time Functions:: Functions for dealing with timestamps.
+* Bitwise Functions:: Functions for bitwise operations.
+* I18N Functions:: Functions for string translation.
+* User-defined:: Describes User-defined functions in detail.
+* Definition Syntax:: How to write definitions and what they
+ mean.
+* Function Example:: An example function definition and what it
+ does.
+* Function Caveats:: Things to watch out for.
+* Return Statement:: Specifying the value a function returns.
+* Dynamic Typing:: How variable types can change at runtime.
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU `gettext' works.
+* Programmer i18n:: Features for the programmer.
+* Translator i18n:: Features for the translator.
+* String Extraction:: Extracting marked strings.
+* Printf Ordering:: Rearranging `printf' arguments.
+* I18N Portability:: `awk'-level portability issues.
+* I18N Example:: A simple i18n example.
+* Gawk I18N:: `gawk' is also internationalized.
+* Nondecimal Data:: Allowing nondecimal input data.
+* Two-way I/O:: Two-way communications with another
+ process.
+* TCP/IP Networking:: Using `gawk' for network
+ programming.
+* Portal Files:: Using `gawk' with BSD portals.
+* Profiling:: Profiling your `awk' programs.
+* Command Line:: How to run `awk'.
+* Options:: Command-line options and their meanings.
+* Other Arguments:: Input file names and variable assignments.
+* AWKPATH Variable:: Searching directories for `awk'
+ programs.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Known Bugs:: Known Bugs in `gawk'.
+* Library Names:: How to best name private global variables
+ in library functions.
+* General Functions:: Functions that are of general use.
+* Nextfile Function:: Two implementations of a `nextfile'
+ function.
+* Assert Function:: A function for assertions in `awk'
+ programs.
+* Round Function:: A function for rounding if `sprintf'
+ does not do it correctly.
+* Cliff Random Function:: The Cliff Random Number Generator.
+* Ordinal Functions:: Functions for using characters as numbers
+ and vice versa.
+* Join Function:: A function to join an array into a string.
+* Gettimeofday Function:: A function to get formatted times.
+* Data File Management:: Functions for managing command-line data
+ files.
+* Filetrans Function:: A function for handling data file
+ transitions.
+* Rewind Function:: A function for rereading the current file.
+* File Checking:: Checking that data files are readable.
+* Empty Files:: Checking for zero-length files.
+* Ignoring Assigns:: Treating assignments as file names.
+* Getopt Function:: A function for processing command-line
+ arguments.
+* Passwd Functions:: Functions for getting user information.
+* Group Functions:: Functions for getting group information.
+* Running Examples:: How to run these examples.
+* Clones:: Clones of common utilities.
+* Cut Program:: The `cut' utility.
+* Egrep Program:: The `egrep' utility.
+* Id Program:: The `id' utility.
+* Split Program:: The `split' utility.
+* Tee Program:: The `tee' utility.
+* Uniq Program:: The `uniq' utility.
+* Wc Program:: The `wc' utility.
+* Miscellaneous Programs:: Some interesting `awk' programs.
+* Dupword Program:: Finding duplicated words in a document.
+* Alarm Program:: An alarm clock.
+* Translate Program:: A program similar to the `tr'
+ utility.
+* Labels Program:: Printing mailing labels.
+* Word Sorting:: A program to produce a word usage count.
+* History Sorting:: Eliminating duplicate entries from a
+ history file.
+* Extract Program:: Pulling out programs from Texinfo source
+ files.
+* Simple Sed:: A Simple Stream Editor.
+* Igawk Program:: A wrapper for `awk' that includes
+ files.
+* V7/SVR3.1:: The major changes between V7 and System V
+ Release 3.1.
+* SVR4:: Minor changes between System V Releases 3.1
+ and 4.
+* POSIX:: New features from the POSIX standard.
+* BTL:: New features from the Bell Laboratories
+ version of `awk'.
+* POSIX/GNU:: The extensions in `gawk' not in
+ POSIX `awk'.
+* Contributors:: The major contributors to `gawk'.
+* Gawk Distribution:: What is in the `gawk' distribution.
+* Getting:: How to get the distribution.
+* Extracting:: How to extract the distribution.
+* Distribution contents:: What is in the distribution.
+* Unix Installation:: Installing `gawk' under various
+ versions of Unix.
+* Quick Installation:: Compiling `gawk' under Unix.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+* Non-Unix Installation:: Installation on Other Operating Systems.
+* Amiga Installation:: Installing `gawk' on an Amiga.
+* BeOS Installation:: Installing `gawk' on BeOS.
+* PC Installation:: Installing and Compiling `gawk' on
+ MS-DOS and OS/2.
+* PC Binary Installation:: Installing a prepared distribution.
+* PC Compiling:: Compiling `gawk' for MS-DOS, Windows32,
+ and OS/2.
+* PC Using:: Running `gawk' on MS-DOS, Windows32 and
+ OS/2.
+* PC Dynamic:: Compiling `gawk' for dynamic
+ libraries.
+* Cygwin:: Building and running `gawk' for
+ Cygwin.
+* VMS Installation:: Installing `gawk' on VMS.
+* VMS Compilation:: How to compile `gawk' under VMS.
+* VMS Installation Details:: How to install `gawk' under VMS.
+* VMS Running:: How to run `gawk' under VMS.
+* VMS POSIX:: Alternate instructions for VMS POSIX.
+* Unsupported:: Systems whose ports are no longer
+ supported.
+* Atari Installation:: Installing `gawk' on the Atari ST.
+* Atari Compiling:: Compiling `gawk' on Atari.
+* Atari Using:: Running `gawk' on Atari.
+* Tandem Installation:: Installing `gawk' on a Tandem.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available `awk'
+ implementations.
+* Compatibility Mode:: How to disable certain `gawk'
+ extensions.
+* Additions:: Making Additions To `gawk'.
+* Adding Code:: Adding code to the main body of
+ `gawk'.
+* New Ports:: Porting `gawk' to a new operating
+ system.
+* Dynamic Extensions:: Adding new built-in functions to
+ `gawk'.
+* Internals:: A brief look at some `gawk'
+ internals.
+* Sample Library:: A example of new functions.
+* Internal File Description:: What the new functions will do.
+* Internal File Ops:: The code for internal file operations.
+* Using Internal File Ops:: How to use an external extension.
+* Future Extensions:: New features that may be implemented one
+ day.
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+* Floating Point Issues:: Stuff to know about floating-point numbers.
+
+ To Miriam, for making me complete.
+
+ To Chana, for the joy you bring us.
+
+ To Rivka, for the exponential increase.
+
+ To Nachum, for the added dimension.
+
+ To Malka, for the new beginning.
+
+
+\1f
+File: gawk.info, Node: Foreword, Next: Preface, Prev: Top, Up: Top
+
+Foreword
+********
+
+Arnold Robbins and I are good friends. We were introduced 11 years ago
+by circumstances--and our favorite programming language, AWK. The
+circumstances started a couple of years earlier. I was working at a new
+job and noticed an unplugged Unix computer sitting in the corner. No
+one knew how to use it, and neither did I. However, a couple of days
+later it was running, and I was `root' and the one-and-only user. That
+day, I began the transition from statistician to Unix programmer.
+
+ On one of many trips to the library or bookstore in search of books
+on Unix, I found the gray AWK book, a.k.a. Aho, Kernighan and
+Weinberger, `The AWK Programming Language', Addison-Wesley, 1988.
+AWK's simple programming paradigm--find a pattern in the input and then
+perform an action--often reduced complex or tedious data manipulations
+to few lines of code. I was excited to try my hand at programming in
+AWK.
+
+ Alas, the `awk' on my computer was a limited version of the
+language described in the AWK book. I discovered that my computer had
+"old `awk'" and the AWK book described "new `awk'." I learned that
+this was typical; the old version refused to step aside or relinquish
+its name. If a system had a new `awk', it was invariably called
+`nawk', and few systems had it. The best way to get a new `awk' was to
+`ftp' the source code for `gawk' from `prep.ai.mit.edu'. `gawk' was a
+version of new `awk' written by David Trueman and Arnold, and available
+under the GNU General Public License.
+
+ (Incidentally, it's no longer difficult to find a new `awk'. `gawk'
+ships with Linux, and you can download binaries or source code for
+almost any system; my wife uses `gawk' on her VMS box.)
+
+ My Unix system started out unplugged from the wall; it certainly was
+not plugged into a network. So, oblivious to the existence of `gawk'
+and the Unix community in general, and desiring a new `awk', I wrote my
+own, called `mawk'. Before I was finished I knew about `gawk', but it
+was too late to stop, so I eventually posted to a `comp.sources'
+newsgroup.
+
+ A few days after my posting, I got a friendly email from Arnold
+introducing himself. He suggested we share design and algorithms and
+attached a draft of the POSIX standard so that I could update `mawk' to
+support language extensions added after publication of the AWK book.
+
+ Frankly, if our roles had been reversed, I would not have been so
+open and we probably would have never met. I'm glad we did meet. He
+is an AWK expert's AWK expert and a genuinely nice person. Arnold
+contributes significant amounts of his expertise and time to the Free
+Software Foundation.
+
+ This book is the `gawk' reference manual, but at its core it is a
+book about AWK programming that will appeal to a wide audience. It is
+a definitive reference to the AWK language as defined by the 1987 Bell
+Labs release and codified in the 1992 POSIX Utilities standard.
+
+ On the other hand, the novice AWK programmer can study a wealth of
+practical programs that emphasize the power of AWK's basic idioms: data
+driven control-flow, pattern matching with regular expressions, and
+associative arrays. Those looking for something new can try out
+`gawk''s interface to network protocols via special `/inet' files.
+
+ The programs in this book make clear that an AWK program is
+typically much smaller and faster to develop than a counterpart written
+in C. Consequently, there is often a payoff to prototype an algorithm
+or design in AWK to get it running quickly and expose problems early.
+Often, the interpreted performance is adequate and the AWK prototype
+becomes the product.
+
+ The new `pgawk' (profiling `gawk'), produces program execution
+counts. I recently experimented with an algorithm that for n lines of
+input, exhibited ~ C n^2 performance, while theory predicted ~ C n log n
+behavior. A few minutes poring over the `awkprof.out' profile
+pinpointed the problem to a single line of code. `pgawk' is a welcome
+addition to my programmer's toolbox.
+
+ Arnold has distilled over a decade of experience writing and using
+AWK programs, and developing `gawk', into this book. If you use AWK or
+want to learn how, then read this book.
+
+ Michael Brennan
+ Author of `mawk'
+
+\1f
+File: gawk.info, Node: Preface, Next: Getting Started, Prev: Foreword, Up: Top
+
+Preface
+*******
+
+Several kinds of tasks occur repeatedly when working with text files.
+You might want to extract certain lines and discard the rest. Or you
+may need to make changes wherever certain patterns appear, but leave
+the rest of the file alone. Writing single-use programs for these
+tasks in languages such as C, C++, or Pascal is time-consuming and
+inconvenient. Such jobs are often easier with `awk'. The `awk'
+utility interprets a special-purpose programming language that makes it
+easy to handle simple data-reformatting jobs.
+
+The GNU implementation of `awk' is called `gawk'; it is fully
+compatible with the System V Release 4 version of `awk'. `gawk' is
+also compatible with the POSIX specification of the `awk' language.
+This means that all properly written `awk' programs should work with
+`gawk'. Thus, we usually don't distinguish between `gawk' and other
+`awk' implementations.
+
+Using `awk' allows you to:
+
+ * Manage small, personal databases
+
+ * Generate reports
+
+ * Validate data
+
+ * Produce indexes and perform other document preparation tasks
+
+ * Experiment with algorithms that you can adapt later to other
+ computer languages
+
+In addition, `gawk' provides facilities that make it easy to:
+
+ * Extract bits and pieces of data for processing
+
+ * Sort data
+
+ * Perform simple network communications
+
+This Info file teaches you about the `awk' language and how you can use
+it effectively. You should already be familiar with basic system
+commands, such as `cat' and `ls',(1) as well as basic shell facilities,
+such as input/output (I/O) redirection and pipes.
+
+Implementations of the `awk' language are available for many different
+computing environments. This Info file, while describing the `awk'
+language in general, also describes the particular implementation of
+`awk' called `gawk' (which stands for "GNU awk"). `gawk' runs on a
+broad range of Unix systems, ranging from 80386 PC-based computers up
+through large-scale systems, such as Crays. `gawk' has also been ported
+to Mac OS X, MS-DOS, Microsoft Windows (all versions) and OS/2 PCs,
+Atari and Amiga microcomputers, BeOS, Tandem D20, and VMS.
+
+* Menu:
+
+* History:: The history of `gawk' and
+ `awk'.
+* Names:: What name to use to find `awk'.
+* This Manual:: Using this Info file. Includes sample
+ input files that you can use.
+* Conventions:: Typographical Conventions.
+* Manual History:: Brief history of the GNU project and this
+ Info file.
+* How To Contribute:: Helping to save the world.
+* Acknowledgments:: Acknowledgments.
+
+---------- Footnotes ----------
+
+(1) These commands are available on POSIX-compliant systems, as well as
+on traditional Unix-based systems. If you are using some other
+operating system, you still need to be familiar with the ideas of I/O
+redirection and pipes.
+
+\1f
+File: gawk.info, Node: History, Next: Names, Up: Preface
+
+History of `awk' and `gawk'
+===========================
+
+ Recipe For A Programming Language
+ 1 part `egrep' 1 part `snobol'
+ 2 parts `ed' 3 parts C
+
+ Blend all parts well using `lex' and `yacc'. Document minimally
+ and release.
+
+ After eight years, add another part `egrep' and two more parts C.
+ Document very well and release.
+
+The name `awk' comes from the initials of its designers: Alfred V.
+Aho, Peter J. Weinberger and Brian W. Kernighan. The original version
+of `awk' was written in 1977 at AT&T Bell Laboratories. In 1985, a new
+version made the programming language more powerful, introducing
+user-defined functions, multiple input streams, and computed regular
+expressions. This new version became widely available with Unix System
+V Release 3.1 (SVR3.1). The version in SVR4 added some new features
+and cleaned up the behavior in some of the "dark corners" of the
+language. The specification for `awk' in the POSIX Command Language
+and Utilities standard further clarified the language. Both the `gawk'
+designers and the original Bell Laboratories `awk' designers provided
+feedback for the POSIX specification.
+
+Paul Rubin wrote the GNU implementation, `gawk', in 1986. Jay Fenlason
+completed it, with advice from Richard Stallman. John Woods
+contributed parts of the code as well. In 1988 and 1989, David
+Trueman, with help from me, thoroughly reworked `gawk' for compatibility
+with the newer `awk'. Circa 1995, I became the primary maintainer.
+Current development focuses on bug fixes, performance improvements,
+standards compliance, and occasionally, new features.
+
+In May of 1997, Ju"rgen Kahrs felt the need for network access from
+`awk', and with a little help from me, set about adding features to do
+this for `gawk'. At that time, he also wrote the bulk of `TCP/IP
+Internetworking with `gawk'' (a separate document, available as part of
+the `gawk' distribution). His code finally became part of the main
+`gawk' distribution with `gawk' version 3.1.
+
+*Note Contributors::, for a complete list of those who made important
+contributions to `gawk'.
+
+\1f
+File: gawk.info, Node: Names, Next: This Manual, Prev: History, Up: Preface
+
+A Rose by Any Other Name
+========================
+
+The `awk' language has evolved over the years. Full details are
+provided in *Note Language History::. The language described in this
+Info file is often referred to as "new `awk'" (`nawk').
+
+Because of this, many systems have multiple versions of `awk'. Some
+systems have an `awk' utility that implements the original version of
+the `awk' language and a `nawk' utility for the new version. Others
+have an `oawk' version for the "old `awk'" language and plain `awk' for
+the new one. Still others only have one version, which is usually the
+new one.(1)
+
+All in all, this makes it difficult for you to know which version of
+`awk' you should run when writing your programs. The best advice I can
+give here is to check your local documentation. Look for `awk', `oawk',
+and `nawk', as well as for `gawk'. It is likely that you already have
+some version of new `awk' on your system, which is what you should use
+when running your programs. (Of course, if you're reading this Info
+file, chances are good that you have `gawk'!)
+
+Throughout this Info file, whenever we refer to a language feature that
+should be available in any complete implementation of POSIX `awk', we
+simply use the term `awk'. When referring to a feature that is
+specific to the GNU implementation, we use the term `gawk'.
+
+---------- Footnotes ----------
+
+(1) Often, these systems use `gawk' for their `awk' implementation!
+
+\1f
+File: gawk.info, Node: This Manual, Next: Conventions, Prev: Names, Up: Preface
+
+Using This Book
+===============
+
+The term `awk' refers to a particular program as well as to the
+language you use to tell this program what to do. When we need to be
+careful, we call the language "the `awk' language," and the program
+"the `awk' utility." This Info file explains both the `awk' language
+and how to run the `awk' utility. The term "`awk' program" refers to a
+program written by you in the `awk' programming language.
+
+Primarily, this Info file explains the features of `awk', as defined in
+the POSIX standard. It does so in the context of the `gawk'
+implementation. While doing so, it also attempts to describe important
+differences between `gawk' and other `awk' implementations.(1) Finally,
+any `gawk' features that are not in the POSIX standard for `awk' are
+noted.
+
+There are subsections labelled as *Advanced Notes* scattered throughout
+the Info file. They add a more complete explanation of points that are
+relevant, but not likely to be of interest on first reading. All
+appear in the index, under the heading "advanced features."
+
+Most of the time, the examples use complete `awk' programs. In some of
+the more advanced sections, only the part of the `awk' program that
+illustrates the concept currently being described is shown.
+
+While this Info file is aimed principally at people who have not been
+exposed to `awk', there is a lot of information here that even the `awk'
+expert should find useful. In particular, the description of POSIX
+`awk' and the example programs in *Note Library Functions::, and in
+*Note Sample Programs::, should be of interest.
+
+*Note Getting Started::, provides the essentials you need to know to
+begin using `awk'.
+
+*Note Regexp::, introduces regular expressions in general, and in
+particular the flavors supported by POSIX `awk' and `gawk'.
+
+*Note Reading Files::, describes how `awk' reads your data. It
+introduces the concepts of records and fields, as well as the `getline'
+command. I/O redirection is first described here.
+
+*Note Printing::, describes how `awk' programs can produce output with
+`print' and `printf'.
+
+*Note Expressions::, describes expressions, which are the basic
+building blocks for getting most things done in a program.
+
+*Note Patterns and Actions::, describes how to write patterns for
+matching records, actions for doing something when a record is matched,
+and the built-in variables `awk' and `gawk' use.
+
+*Note Arrays::, covers `awk''s one-and-only data structure: associative
+arrays. Deleting array elements and whole arrays is also described, as
+well as sorting arrays in `gawk'.
+
+*Note Functions::, describes the built-in functions `awk' and `gawk'
+provide, as well as how to define your own functions.
+
+*Note Internationalization::, describes special features in `gawk' for
+translating program messages into different languages at runtime.
+
+*Note Advanced Features::, describes a number of `gawk'-specific
+advanced features. Of particular note are the abilities to have
+two-way communications with another process, perform TCP/IP networking,
+and profile your `awk' programs.
+
+*Note Invoking Gawk::, describes how to run `gawk', the meaning of its
+command-line options, and how it finds `awk' program source files.
+
+*Note Library Functions::, and *Note Sample Programs::, provide many
+sample `awk' programs. Reading them allows you to see `awk' solving
+real problems.
+
+*Note Language History::, describes how the `awk' language has evolved
+since first release to present. It also describes how `gawk' has
+acquired features over time.
+
+*Note Installation::, describes how to get `gawk', how to compile it
+under Unix, and how to compile and use it on different non-Unix
+systems. It also describes how to report bugs in `gawk' and where to
+get three other freely available implementations of `awk'.
+
+*Note Notes::, describes how to disable `gawk''s extensions, as well as
+how to contribute new code to `gawk', how to write extension libraries,
+and some possible future directions for `gawk' development.
+
+*Note Basic Concepts::, provides some very cursory background material
+for those who are completely unfamiliar with computer programming.
+Also centralized there is a discussion of some of the issues
+surrounding floating-point numbers.
+
+The *Note Glossary::, defines most, if not all, the significant terms
+used throughout the book. If you find terms that you aren't familiar
+with, try looking them up here.
+
+*Note Copying::, and *Note GNU Free Documentation License::, present
+the licenses that cover the `gawk' source code and this Info file,
+respectively.
+
+---------- Footnotes ----------
+
+(1) All such differences appear in the index under the entry
+"differences in `awk' and `gawk'."
+
+\1f
+File: gawk.info, Node: Conventions, Next: Manual History, Prev: This Manual, Up: Preface
+
+Typographical Conventions
+=========================
+
+This Info file is written using Texinfo, the GNU documentation
+formatting language. A single Texinfo source file is used to produce
+both the printed and online versions of the documentation. This minor
+node briefly documents the typographical conventions used in Texinfo.
+
+Examples you would type at the command-line are preceded by the common
+shell primary and secondary prompts, `$' and `>'. Output from the
+command is preceded by the glyph "-|". This typically represents the
+command's standard output. Error messages, and other output on the
+command's standard error, are preceded by the glyph "error-->". For
+example:
+
+ $ echo hi on stdout
+ -| hi on stdout
+ $ echo hello on stderr 1>&2
+ error--> hello on stderr
+
+Characters that you type at the keyboard look `like this'. In
+particular, there are special characters called "control characters."
+These are characters that you type by holding down both the `CONTROL'
+key and another key, at the same time. For example, a `Ctrl-d' is typed
+by first pressing and holding the `CONTROL' key, next pressing the `d'
+key and finally releasing both keys.
+
+Dark Corners
+............
+
+ Dark corners are basically fractal -- no matter how much you
+ illuminate, there's always a smaller but darker one.
+ Brian Kernighan
+
+Until the POSIX standard (and `The Gawk Manual'), many features of
+`awk' were either poorly documented or not documented at all.
+Descriptions of such features (often called "dark corners") are noted
+in this Info file with "(d.c.)". They also appear in the index under
+the heading "dark corner."
+
+As noted by the opening quote, though, any coverage of dark corners is,
+by definition, something that is incomplete.
+
+\1f
+File: gawk.info, Node: Manual History, Next: How To Contribute, Prev: Conventions, Up: Preface
+
+The GNU Project and This Book
+=============================
+
+The Free Software Foundation (FSF) is a nonprofit organization dedicated
+to the production and distribution of freely distributable software.
+It was founded by Richard M. Stallman, the author of the original Emacs
+editor. GNU Emacs is the most widely used version of Emacs today.
+
+The GNU(1) Project is an ongoing effort on the part of the Free Software
+Foundation to create a complete, freely distributable, POSIX-compliant
+computing environment. The FSF uses the "GNU General Public License"
+(GPL) to ensure that their software's source code is always available
+to the end user. A copy of the GPL is included for your reference
+(*note Copying::). The GPL applies to the C language source code for
+`gawk'. To find out more about the FSF and the GNU Project online, see
+the GNU Project's home page (http://www.gnu.org). This Info file may
+also be read from their web site (http://www.gnu.org/manual/gawk/).
+
+A shell, an editor (Emacs), highly portable optimizing C, C++, and
+Objective-C compilers, a symbolic debugger and dozens of large and
+small utilities (such as `gawk'), have all been completed and are
+freely available. The GNU operating system kernel (the HURD), has been
+released but is still in an early stage of development.
+
+Until the GNU operating system is more fully developed, you should
+consider using GNU/Linux, a freely distributable, Unix-like operating
+system for Intel 80386, DEC Alpha, Sun SPARC, IBM S/390, and other
+systems.(2) There are many books on GNU/Linux. One that is freely
+available is `Linux Installation and Getting Started', by Matt Welsh.
+Many GNU/Linux distributions are often available in computer stores or
+bundled on CD-ROMs with books about Linux. (There are three other
+freely available, Unix-like operating systems for 80386 and other
+systems: NetBSD, FreeBSD, and OpenBSD. All are based on the 4.4-Lite
+Berkeley Software Distribution, and they use recent versions of `gawk'
+for their versions of `awk'.)
+
+The Info file itself has gone through a number of previous editions.
+Paul Rubin wrote the very first draft of `The GAWK Manual'; it was
+around 40 pages in size. Diane Close and Richard Stallman improved it,
+yielding a version that was around 90 pages long and barely described
+the original, "old" version of `awk'.
+
+I started working with that version in the fall of 1988. As work on it
+progressed, the FSF published several preliminary versions (numbered
+0.X). In 1996, Edition 1.0 was released with `gawk' 3.0.0. The FSF
+published the first two editions under the title `The GNU Awk User's
+Guide'.
+
+This edition maintains the basic structure of Edition 1.0, but with
+significant additional material, reflecting the host of new features in
+`gawk' version 3.1. Of particular note is *Note Array Sorting::, as
+well as *Note Bitwise Functions::, *Note Internationalization::, and
+also *Note Advanced Features::, and *Note Dynamic Extensions::.
+
+`GAWK: Effective AWK Programming' will undoubtedly continue to evolve.
+An electronic version comes with the `gawk' distribution from the FSF.
+If you find an error in this Info file, please report it! *Note
+Bugs::, for information on submitting problem reports electronically,
+or write to me in care of the publisher.
+
+---------- Footnotes ----------
+
+(1) GNU stands for "GNU's not Unix."
+
+(2) The terminology "GNU/Linux" is explained in the *Note Glossary::.
+
+\1f
+File: gawk.info, Node: How To Contribute, Next: Acknowledgments, Prev: Manual History, Up: Preface
+
+How to Contribute
+=================
+
+As the maintainer of GNU `awk', I am starting a collection of publicly
+available `awk' programs. For more information, see
+`ftp://ftp.freefriends.org/arnold/Awkstuff'. If you have written an
+interesting `awk' program, or have written a `gawk' extension that you
+would like to share with the rest of the world, please contact me
+(<arnold@skeeve.com>). Making things available on the Internet helps
+keep the `gawk' distribution down to manageable size.
+
+\1f
+File: gawk.info, Node: Acknowledgments, Prev: How To Contribute, Up: Preface
+
+Acknowledgments
+===============
+
+The initial draft of `The GAWK Manual' had the following
+acknowledgments:
+
+ Many people need to be thanked for their assistance in producing
+ this manual. Jay Fenlason contributed many ideas and sample
+ programs. Richard Mlynarik and Robert Chassell gave helpful
+ comments on drafts of this manual. The paper `A Supplemental
+ Document for `awk'' by John W. Pierce of the Chemistry Department
+ at UC San Diego, pinpointed several issues relevant both to `awk'
+ implementation and to this manual, that would otherwise have
+ escaped us.
+
+I would like to acknowledge Richard M. Stallman, for his vision of a
+better world and for his courage in founding the FSF and starting the
+GNU Project.
+
+The following people (in alphabetical order) provided helpful comments
+on various versions of this book, up to and including this edition.
+Rick Adams, 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, and Chuck Toporek.
+
+Robert J. Chassell provided much valuable advice on the use of Texinfo.
+He also deserves special thanks for convincing me _not_ to title this
+Info file `How To Gawk Politely'. Karl Berry helped significantly with
+the TeX part of Texinfo.
+
+I would like to thank Marshall and Elaine Hartholz of Seattle and Dr.
+Bert and Rita Schreiber of Detroit for large amounts of quiet vacation
+time in their homes, which allowed me to make significant progress on
+this Info file and on `gawk' itself.
+
+Phil Hughes of SSC contributed in a very important way by loaning me
+his laptop GNU/Linux system, not once, but twice, which allowed me to
+do a lot of work while away from home.
+
+David Trueman deserves special credit; he has done a yeoman job of
+evolving `gawk' so that it performs well and without bugs. Although he
+is no longer involved with `gawk', working with him on this project was
+a significant pleasure.
+
+The intrepid members of the GNITS mailing list, and most notably Ulrich
+Drepper, provided invaluable help and feedback for the design of the
+internationalization features.
+
+Nelson Beebe, Martin Brown, Andreas Buening, Scott Deifik, Darrel
+Hankerson, Isamu Hasegawa, Michal Jaegermann, Ju"rgen Kahrs, Pat Rankin,
+Kai Uwe Rommel, and Eli Zaretskii (in alphabetical order) make up the
+`gawk' "crack portability team." Without their hard work and help,
+`gawk' would not be nearly the fine program it is today. It has been
+and continues to be a pleasure working with this team of fine people.
+
+David and I would like to thank Brian Kernighan of Bell Laboratories for
+invaluable assistance during the testing and debugging of `gawk', and
+for help in clarifying numerous points about the language. We could
+not have done nearly as good a job on either `gawk' or its
+documentation without his help.
+
+Chuck Toporek, Mary Sheehan, and Claire Coutier of O'Reilly &
+Associates contributed significant editorial help for this Info file
+for the 3.1 release of `gawk'.
+
+I must thank my wonderful wife, Miriam, for her patience through the
+many versions of this project, for her proofreading, and for sharing me
+with the computer. I would like to thank my parents for their love,
+and for the grace with which they raised and educated me. Finally, I
+also must acknowledge my gratitude to G-d, for the many opportunities
+He has sent my way, as well as for the gifts He has given me with which
+to take advantage of those opportunities.
+
+
+Arnold Robbins
+Nof Ayalon
+ISRAEL
+March, 2001
+
+\1f
+File: gawk.info, Node: Getting Started, Next: Regexp, Prev: Preface, Up: Top
+
+1 Getting Started with `awk'
+****************************
+
+The basic function of `awk' is to search files for lines (or other
+units of text) that contain certain patterns. When a line matches one
+of the patterns, `awk' performs specified actions on that line. `awk'
+keeps processing input lines in this way until it reaches the end of
+the input files.
+
+Programs in `awk' are different from programs in most other languages,
+because `awk' programs are "data-driven"; that is, you describe the
+data you want to work with and then what to do when you find it. Most
+other languages are "procedural"; you have to describe, in great
+detail, every step the program is to take. When working with procedural
+languages, it is usually much harder to clearly describe the data your
+program will process. For this reason, `awk' programs are often
+refreshingly easy to read and write.
+
+When you run `awk', you specify an `awk' "program" that tells `awk'
+what to do. The program consists of a series of "rules". (It may also
+contain "function definitions", an advanced feature that we will ignore
+for now. *Note User-defined::.) Each rule specifies one pattern to
+search for and one action to perform upon finding the pattern.
+
+Syntactically, a rule consists of a pattern followed by an action. The
+action is enclosed in curly braces to separate it from the pattern.
+Newlines usually separate rules. Therefore, an `awk' program looks
+like this:
+
+ PATTERN { ACTION }
+ PATTERN { ACTION }
+ ...
+
+* Menu:
+
+* Running gawk:: How to run `gawk' programs; includes
+ command-line syntax.
+* Sample Data Files:: Sample data files for use in the `awk'
+ programs illustrated in this Info file.
+* Very Simple:: A very simple example.
+* Two Rules:: A less simple one-line example using two
+ rules.
+* More Complex:: A more complex example.
+* Statements/Lines:: Subdividing or combining statements into
+ lines.
+* Other Features:: Other Features of `awk'.
+* When:: When to use `gawk' and when to use
+ other things.
+
+\1f
+File: gawk.info, Node: Running gawk, Next: Sample Data Files, Up: Getting Started
+
+1.1 How to Run `awk' Programs
+=============================
+
+There are several ways to run an `awk' program. If the program is
+short, it is easiest to include it in the command that runs `awk', like
+this:
+
+ awk 'PROGRAM' INPUT-FILE1 INPUT-FILE2 ...
+
+When the program is long, it is usually more convenient to put it in a
+file and run it with a command like this:
+
+ awk -f PROGRAM-FILE INPUT-FILE1 INPUT-FILE2 ...
+
+This minor node discusses both mechanisms, along with several
+variations of each.
+
+* Menu:
+
+* One-shot:: Running a short throwaway `awk'
+ program.
+* Read Terminal:: Using no input files (input from terminal
+ instead).
+* Long:: Putting permanent `awk' programs in
+ files.
+* Executable Scripts:: Making self-contained `awk' programs.
+* Comments:: Adding documentation to `gawk'
+ programs.
+* Quoting:: More discussion of shell quoting issues.
+
+\1f
+File: gawk.info, Node: One-shot, Next: Read Terminal, Up: Running gawk
+
+1.1.1 One-Shot Throwaway `awk' Programs
+---------------------------------------
+
+Once you are familiar with `awk', you will often type in simple
+programs the moment you want to use them. Then you can write the
+program as the first argument of the `awk' command, like this:
+
+ awk 'PROGRAM' INPUT-FILE1 INPUT-FILE2 ...
+
+where PROGRAM consists of a series of PATTERNS and ACTIONS, as
+described earlier.
+
+This command format instructs the "shell", or command interpreter, to
+start `awk' and use the PROGRAM to process records in the input
+file(s). There are single quotes around PROGRAM so the shell won't
+interpret any `awk' characters as special shell characters. The quotes
+also cause the shell to treat all of PROGRAM as a single argument for
+`awk', and allow PROGRAM to be more than one line long.
+
+This format is also useful for running short or medium-sized `awk'
+programs from shell scripts, because it avoids the need for a separate
+file for the `awk' program. A self-contained shell script is more
+reliable because there are no other files to misplace.
+
+*Note Very Simple::, presents several short, self-contained programs.
+
+\1f
+File: gawk.info, Node: Read Terminal, Next: Long, Prev: One-shot, Up: Running gawk
+
+1.1.2 Running `awk' Without Input Files
+---------------------------------------
+
+You can also run `awk' without any input files. If you type the
+following command line:
+
+ awk 'PROGRAM'
+
+`awk' applies the PROGRAM to the "standard input", which usually means
+whatever you type on the terminal. This continues until you indicate
+end-of-file by typing `Ctrl-d'. (On other operating systems, the
+end-of-file character may be different. For example, on OS/2 and
+MS-DOS, it is `Ctrl-z'.)
+
+As an example, the following program prints a friendly piece of advice
+(from Douglas Adams's `The Hitchhiker's Guide to the Galaxy'), to keep
+you from worrying about the complexities of computer programming
+(`BEGIN' is a feature we haven't discussed yet):
+
+ $ awk "BEGIN { print \"Don't Panic!\" }"
+ -| Don't Panic!
+
+This program does not read any input. The `\' before each of the inner
+double quotes is necessary because of the shell's quoting rules--in
+particular because it mixes both single quotes and double quotes.(1)
+
+This next simple `awk' program emulates the `cat' utility; it copies
+whatever you type on the keyboard to its standard output (why this
+works is explained shortly).
+
+ $ awk '{ print }'
+ Now is the time for all good men
+ -| Now is the time for all good men
+ to come to the aid of their country.
+ -| to come to the aid of their country.
+ Four score and seven years ago, ...
+ -| Four score and seven years ago, ...
+ What, me worry?
+ -| What, me worry?
+ Ctrl-d
+
+---------- Footnotes ----------
+
+(1) Although we generally recommend the use of single quotes around the
+program text, double quotes are needed here in order to put the single
+quote into the message.
+
+\1f
+File: gawk.info, Node: Long, Next: Executable Scripts, Prev: Read Terminal, Up: Running gawk
+
+1.1.3 Running Long Programs
+---------------------------
+
+Sometimes your `awk' programs can be very long. In this case, it is
+more convenient to put the program into a separate file. In order to
+tell `awk' to use that file for its program, you type:
+
+ awk -f SOURCE-FILE INPUT-FILE1 INPUT-FILE2 ...
+
+The `-f' instructs the `awk' utility to get the `awk' program from the
+file SOURCE-FILE. Any file name can be used for SOURCE-FILE. For
+example, you could put the program:
+
+ BEGIN { print "Don't Panic!" }
+
+into the file `advice'. Then this command:
+
+ awk -f advice
+
+does the same thing as this one:
+
+ awk "BEGIN { print \"Don't Panic!\" }"
+
+This was explained earlier (*note Read Terminal::). Note that you
+don't usually need single quotes around the file name that you specify
+with `-f', because most file names don't contain any of the shell's
+special characters. Notice that in `advice', the `awk' program did not
+have single quotes around it. The quotes are only needed for programs
+that are provided on the `awk' command line.
+
+If you want to identify your `awk' program files clearly as such, you
+can add the extension `.awk' to the file name. This doesn't affect the
+execution of the `awk' program but it does make "housekeeping" easier.
+
+\1f
+File: gawk.info, Node: Executable Scripts, Next: Comments, Prev: Long, Up: Running gawk
+
+1.1.4 Executable `awk' Programs
+-------------------------------
+
+Once you have learned `awk', you may want to write self-contained `awk'
+scripts, using the `#!' script mechanism. You can do this on many Unix
+systems(1) as well as on the GNU system. For example, you could update
+the file `advice' to look like this:
+
+ #! /bin/awk -f
+
+ BEGIN { print "Don't Panic!" }
+
+After making this file executable (with the `chmod' utility), simply
+type `advice' at the shell and the system arranges to run `awk'(2) as
+if you had typed `awk -f advice':
+
+ $ chmod +x advice
+ $ advice
+ -| Don't Panic!
+
+(We assume you have the current directory in your shell's search path
+variable (typically `$PATH'). If not, you may need to type `./advice'
+at the shell.)
+
+Self-contained `awk' scripts are useful when you want to write a
+program that users can invoke without their having to know that the
+program is written in `awk'.
+
+Advanced Notes: Portability Issues with `#!'
+--------------------------------------------
+
+Some systems limit the length of the interpreter name to 32 characters.
+Often, this can be dealt with by using a symbolic link.
+
+You should not put more than one argument on the `#!' line after the
+path to `awk'. It does not work. The operating system treats the rest
+of the line as a single argument and passes it to `awk'. Doing this
+leads to confusing behavior--most likely a usage diagnostic of some
+sort from `awk'.
+
+Finally, the value of `ARGV[0]' (*note Built-in Variables::) varies
+depending upon your operating system. Some systems put `awk' there,
+some put the full pathname of `awk' (such as `/bin/awk'), and some put
+the name of your script (`advice'). Don't rely on the value of
+`ARGV[0]' to provide your script name.
+
+---------- Footnotes ----------
+
+(1) The `#!' mechanism works on Linux systems, systems derived from the
+4.4-Lite Berkeley Software Distribution, and most commercial Unix
+systems.
+
+(2) The line beginning with `#!' lists the full file name of an
+interpreter to run and an optional initial command-line argument to
+pass to that interpreter. The operating system then runs the
+interpreter with the given argument and the full argument list of the
+executed program. The first argument in the list is the full file name
+of the `awk' program. The rest of the argument list contains either
+options to `awk', or data files, or both.
+
+\1f
+File: gawk.info, Node: Comments, Next: Quoting, Prev: Executable Scripts, Up: Running gawk
+
+1.1.6 Comments in `awk' Programs
+--------------------------------
+
+A "comment" is some text that is included in a program for the sake of
+human readers; it is not really an executable part of the program.
+Comments can explain what the program does and how it works. Nearly all
+programming languages have provisions for comments, as programs are
+typically hard to understand without them.
+
+In the `awk' language, a comment starts with the sharp sign character
+(`#') and continues to the end of the line. The `#' does not have to
+be the first character on the line. The `awk' language ignores the rest
+of a line following a sharp sign. For example, we could have put the
+following into `advice':
+
+ # This program prints a nice friendly message. It helps
+ # keep novice users from being afraid of the computer.
+ BEGIN { print "Don't Panic!" }
+
+You can put comment lines into keyboard-composed throwaway `awk'
+programs, but this usually isn't very useful; the purpose of a comment
+is to help you or another person understand the program when reading it
+at a later time.
+
+*Caution:* As mentioned in *Note One-shot::, you can enclose small to
+medium programs in single quotes, in order to keep your shell scripts
+self-contained. When doing so, _don't_ put an apostrophe (i.e., a
+single quote) into a comment (or anywhere else in your program). The
+shell interprets the quote as the closing quote for the entire program.
+As a result, usually the shell prints a message about mismatched
+quotes, and if `awk' actually runs, it will probably print strange
+messages about syntax errors. For example, look at the following:
+
+ $ awk '{ print "hello" } # let's be cute'
+ >
+
+The shell sees that the first two quotes match, and that a new quoted
+object begins at the end of the command line. It therefore prompts
+with the secondary prompt, waiting for more input. With Unix `awk',
+closing the quoted string produces this result:
+
+ $ awk '{ print "hello" } # let's be cute'
+ > '
+ error--> awk: can't open file be
+ error--> source line number 1
+
+Putting a backslash before the single quote in `let's' wouldn't help,
+since backslashes are not special inside single quotes. The next
+node describes the shell's quoting rules.
+
+\1f
+File: gawk.info, Node: Quoting, Prev: Comments, Up: Running gawk
+
+1.1.7 Shell-Quoting Issues
+--------------------------
+
+For short to medium length `awk' programs, it is most convenient to
+enter the program on the `awk' command line. This is best done by
+enclosing the entire program in single quotes. This is true whether
+you are entering the program interactively at the shell prompt, or
+writing it as part of a larger shell script:
+
+ awk 'PROGRAM TEXT' INPUT-FILE1 INPUT-FILE2 ...
+
+Once you are working with the shell, it is helpful to have a basic
+knowledge of shell quoting rules. The following rules apply only to
+POSIX-compliant, Bourne-style shells (such as `bash', the GNU
+Bourne-Again Shell). If you use `csh', you're on your own.
+
+ * Quoted items can be concatenated with nonquoted items as well as
+ with other quoted items. The shell turns everything into one
+ argument for the command.
+
+ * Preceding any single character with a backslash (`\') quotes that
+ character. The shell removes the backslash and passes the quoted
+ character on to the command.
+
+ * Single quotes protect everything between the opening and closing
+ quotes. The shell does no interpretation of the quoted text,
+ passing it on verbatim to the command. It is _impossible_ to
+ embed a single quote inside single-quoted text. Refer back to
+ *Note Comments::, for an example of what happens if you try.
+
+ * Double quotes protect most things between the opening and closing
+ quotes. The shell does at least variable and command substitution
+ on the quoted text. Different shells may do additional kinds of
+ processing on double-quoted text.
+
+ Since certain characters within double-quoted text are processed
+ by the shell, they must be "escaped" within the text. Of note are
+ the characters `$', ``', `\', and `"', all of which must be
+ preceded by a backslash within double-quoted text if they are to
+ be passed on literally to the program. (The leading backslash is
+ stripped first.) Thus, the example seen in *Note Read Terminal::,
+ is applicable:
+
+ $ awk "BEGIN { print \"Don't Panic!\" }"
+ -| Don't Panic!
+
+ Note that the single quote is not special within double quotes.
+
+ * Null strings are removed when they occur as part of a non-null
+ command-line argument, while explicit non-null objects are kept.
+ For example, to specify that the field separator `FS' should be
+ set to the null string, use:
+
+ awk -F "" 'PROGRAM' FILES # correct
+
+ Don't use this:
+
+ awk -F"" 'PROGRAM' FILES # wrong!
+
+ In the second case, `awk' will attempt to use the text of the
+ program as the value of `FS', and the first file name as the text
+ of the program! This results in syntax errors at best, and
+ confusing behavior at worst.
+
+Mixing single and double quotes is difficult. You have to resort to
+shell quoting tricks, like this:
+
+ $ awk 'BEGIN { print "Here is a single quote <'"'"'>" }'
+ -| Here is a single quote <'>
+
+This program consists of three concatenated quoted strings. The first
+and the third are single-quoted, the second is double-quoted.
+
+This can be "simplified" to:
+
+ $ awk 'BEGIN { print "Here is a single quote <'\''>" }'
+ -| Here is a single quote <'>
+
+Judge for yourself which of these two is the more readable.
+
+Another option is to use double quotes, escaping the embedded,
+`awk'-level double quotes:
+
+ $ awk "BEGIN { print \"Here is a single quote <'>\" }"
+ -| Here is a single quote <'>
+
+This option is also painful, because double quotes, backslashes, and
+dollar signs are very common in `awk' programs.
+
+A third option is to use the octal escape sequence equivalents for the
+single- and double-quote characters, like so:
+
+ $ awk 'BEGIN { print "Here is a single quote <\47>" }'
+ -| Here is a single quote <'>
+ $ awk 'BEGIN { print "Here is a double quote <\42>" }'
+ -| Here is a double quote <">
+
+This works nicely, except that you should comment clearly what the
+escapes mean.
+
+A fourth option is to use command-line variable assignment, like this:
+
+ $ awk -v sq="'" 'BEGIN { print "Here is a single quote <" sq ">" }'
+ -| Here is a single quote <'>
+
+If you really need both single and double quotes in your `awk' program,
+it is probably best to move it into a separate file, where the shell
+won't be part of the picture, and you can say what you mean.
+
+\1f
+File: gawk.info, Node: Sample Data Files, Next: Very Simple, Prev: Running gawk, Up: Getting Started
+
+1.2 Data Files for the Examples
+===============================
+
+Many of the examples in this Info file take their input from two sample
+data files. The first, `BBS-list', represents a list of computer
+bulletin board systems together with information about those systems.
+The second data file, called `inventory-shipped', contains information
+about monthly shipments. In both files, each line is considered to be
+one "record".
+
+In the data file `BBS-list', each record contains the name of a computer
+bulletin board, its phone number, the board's baud rate(s), and a code
+for the number of hours it is operational. An `A' in the last column
+means the board operates 24 hours a day. A `B' in the last column
+means the board only operates on evening and weekend hours. A `C'
+means the board operates only on weekends:
+
+ aardvark 555-5553 1200/300 B
+ alpo-net 555-3412 2400/1200/300 A
+ barfly 555-7685 1200/300 A
+ bites 555-1675 2400/1200/300 A
+ camelot 555-0542 300 C
+ core 555-2912 1200/300 C
+ fooey 555-1234 2400/1200/300 B
+ foot 555-6699 1200/300 B
+ macfoo 555-6480 1200/300 A
+ sdace 555-3430 2400/1200/300 A
+ sabafoo 555-2127 1200/300 C
+
+The data file `inventory-shipped' represents information about
+shipments during the year. Each record contains the month, the number
+of green crates shipped, the number of red boxes shipped, the number of
+orange bags shipped, and the number of blue packages shipped,
+respectively. There are 16 entries, covering the 12 months of last year
+and the first four months of the current year.
+
+ 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
+
+If you are reading this in GNU Emacs using Info, you can copy the
+regions of text showing these sample files into your own test files.
+This way you can try out the examples shown in the remainder of this
+document. You do this by using the command `M-x write-region' to copy
+text from the Info file into a file for use with `awk' (*Note
+Miscellaneous File Operations: (emacs)Misc File Ops, for more
+information). Using this information, create your own `BBS-list' and
+`inventory-shipped' files and practice what you learn in this Info file.
+
+If you are using the stand-alone version of Info, see *Note Extract
+Program::, for an `awk' program that extracts these data files from
+`gawk.texi', the Texinfo source file for this Info file.
+
+\1f
+File: gawk.info, Node: Very Simple, Next: Two Rules, Prev: Sample Data Files, Up: Getting Started
+
+1.3 Some Simple Examples
+========================
+
+The following command runs a simple `awk' program that searches the
+input file `BBS-list' for the character string `foo' (a grouping of
+characters is usually called a "string"; the term "string" is based on
+similar usage in English, such as "a string of pearls," or "a string of
+cars in a train"):
+
+ awk '/foo/ { print $0 }' BBS-list
+
+When lines containing `foo' are found, they are printed because
+`print $0' means print the current line. (Just `print' by itself means
+the same thing, so we could have written that instead.)
+
+You will notice that slashes (`/') surround the string `foo' in the
+`awk' program. The slashes indicate that `foo' is the pattern to
+search for. This type of pattern is called a "regular expression",
+which is covered in more detail later (*note Regexp::). The pattern is
+allowed to match parts of words. There are single quotes around the
+`awk' program so that the shell won't interpret any of it as special
+shell characters.
+
+Here is what this program prints:
+
+ $ awk '/foo/ { print $0 }' BBS-list
+ -| fooey 555-1234 2400/1200/300 B
+ -| foot 555-6699 1200/300 B
+ -| macfoo 555-6480 1200/300 A
+ -| sabafoo 555-2127 1200/300 C
+
+In an `awk' rule, either the pattern or the action can be omitted, but
+not both. If the pattern is omitted, then the action is performed for
+_every_ input line. If the action is omitted, the default action is to
+print all lines that match the pattern.
+
+Thus, we could leave out the action (the `print' statement and the curly
+braces) in the previous example and the result would be the same: all
+lines matching the pattern `foo' are printed. By comparison, omitting
+the `print' statement but retaining the curly braces makes an empty
+action that does nothing (i.e., no lines are printed).
+
+Many practical `awk' programs are just a line or two. Following is a
+collection of useful, short programs to get you started. Some of these
+programs contain constructs that haven't been covered yet. (The
+description of the program will give you a good idea of what is going
+on, but please read the rest of the Info file to become an `awk'
+expert!) Most of the examples use a data file named `data'. This is
+just a placeholder; if you use these programs yourself, substitute your
+own file names for `data'. For future reference, note that there is
+often more than one way to do things in `awk'. At some point, you may
+want to look back at these examples and see if you can come up with
+different ways to do the same things shown here:
+
+ * Print the length of the longest input line:
+
+ awk '{ if (length($0) > max) max = length($0) }
+ END { print max }' data
+
+ * Print every line that is longer than 80 characters:
+
+ awk 'length($0) > 80' data
+
+ The sole rule has a relational expression as its pattern and it
+ has no action--so the default action, printing the record, is used.
+
+ * Print the length of the longest line in `data':
+
+ expand data | awk '{ if (x < length()) x = length() }
+ END { print "maximum line length is " x }'
+
+ The input is processed by the `expand' utility to change tabs into
+ spaces, so the widths compared are actually the right-margin
+ columns.
+
+ * Print every line that has at least one field:
+
+ awk 'NF > 0' data
+
+ This is an easy way to delete blank lines from a file (or rather,
+ to create a new file similar to the old file but from which the
+ blank lines have been removed).
+
+ * Print seven random numbers from 0 to 100, inclusive:
+
+ awk 'BEGIN { for (i = 1; i <= 7; i++)
+ print int(101 * rand()) }'
+
+ * Print the total number of bytes used by FILES:
+
+ ls -l FILES | awk '{ x += $5 }
+ END { print "total bytes: " x }'
+
+ * Print the total number of kilobytes used by FILES:
+
+ ls -l FILES | awk '{ x += $5 }
+ END { print "total K-bytes: " (x + 1023)/1024 }'
+
+ * Print a sorted list of the login names of all users:
+
+ awk -F: '{ print $1 }' /etc/passwd | sort
+
+ * Count the lines in a file:
+
+ awk 'END { print NR }' data
+
+ * Print the even-numbered lines in the data file:
+
+ awk 'NR % 2 == 0' data
+
+ If you use the expression `NR % 2 == 1' instead, the program would
+ print the odd-numbered lines.
+
+\1f
+File: gawk.info, Node: Two Rules, Next: More Complex, Prev: Very Simple, Up: Getting Started
+
+1.4 An Example with Two Rules
+=============================
+
+The `awk' utility reads the input files one line at a time. For each
+line, `awk' tries the patterns of each of the rules. If several
+patterns match, then several actions are run in the order in which they
+appear in the `awk' program. If no patterns match, then no actions are
+run.
+
+After processing all the rules that match the line (and perhaps there
+are none), `awk' reads the next line. (However, *note Next Statement::,
+and also *note Nextfile Statement::). This continues until the program
+reaches the end of the file. For example, the following `awk' program
+contains two rules:
+
+ /12/ { print $0 }
+ /21/ { print $0 }
+
+The first rule has the string `12' as the pattern and `print $0' as the
+action. The second rule has the string `21' as the pattern and also
+has `print $0' as the action. Each rule's action is enclosed in its
+own pair of braces.
+
+This program prints every line that contains the string `12' _or_ the
+string `21'. If a line contains both strings, it is printed twice,
+once by each rule.
+
+This is what happens if we run this program on our two sample data
+files, `BBS-list' and `inventory-shipped':
+
+ $ awk '/12/ { print $0 }
+ > /21/ { print $0 }' BBS-list inventory-shipped
+ -| aardvark 555-5553 1200/300 B
+ -| alpo-net 555-3412 2400/1200/300 A
+ -| barfly 555-7685 1200/300 A
+ -| bites 555-1675 2400/1200/300 A
+ -| core 555-2912 1200/300 C
+ -| fooey 555-1234 2400/1200/300 B
+ -| foot 555-6699 1200/300 B
+ -| macfoo 555-6480 1200/300 A
+ -| sdace 555-3430 2400/1200/300 A
+ -| sabafoo 555-2127 1200/300 C
+ -| sabafoo 555-2127 1200/300 C
+ -| Jan 21 36 64 620
+ -| Apr 21 70 74 514
+
+Note how the line beginning with `sabafoo' in `BBS-list' was printed
+twice, once for each rule.
+
+\1f
+File: gawk.info, Node: More Complex, Next: Statements/Lines, Prev: Two Rules, Up: Getting Started
+
+1.5 A More Complex Example
+==========================
+
+Now that we've mastered some simple tasks, let's look at what typical
+`awk' programs do. This example shows how `awk' can be used to
+summarize, select, and rearrange the output of another utility. It uses
+features that haven't been covered yet, so don't worry if you don't
+understand all the details:
+
+ ls -l | awk '$6 == "Nov" { sum += $5 }
+ END { print sum }'
+
+This command prints the total number of bytes in all the files in the
+current directory that were last modified in November (of any year).
+(1) The `ls -l' part of this example is a system command that gives you
+a listing of the files in a directory, including each file's size and
+the date the file was last modified. Its output looks like this:
+
+ -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
+
+The first field contains read-write permissions, the second field
+contains the number of links to the file, and the third field
+identifies the owner of the file. The fourth field identifies the group
+of the file. The fifth field contains the size of the file in bytes.
+The sixth, seventh, and eighth fields contain the month, day, and time,
+respectively, that the file was last modified. Finally, the ninth field
+contains the name of the file.(2)
+
+The `$6 == "Nov"' in our `awk' program is an expression that tests
+whether the sixth field of the output from `ls -l' matches the string
+`Nov'. Each time a line has the string `Nov' for its sixth field, the
+action `sum += $5' is performed. This adds the fifth field (the file's
+size) to the variable `sum'. As a result, when `awk' has finished
+reading all the input lines, `sum' is the total of the sizes of the
+files whose lines matched the pattern. (This works because `awk'
+variables are automatically initialized to zero.)
+
+After the last line of output from `ls' has been processed, the `END'
+rule executes and prints the value of `sum'. In this example, the
+value of `sum' is 80600.
+
+These more advanced `awk' techniques are covered in later sections
+(*note Action Overview::). Before you can move on to more advanced
+`awk' programming, you have to know how `awk' interprets your input and
+displays your output. By manipulating fields and using `print'
+statements, you can produce some very useful and impressive-looking
+reports.
+
+---------- Footnotes ----------
+
+(1) In the C shell (`csh'), you need to type a semicolon and then a
+backslash at the end of the first line; see *Note Statements/Lines::,
+for an explanation. In a POSIX-compliant shell, such as the Bourne
+shell or `bash', you can type the example as shown. If the command
+`echo $path' produces an empty output line, you are most likely using a
+POSIX-compliant shell. Otherwise, you are probably using the C shell
+or a shell derived from it.
+
+(2) On some very old systems, you may need to use `ls -lg' to get this
+output.
+
+\1f
+File: gawk.info, Node: Statements/Lines, Next: Other Features, Prev: More Complex, Up: Getting Started
+
+1.6 `awk' Statements Versus Lines
+=================================
+
+Most often, each line in an `awk' program is a separate statement or
+separate rule, like this:
+
+ awk '/12/ { print $0 }
+ /21/ { print $0 }' BBS-list inventory-shipped
+
+However, `gawk' ignores newlines after any of the following symbols and
+keywords:
+
+ , { ? : || && do else
+
+A newline at any other point is considered the end of the statement.(1)
+
+If you would like to split a single statement into two lines at a point
+where a newline would terminate it, you can "continue" it by ending the
+first line with a backslash character (`\'). The backslash must be the
+final character on the line in order to be recognized as a continuation
+character. A backslash is allowed anywhere in the statement, even in
+the middle of a string or regular expression. For example:
+
+ awk '/This regular expression is too long, so continue it\
+ on the next line/ { print $1 }'
+
+We have generally not used backslash continuation in the sample programs
+in this Info file. In `gawk', there is no limit on the length of a
+line, so backslash continuation is never strictly necessary; it just
+makes programs more readable. For this same reason, as well as for
+clarity, we have kept most statements short in the sample programs
+presented throughout the Info file. Backslash continuation is most
+useful when your `awk' program is in a separate source file instead of
+entered from the command line. You should also note that many `awk'
+implementations are more particular about where you may use backslash
+continuation. For example, they may not allow you to split a string
+constant using backslash continuation. Thus, for maximum portability
+of your `awk' programs, it is best not to split your lines in the
+middle of a regular expression or a string.
+
+*Caution:* _Backslash continuation does not work as described with the
+C shell._ It works for `awk' programs in files and for one-shot
+programs, _provided_ you are using a POSIX-compliant shell, such as the
+Unix Bourne shell or `bash'. But the C shell behaves differently!
+There, you must use two backslashes in a row, followed by a newline.
+Note also that when using the C shell, _every_ newline in your awk
+program must be escaped with a backslash. To illustrate:
+
+ % awk 'BEGIN { \
+ ? print \\
+ ? "hello, world" \
+ ? }'
+ -| hello, world
+
+Here, the `%' and `?' are the C shell's primary and secondary prompts,
+analogous to the standard shell's `$' and `>'.
+
+Compare the previous example to how it is done with a POSIX-compliant
+shell:
+
+ $ awk 'BEGIN {
+ > print \
+ > "hello, world"
+ > }'
+ -| hello, world
+
+`awk' is a line-oriented language. Each rule's action has to begin on
+the same line as the pattern. To have the pattern and action on
+separate lines, you _must_ use backslash continuation; there is no
+other option.
+
+Another thing to keep in mind is that backslash continuation and
+comments do not mix. As soon as `awk' sees the `#' that starts a
+comment, it ignores _everything_ on the rest of the line. For example:
+
+ $ gawk 'BEGIN { print "dont panic" # a friendly \
+ > BEGIN rule
+ > }'
+ error--> gawk: cmd. line:2: BEGIN rule
+ error--> gawk: cmd. line:2: ^ parse error
+
+In this case, it looks like the backslash would continue the comment
+onto the next line. However, the backslash-newline combination is never
+even noticed because it is "hidden" inside the comment. Thus, the
+`BEGIN' is noted as a syntax error.
+
+When `awk' statements within one rule are short, you might want to put
+more than one of them on a line. This is accomplished by separating
+the statements with a semicolon (`;'). This also applies to the rules
+themselves. Thus, the program shown at the start of this minor node
+could also be written this way:
+
+ /12/ { print $0 } ; /21/ { print $0 }
+
+ NOTE: The requirement that states that rules on the same line must
+ be separated with a semicolon was not in the original `awk'
+ language; it was added for consistency with the treatment of
+ statements within an action.
+
+---------- Footnotes ----------
+
+(1) The `?' and `:' referred to here is the three-operand conditional
+expression described in *Note Conditional Exp::. Splitting lines after
+`?' and `:' is a minor `gawk' extension; if `--posix' is specified
+(*note Options::), then this extension is disabled.
+
+\1f
+File: gawk.info, Node: Other Features, Next: When, Prev: Statements/Lines, Up: Getting Started
+
+1.7 Other Features of `awk'
+===========================
+
+The `awk' language provides a number of predefined, or "built-in",
+variables that your programs can use to get information from `awk'.
+There are other variables your program can set as well to control how
+`awk' processes your data.
+
+In addition, `awk' provides a number of built-in functions for doing
+common computational and string-related operations. `gawk' provides
+built-in functions for working with timestamps, performing bit
+manipulation, and for runtime string translation.
+
+As we develop our presentation of the `awk' language, we introduce most
+of the variables and many of the functions. They are defined
+systematically in *Note Built-in Variables::, and *Note Built-in::.
+
+\1f
+File: gawk.info, Node: When, Prev: Other Features, Up: Getting Started
+
+1.8 When to Use `awk'
+=====================
+
+Now that you've seen some of what `awk' can do, you might wonder how
+`awk' could be useful for you. By using utility programs, advanced
+patterns, field separators, arithmetic statements, and other selection
+criteria, you can produce much more complex output. The `awk' language
+is very useful for producing reports from large amounts of raw data,
+such as summarizing information from the output of other utility
+programs like `ls'. (*Note More Complex::.)
+
+Programs written with `awk' are usually much smaller than they would be
+in other languages. This makes `awk' programs easy to compose and use.
+Often, `awk' programs can be quickly composed at your terminal, used
+once, and thrown away. Because `awk' programs are interpreted, you can
+avoid the (usually lengthy) compilation part of the typical
+edit-compile-test-debug cycle of software development.
+
+Complex programs have been written in `awk', including a complete
+retargetable assembler for eight-bit microprocessors (*note Glossary::,
+for more information), and a microcode assembler for a special-purpose
+Prolog computer. More recently, `gawk' was used for writing a Wiki
+clone.(1) While the original `awk''s capabilities were strained by tasks
+of such complexity, modern versions are more capable. Even the Bell
+Labs version of `awk' has fewer predefined limits, and those that it
+has are much larger than they used to be.
+
+If you find yourself writing `awk' scripts of more than, say, a few
+hundred lines, you might consider using a different programming
+language. Emacs Lisp is a good choice if you need sophisticated string
+or pattern matching capabilities. The shell is also good at string and
+pattern matching; in addition, it allows powerful use of the system
+utilities. More conventional languages, such as C, C++, and Java, offer
+better facilities for system programming and for managing the complexity
+of large programs. Programs in these languages may require more lines
+of source code than the equivalent `awk' programs, but they are easier
+to maintain and usually run more efficiently.
+
+---------- Footnotes ----------
+
+(1) Yet Another Wiki Clone
+(http://www.awk-scripting.de/cgi/wiki.cgi/yawk/).
+
+\1f
+File: gawk.info, Node: Regexp, Next: Reading Files, Prev: Getting Started, Up: Top
+
+2 Regular Expressions
+*********************
+
+A "regular expression", or "regexp", is a way of describing a set of
+strings. Because regular expressions are such a fundamental part of
+`awk' programming, their format and use deserve a separate major node.
+
+A regular expression enclosed in slashes (`/') is an `awk' pattern that
+matches every input record whose text belongs to that set. The
+simplest regular expression is a sequence of letters, numbers, or both.
+Such a regexp matches any string that contains that sequence. Thus,
+the regexp `foo' matches any string containing `foo'. Therefore, the
+pattern `/foo/' matches any input record containing the three
+characters `foo' _anywhere_ in the record. Other kinds of regexps let
+you specify more complicated classes of strings.
+
+* Menu:
+
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Character Lists:: What can go between `[...]'.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* Locales:: How the locale affects things.
+
+\1f
+File: gawk.info, Node: Regexp Usage, Next: Escape Sequences, Up: Regexp
+
+2.1 How to Use Regular Expressions
+==================================
+
+A regular expression can be used as a pattern by enclosing it in
+slashes. Then the regular expression is tested against the entire text
+of each record. (Normally, it only needs to match some part of the
+text in order to succeed.) For example, the following prints the
+second field of each record that contains the string `foo' anywhere in
+it:
+
+ $ awk '/foo/ { print $2 }' BBS-list
+ -| 555-1234
+ -| 555-6699
+ -| 555-6480
+ -| 555-2127
+
+`~' (tilde), `~' operator Regular expressions can also be used in
+matching expressions. These expressions allow you to specify the
+string to match against; it need not be the entire current input
+record. The two operators `~' and `!~' perform regular expression
+comparisons. Expressions using these operators can be used as
+patterns, or in `if', `while', `for', and `do' statements. (*Note
+Statements::.) For example:
+
+ EXP ~ /REGEXP/
+
+is true if the expression EXP (taken as a string) matches REGEXP. The
+following example matches, or selects, all input records with the
+uppercase letter `J' somewhere in the first field:
+
+ $ awk '$1 ~ /J/' inventory-shipped
+ -| Jan 13 25 15 115
+ -| Jun 31 42 75 492
+ -| Jul 24 34 67 436
+ -| Jan 21 36 64 620
+
+So does this:
+
+ awk '{ if ($1 ~ /J/) print }' inventory-shipped
+
+This next example is true if the expression EXP (taken as a character
+string) does _not_ match REGEXP:
+
+ EXP !~ /REGEXP/
+
+The following example matches, or selects, all input records whose
+first field _does not_ contain the uppercase letter `J':
+
+ $ awk '$1 !~ /J/' inventory-shipped
+ -| Feb 15 32 24 226
+ -| Mar 15 24 34 228
+ -| Apr 31 52 63 420
+ -| May 16 34 29 208
+ ...
+
+When a regexp is enclosed in slashes, such as `/foo/', we call it a
+"regexp constant", much like `5.27' is a numeric constant and `"foo"'
+is a string constant.
+
+\1f
+File: gawk.info, Node: Escape Sequences, Next: Regexp Operators, Prev: Regexp Usage, Up: Regexp
+
+2.2 Escape Sequences
+====================
+
+Some characters cannot be included literally in string constants
+(`"foo"') or regexp constants (`/foo/'). Instead, they should be
+represented with "escape sequences", which are character sequences
+beginning with a backslash (`\'). One use of an escape sequence is to
+include a double-quote character in a string constant. Because a plain
+double quote ends the string, you must use `\"' to represent an actual
+double-quote character as a part of the string. For example:
+
+ $ awk 'BEGIN { print "He said \"hi!\" to her." }'
+ -| He said "hi!" to her.
+
+The backslash character itself is another character that cannot be
+included normally; you must write `\\' to put one backslash in the
+string or regexp. Thus, the string whose contents are the two
+characters `"' and `\' must be written `"\"\\"'.
+
+Backslash also represents unprintable characters such as TAB or
+newline. While there is nothing to stop you from entering most
+unprintable characters directly in a string constant or regexp constant,
+they may look ugly.
+
+The following table lists all the escape sequences used in `awk' and
+what they represent. Unless noted otherwise, all these escape sequences
+apply to both string constants and regexp constants:
+
+`\\'
+ A literal backslash, `\'.
+
+`\a'
+ The "alert" character, `Ctrl-g', ASCII code 7 (BEL). (This
+ usually makes some sort of audible noise.)
+
+`\b'
+ Backspace, `Ctrl-h', ASCII code 8 (BS).
+
+`\f'
+ Formfeed, `Ctrl-l', ASCII code 12 (FF).
+
+`\n'
+ Newline, `Ctrl-j', ASCII code 10 (LF).
+
+`\r'
+ Carriage return, `Ctrl-m', ASCII code 13 (CR).
+
+`\t'
+ Horizontal TAB, `Ctrl-i', ASCII code 9 (HT).
+
+`\v'
+ Vertical tab, `Ctrl-k', ASCII code 11 (VT).
+
+`\NNN'
+ The octal value NNN, where NNN stands for 1 to 3 digits between
+ `0' and `7'. For example, the code for the ASCII ESC (escape)
+ character is `\033'.
+
+`\xHH...'
+ The hexadecimal value HH, where HH stands for a sequence of
+ hexadecimal digits (`0'-`9', and either `A'-`F' or `a'-`f'). Like
+ the same construct in ISO C, the escape sequence continues until
+ the first nonhexadecimal digit is seen. However, using more than
+ two hexadecimal digits produces undefined results. (The `\x'
+ escape sequence is not allowed in POSIX `awk'.)
+
+`\/'
+ A literal slash (necessary for regexp constants only). This
+ expression is used when you want to write a regexp constant that
+ contains a slash. Because the regexp is delimited by slashes, you
+ need to escape the slash that is part of the pattern, in order to
+ tell `awk' to keep processing the rest of the regexp.
+
+`\"'
+ A literal double quote (necessary for string constants only).
+ This expression is used when you want to write a string constant
+ that contains a double quote. Because the string is delimited by
+ double quotes, you need to escape the quote that is part of the
+ string, in order to tell `awk' to keep processing the rest of the
+ string.
+
+In `gawk', a number of additional two-character sequences that begin
+with a backslash have special meaning in regexps. *Note GNU Regexp
+Operators::.
+
+In a regexp, a backslash before any character that is not in the
+previous list and not listed in *Note GNU Regexp Operators::, means
+that the next character should be taken literally, even if it would
+normally be a regexp operator. For example, `/a\+b/' matches the three
+characters `a+b'.
+
+For complete portability, do not use a backslash before any character
+not shown in the previous list.
+
+To summarize:
+
+ * The escape sequences in the table above are always processed first,
+ for both string constants and regexp constants. This happens very
+ early, as soon as `awk' reads your program.
+
+ * `gawk' processes both regexp constants and dynamic regexps (*note
+ Computed Regexps::), for the special operators listed in *Note GNU
+ Regexp Operators::.
+
+ * A backslash before any other character means to treat that
+ character literally.
+
+Advanced Notes: Backslash Before Regular Characters
+---------------------------------------------------
+
+If you place a backslash in a string constant before something that is
+not one of the characters previously listed, POSIX `awk' purposely
+leaves what happens as undefined. There are two choices:
+
+Strip the backslash out
+ This is what Unix `awk' and `gawk' both do. For example, `"a\qc"'
+ is the same as `"aqc"'. (Because this is such an easy bug both to
+ introduce and to miss, `gawk' warns you about it.) Consider `FS =
+ "[ \t]+\|[ \t]+"' to use vertical bars surrounded by whitespace as
+ the field separator. There should be two backslashes in the string
+ `FS = "[ \t]+\\|[ \t]+"'.)
+
+Leave the backslash alone
+ Some other `awk' implementations do this. In such
+ implementations, typing `"a\qc"' is the same as typing `"a\\qc"'.
+
+Advanced Notes: Escape Sequences for Metacharacters
+---------------------------------------------------
+
+Suppose you use an octal or hexadecimal escape to represent a regexp
+metacharacter. (See *Note Regexp Operators::.) Does `awk' treat the
+character as a literal character or as a regexp operator?
+
+Historically, such characters were taken literally. (d.c.) However,
+the POSIX standard indicates that they should be treated as real
+metacharacters, which is what `gawk' does. In compatibility mode
+(*note Options::), `gawk' treats the characters represented by octal
+and hexadecimal escape sequences literally when used in regexp
+constants. Thus, `/a\52b/' is equivalent to `/a\*b/'.
+
+\1f
+File: gawk.info, Node: Regexp Operators, Next: Character Lists, Prev: Escape Sequences, Up: Regexp
+
+2.3 Regular Expression Operators
+================================
+
+You can combine regular expressions with special characters, called
+"regular expression operators" or "metacharacters", to increase the
+power and versatility of regular expressions.
+
+The escape sequences described in *Note Escape Sequences::, are valid
+inside a regexp. They are introduced by a `\' and are recognized and
+converted into corresponding real characters as the very first step in
+processing regexps.
+
+Here is a list of metacharacters. All characters that are not escape
+sequences and that are not listed in the table stand for themselves:
+
+`\'
+ This is used to suppress the special meaning of a character when
+ matching. For example, `\$' matches the character `$'.
+
+`^'
+ This matches the beginning of a string. For example, `^@chapter'
+ matches `@chapter' at the beginning of a string and can be used to
+ identify chapter beginnings in Texinfo source files. The `^' is
+ known as an "anchor", because it anchors the pattern to match only
+ at the beginning of the string.
+
+ It is important to realize that `^' does not match the beginning of
+ a line embedded in a string. The condition is not true in the
+ following example:
+
+ if ("line1\nLINE 2" ~ /^L/) ...
+
+`$'
+ This is similar to `^', but it matches only at the end of a string.
+ For example, `p$' matches a record that ends with a `p'. The `$'
+ is an anchor and does not match the end of a line embedded in a
+ string. The condition in the following example is not true:
+
+ if ("line1\nLINE 2" ~ /1$/) ...
+
+`.'
+ This matches any single character, _including_ the newline
+ character. For example, `.P' matches any single character
+ followed by a `P' in a string. Using concatenation, we can make a
+ regular expression such as `U.A', which matches any
+ three-character sequence that begins with `U' and ends with `A'.
+
+ In strict POSIX mode (*note Options::), `.' does not match the NUL
+ character, which is a character with all bits equal to zero.
+ Otherwise, NUL is just another character. Other versions of `awk'
+ may not be able to match the NUL character.
+
+`[...]'
+ This is called a "character list".(1) It matches any _one_ of the
+ characters that are enclosed in the square brackets. For example,
+ `[MVX]' matches any one of the characters `M', `V', or `X' in a
+ string. A full discussion of what can be inside the square
+ brackets of a character list is given in *Note Character Lists::.
+
+`[^ ...]'
+ This is a "complemented character list". The first character after
+ the `[' _must_ be a `^'. It matches any characters _except_ those
+ in the square brackets. For example, `[^awk]' matches any
+ character that is not an `a', `w', or `k'.
+
+`|'
+ This is the "alternation operator" and it is used to specify
+ alternatives. The `|' has the lowest precedence of all the regular
+ expression operators. For example, `^P|[[:digit:]]' matches any
+ string that matches either `^P' or `[[:digit:]]'. This means it
+ matches any string that starts with `P' or contains a digit.
+
+ The alternation applies to the largest possible regexps on either
+ side.
+
+`(...)'
+ Parentheses are used for grouping in regular expressions, as in
+ arithmetic. They can be used to concatenate regular expressions
+ containing the alternation operator, `|'. For example,
+ `@(samp|code)\{[^}]+\}' matches both `@code{foo}' and `@samp{bar}'.
+ (These are Texinfo formatting control sequences. The `+' is
+ explained further on in this list.)
+
+`*'
+ This symbol means that the preceding regular expression should be
+ repeated as many times as necessary to find a match. For example,
+ `ph*' applies the `*' symbol to the preceding `h' and looks for
+ matches of one `p' followed by any number of `h's. This also
+ matches just `p' if no `h's are present.
+
+ The `*' repeats the _smallest_ possible preceding expression.
+ (Use parentheses if you want to repeat a larger expression.) It
+ finds as many repetitions as possible. For example, `awk
+ '/\(c[ad][ad]*r x\)/ { print }' sample' prints every record in
+ `sample' containing a string of the form `(car x)', `(cdr x)',
+ `(cadr x)', and so on. Notice the escaping of the parentheses by
+ preceding them with backslashes.
+
+`+'
+ This symbol is similar to `*', except that the preceding
+ expression must be matched at least once. This means that `wh+y'
+ would match `why' and `whhy', but not `wy', whereas `wh*y' would
+ match all three of these strings. The following is a simpler way
+ of writing the last `*' example:
+
+ awk '/\(c[ad]+r x\)/ { print }' sample
+
+`?'
+ This symbol is similar to `*', except that the preceding
+ expression can be matched either once or not at all. For example,
+ `fe?d' matches `fed' and `fd', but nothing else.
+
+`{N}'
+`{N,}'
+`{N,M}'
+ One or two numbers inside braces denote an "interval expression".
+ If there is one number in the braces, the preceding regexp is
+ repeated N times. If there are two numbers separated by a comma,
+ the preceding regexp is repeated N to M times. If there is one
+ number followed by a comma, then the preceding regexp is repeated
+ at least N times:
+
+ `wh{3}y'
+ Matches `whhhy', but not `why' or `whhhhy'.
+
+ `wh{3,5}y'
+ Matches `whhhy', `whhhhy', or `whhhhhy', only.
+
+ `wh{2,}y'
+ Matches `whhy' or `whhhy', and so on.
+
+ Interval expressions were not traditionally available in `awk'.
+ They were added as part of the POSIX standard to make `awk' and
+ `egrep' consistent with each other.
+
+ However, because old programs may use `{' and `}' in regexp
+ constants, by default `gawk' does _not_ match interval expressions
+ in regexps. If either `--posix' or `--re-interval' are specified
+ (*note Options::), then interval expressions are allowed in
+ regexps.
+
+ For new programs that use `{' and `}' in regexp constants, it is
+ good practice to always escape them with a backslash. Then the
+ regexp constants are valid and work the way you want them to, using
+ any version of `awk'.(2)
+
+In regular expressions, the `*', `+', and `?' operators, as well as the
+braces `{' and `}', have the highest precedence, followed by
+concatenation, and finally by `|'. As in arithmetic, parentheses can
+change how operators are grouped.
+
+In POSIX `awk' and `gawk', the `*', `+', and `?' operators stand for
+themselves when there is nothing in the regexp that precedes them. For
+example, `/+/' matches a literal plus sign. However, many other
+versions of `awk' treat such a usage as a syntax error.
+
+If `gawk' is in compatibility mode (*note Options::), POSIX character
+classes and interval expressions are not available in regular
+expressions.
+
+---------- Footnotes ----------
+
+(1) In other literature, you may see a character list referred to as
+either a "character set", a "character class", or a "bracket
+expression".
+
+(2) Use two backslashes if you're using a string constant with a regexp
+operator or function.
+
+\1f
+File: gawk.info, Node: Character Lists, Next: GNU Regexp Operators, Prev: Regexp Operators, Up: Regexp
+
+2.4 Using Character Lists
+=========================
+
+Within a character list, a "range expression" consists of two
+characters separated by a hyphen. It matches any single character that
+sorts between the two characters, using the locale's collating sequence
+and character set. For example, in the default C locale, `[a-dx-z]' is
+equivalent to `[abcdxyz]'. Many locales sort characters in dictionary
+order, and in these locales, `[a-dx-z]' is typically not equivalent to
+`[abcdxyz]'; instead it might be equivalent to `[aBbCcDdxXyYz]', for
+example. To obtain the traditional interpretation of bracket
+expressions, you can use the C locale by setting the `LC_ALL'
+environment variable to the value `C'.
+
+To include one of the characters `\', `]', `-', or `^' in a character
+list, put a `\' in front of it. For example:
+
+ [d\]]
+
+matches either `d' or `]'.
+
+This treatment of `\' in character lists is compatible with other `awk'
+implementations and is also mandated by POSIX. The regular expressions
+in `awk' are a superset of the POSIX specification for Extended Regular
+Expressions (EREs). POSIX EREs are based on the regular expressions
+accepted by the traditional `egrep' utility.
+
+"Character classes" are a new feature introduced in the POSIX standard.
+A character class is a special notation for describing lists of
+characters that have a specific attribute, but the actual characters
+can vary from country to country and/or from character set to character
+set. For example, the notion of what is an alphabetic character
+differs between the United States and France.
+
+A character class is only valid in a regexp _inside_ the brackets of a
+character list. Character classes consist of `[:', a keyword denoting
+the class, and `:]'. *Note table-char-classes:: lists the character
+classes defined by the POSIX standard.
+
+Class Meaning
+--------------------------------------------------------------------------
+`[:alnum:]' Alphanumeric characters.
+--------------------------------------------------------------------------
+`[:alpha:]' Alphabetic characters.
+--------------------------------------------------------------------------
+`[:blank:]' Space and TAB characters.
+--------------------------------------------------------------------------
+`[:cntrl:]' Control characters.
+--------------------------------------------------------------------------
+`[:digit:]' Numeric characters.
+--------------------------------------------------------------------------
+`[:graph:]' Characters that are both printable and visible. (A space is
+ printable but not visible, whereas an `a' is both.)
+--------------------------------------------------------------------------
+`[:lower:]' Lowercase alphabetic characters.
+--------------------------------------------------------------------------
+`[:print:]' Printable characters (characters that are not control
+ characters).
+--------------------------------------------------------------------------
+`[:punct:]' Punctuation characters (characters that are not letters,
+ digits, control characters, or space characters).
+--------------------------------------------------------------------------
+`[:space:]' Space characters (such as space, TAB, and formfeed, to name
+ a few).
+--------------------------------------------------------------------------
+`[:upper:]' Uppercase alphabetic characters.
+--------------------------------------------------------------------------
+`[:xdigit:]'Characters that are hexadecimal digits.
+--------------------------------------------------------------------------
+
+Table 2.1: POSIX Character Classes
+
+ For example, before the POSIX standard, you had to write
+`/[A-Za-z0-9]/' to match alphanumeric characters. If your character
+set had other alphabetic characters in it, this would not match them,
+and if your character set collated differently from ASCII, this might
+not even match the ASCII alphanumeric characters. With the POSIX
+character classes, you can write `/[[:alnum:]]/' to match the alphabetic
+and numeric characters in your character set.
+
+ Two additional special sequences can appear in character lists.
+These apply to non-ASCII character sets, which can have single symbols
+(called "collating elements") that are represented with more than one
+character. They can also have several characters that are equivalent for
+"collating", or sorting, purposes. (For example, in French, a plain "e"
+and a grave-accented "e`" are equivalent.) These sequences are:
+
+Collating symbols
+ Multicharacter collating elements enclosed between `[.' and `.]'.
+ For example, if `ch' is a collating element, then `[[.ch.]]' is a
+ regexp that matches this collating element, whereas `[ch]' is a
+ regexp that matches either `c' or `h'.
+
+Equivalence classes
+ Locale-specific names for a list of characters that are equal. The
+ name is enclosed between `[=' and `=]'. For example, the name `e'
+ might be used to represent all of "e," "e`," and "e'." In this
+ case, `[[=e=]]' is a regexp that matches any of `e', `e'', or `e`'.
+
+ These features are very valuable in non-English-speaking locales.
+
+ *Caution:* The library functions that `gawk' uses for regular
+expression matching currently recognize only POSIX character classes;
+they do not recognize collating symbols or equivalence classes.
+
+\1f
+File: gawk.info, Node: GNU Regexp Operators, Next: Case-sensitivity, Prev: Character Lists, Up: Regexp
+
+2.5 `gawk'-Specific Regexp Operators
+====================================
+
+GNU software that deals with regular expressions provides a number of
+additional regexp operators. These operators are described in this
+minor node and are specific to `gawk'; they are not available in other
+`awk' implementations. Most of the additional operators deal with word
+matching. For our purposes, a "word" is a sequence of one or more
+letters, digits, or underscores (`_'):
+
+`\w'
+ Matches any word-constituent character--that is, it matches any
+ letter, digit, or underscore. Think of it as shorthand for
+ `[[:alnum:]_]'.
+
+`\W'
+ Matches any character that is not word-constituent. Think of it
+ as shorthand for `[^[:alnum:]_]'.
+
+`\<'
+ Matches the empty string at the beginning of a word. For example,
+ `/\<away/' matches `away' but not `stowaway'.
+
+`\>'
+ Matches the empty string at the end of a word. For example,
+ `/stow\>/' matches `stow' but not `stowaway'.
+
+`\y'
+ Matches the empty string at either the beginning or the end of a
+ word (i.e., the word boundar*y*). For example, `\yballs?\y'
+ matches either `ball' or `balls', as a separate word.
+
+`\B'
+ Matches the empty string that occurs between two word-constituent
+ characters. For example, `/\Brat\B/' matches `crate' but it does
+ not match `dirty rat'. `\B' is essentially the opposite of `\y'.
+
+ There are two other operators that work on buffers. In Emacs, a
+"buffer" is, naturally, an Emacs buffer. For other programs, `gawk''s
+regexp library routines consider the entire string to match as the
+buffer. The operators are:
+
+`\`'
+ Matches the empty string at the beginning of a buffer (string).
+
+`\''
+ Matches the empty string at the end of a buffer (string).
+
+ Because `^' and `$' always work in terms of the beginning and end of
+strings, these operators don't add any new capabilities for `awk'.
+They are provided for compatibility with other GNU software.
+
+ In other GNU software, the word-boundary operator is `\b'. However,
+that conflicts with the `awk' language's definition of `\b' as
+backspace, so `gawk' uses a different letter. An alternative method
+would have been to require two backslashes in the GNU operators, but
+this was deemed too confusing. The current method of using `\y' for the
+GNU `\b' appears to be the lesser of two evils.
+
+ The various command-line options (*note Options::) control how
+`gawk' interprets characters in regexps:
+
+No options
+ In the default case, `gawk' provides all the facilities of POSIX
+ regexps and the GNU regexp operators described in *Note Regexp
+ Operators::. However, interval expressions are not supported.
+
+`--posix'
+ Only POSIX regexps are supported; the GNU operators are not special
+ (e.g., `\w' matches a literal `w'). Interval expressions are
+ allowed.
+
+`--traditional'
+ Traditional Unix `awk' regexps are matched. The GNU operators are
+ not special, interval expressions are not available, nor are the
+ POSIX character classes (`[[:alnum:]]', etc.). Characters
+ described by octal and hexadecimal escape sequences are treated
+ literally, even if they represent regexp metacharacters.
+
+`--re-interval'
+ Allow interval expressions in regexps, even if `--traditional' has
+ been provided. (`--posix' automatically enables interval
+ expressions, so `--re-interval' is redundant when `--posix' is is
+ used.)
+
+\1f
+File: gawk.info, Node: Case-sensitivity, Next: Leftmost Longest, Prev: GNU Regexp Operators, Up: Regexp
+
+2.6 Case Sensitivity in Matching
+================================
+
+Case is normally significant in regular expressions, both when matching
+ordinary characters (i.e., not metacharacters) and inside character
+sets. Thus, a `w' in a regular expression matches only a lowercase `w'
+and not an uppercase `W'.
+
+ The simplest way to do a case-independent match is to use a character
+list--for example, `[Ww]'. However, this can be cumbersome if you need
+to use it often, and it can make the regular expressions harder to
+read. There are two alternatives that you might prefer.
+
+ One way to perform a case-insensitive match at a particular point in
+the program is to convert the data to a single case, using the
+`tolower' or `toupper' built-in string functions (which we haven't
+discussed yet; *note String Functions::). For example:
+
+ tolower($1) ~ /foo/ { ... }
+
+converts the first field to lowercase before matching against it. This
+works in any POSIX-compliant `awk'.
+
+Another method, specific to `gawk', is to set the variable `IGNORECASE'
+to a nonzero value (*note Built-in Variables::). When `IGNORECASE' is
+not zero, _all_ regexp and string operations ignore case. Changing the
+value of `IGNORECASE' dynamically controls the case-sensitivity of the
+program as it runs. Case is significant by default because
+`IGNORECASE' (like most variables) is initialized to zero:
+
+ x = "aB"
+ if (x ~ /ab/) ... # this test will fail
+
+ IGNORECASE = 1
+ if (x ~ /ab/) ... # now it will succeed
+
+In general, you cannot use `IGNORECASE' to make certain rules
+case-insensitive and other rules case-sensitive, because there is no
+straightforward way to set `IGNORECASE' just for the pattern of a
+particular rule.(1) To do this, use either character lists or
+`tolower'. However, one thing you can do with `IGNORECASE' only is
+dynamically turn case-sensitivity on or off for all the rules at once.
+
+`IGNORECASE' can be set on the command line or in a `BEGIN' rule (*note
+Other Arguments::; also *note Using BEGIN/END::). Setting `IGNORECASE'
+from the command line is a way to make a program case-insensitive
+without having to edit it.
+
+Prior to `gawk' 3.0, the value of `IGNORECASE' affected regexp
+operations only. It did not affect string comparison with `==', `!=',
+and so on. Beginning with version 3.0, both regexp and string
+comparison operations are also affected by `IGNORECASE'.
+
+Beginning with `gawk' 3.0, the equivalences between upper- and
+lowercase characters are based on the ISO-8859-1 (ISO Latin-1)
+character set. This character set is a superset of the traditional 128
+ASCII characters, which also provides a number of characters suitable
+for use with European languages.
+
+As of `gawk' 3.1.4, the case equivalencies are fully locale-aware.
+They are based on the C `<ctype.h>' facilities, such as `isalpha()' and
+`toupper()'.
+
+The value of `IGNORECASE' has no effect if `gawk' is in compatibility
+mode (*note Options::). Case is always significant in compatibility
+mode.
+
+---------- Footnotes ----------
+
+(1) Experienced C and C++ programmers will note that it is possible,
+using something like `IGNORECASE = 1 && /foObAr/ { ... }' and
+`IGNORECASE = 0 || /foobar/ { ... }'. However, this is somewhat
+obscure and we don't recommend it.
+
+\1f
+File: gawk.info, Node: Leftmost Longest, Next: Computed Regexps, Prev: Case-sensitivity, Up: Regexp
+
+2.7 How Much Text Matches?
+==========================
+
+Consider the following:
+
+ echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
+
+This example uses the `sub' function (which we haven't discussed yet;
+*note String Functions::) to make a change to the input record. Here,
+the regexp `/a+/' indicates "one or more `a' characters," and the
+replacement text is `<A>'.
+
+The input contains four `a' characters. `awk' (and POSIX) regular
+expressions always match the leftmost, _longest_ sequence of input
+characters that can match. Thus, all four `a' characters are replaced
+with `<A>' in this example:
+
+ $ echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
+ -| <A>bcd
+
+For simple match/no-match tests, this is not so important. But when
+doing text matching and substitutions with the `match', `sub', `gsub',
+and `gensub' functions, it is very important. *Note String Functions::,
+for more information on these functions. Understanding this principle
+is also important for regexp-based record and field splitting (*note
+Records::, and also *note Field Separators::).
+
+\1f
+File: gawk.info, Node: Computed Regexps, Next: Locales, Prev: Leftmost Longest, Up: Regexp
+
+2.8 Using Dynamic Regexps
+=========================
+
+The righthand side of a `~' or `!~' operator need not be a regexp
+constant (i.e., a string of characters between slashes). It may be any
+expression. The expression is evaluated and converted to a string if
+necessary; the contents of the string are used as the regexp. A regexp
+that is computed in this way is called a "dynamic regexp":
+
+ BEGIN { digits_regexp = "[[:digit:]]+" }
+ $0 ~ digits_regexp { print }
+
+This sets `digits_regexp' to a regexp that describes one or more digits,
+and tests whether the input record matches this regexp.
+
+*Caution:* When using the `~' and `!~' operators, there is a difference
+between a regexp constant enclosed in slashes and a string constant
+enclosed in double quotes. If you are going to use a string constant,
+you have to understand that the string is, in essence, scanned _twice_:
+the first time when `awk' reads your program, and the second time when
+it goes to match the string on the lefthand side of the operator with
+the pattern on the right. This is true of any string-valued expression
+(such as `digits_regexp', shown previously), not just string constants.
+
+What difference does it make if the string is scanned twice? The answer
+has to do with escape sequences, and particularly with backslashes. To
+get a backslash into a regular expression inside a string, you have to
+type two backslashes.
+
+For example, `/\*/' is a regexp constant for a literal `*'. Only one
+backslash is needed. To do the same thing with a string, you have to
+type `"\\*"'. The first backslash escapes the second one so that the
+string actually contains the two characters `\' and `*'.
+
+Given that you can use both regexp and string constants to describe
+regular expressions, which should you use? The answer is "regexp
+constants," for several reasons:
+
+ * String constants are more complicated to write and more difficult
+ to read. Using regexp constants makes your programs less
+ error-prone. Not understanding the difference between the two
+ kinds of constants is a common source of errors.
+
+ * It is more efficient to use regexp constants. `awk' can note that
+ you have supplied a regexp and store it internally in a form that
+ makes pattern matching more efficient. When using a string
+ constant, `awk' must first convert the string into this internal
+ form and then perform the pattern matching.
+
+ * Using regexp constants is better form; it shows clearly that you
+ intend a regexp match.
+
+Advanced Notes: Using `\n' in Character Lists of Dynamic Regexps
+----------------------------------------------------------------
+
+Some commercial versions of `awk' do not allow the newline character to
+be used inside a character list for a dynamic regexp:
+
+ $ awk '$0 ~ "[ \t\n]"'
+ error--> awk: newline in character class [
+ error--> ]...
+ error--> source line number 1
+ error--> context is
+ error--> >>> <<<
+
+But a newline in a regexp constant works with no problem:
+
+ $ awk '$0 ~ /[ \t\n]/'
+ here is a sample line
+ -| here is a sample line
+ Ctrl-d
+
+`gawk' does not have this problem, and it isn't likely to occur often
+in practice, but it's worth noting for future reference.
+
+\1f
+File: gawk.info, Node: Locales, Prev: Computed Regexps, Up: Regexp
+
+2.9 Where You Are Makes A Difference
+====================================
+
+Modern systems support the notion of "locales": a way to tell the
+system about the local character set and language. The current locale
+setting can affect the way regexp matching works, often in surprising
+ways. In particular, many locales do case-insensitive matching, even
+when you may have specified characters of only one particular case.
+
+The following example uses the `sub' function, which does text
+replacement (*note String Functions::). Here, the intent is to remove
+trailing uppercase characters:
+
+ $ echo something1234abc | gawk '{ sub("[A-Z]*$", ""); print }'
+ -| something1234
+
+This output is unexpected, since the `abc' at the end of
+`something1234abc' should not normally match `[A-Z]*'. This result is
+due to the locale setting (and thus you may not see it on your system).
+There are two fixes. The first is to use the POSIX character class
+`[[:upper:]]', instead of `[A-Z]'. The second is to change the locale
+setting in the environment, before running `gawk', by using the shell
+statements:
+
+ LANG=C LC_ALL=C
+ export LANG LC_ALL
+
+The setting `C' forces `gawk' to behave in the traditional Unix manner,
+where case distinctions do matter. You may wish to put these
+statements into your shell startup file, e.g., `$HOME/.profile'.
+
+Similar considerations apply to other ranges. For example, `["-/]' is
+perfectly valid in ASCII, but is not valid in many Unicode locales,
+such as `en_US.UTF-8'. (In general, such ranges should be avoided;
+either list the characters individually, or use a POSIX character class
+such as `[[:punct:]]'.)
+
+For the normal case of `RS = "\n"', the locale is largely irrelevant.
+For other single byte record separators, using `LC_ALL=C' will give you
+much better performance when reading records. Otherwise, `gawk' has to
+make several function calls, _per input character_ to find the record
+terminator.
+
+\1f
+File: gawk.info, Node: Reading Files, Next: Printing, Prev: Regexp, Up: Top
+
+3 Reading Input Files
+*********************
+
+In the typical `awk' program, all input is read either from the
+standard input (by default, this is the keyboard, but often it is a
+pipe from another command) or from files whose names you specify on the
+`awk' command line. If you specify input files, `awk' reads them in
+order, processing all the data from one before going on to the next.
+The name of the current input file can be found in the built-in variable
+`FILENAME' (*note Built-in Variables::).
+
+The input is read in units called "records", and is processed by the
+rules of your program one record at a time. By default, each record is
+one line. Each record is automatically split into chunks called
+"fields". This makes it more convenient for programs to work on the
+parts of a record.
+
+On rare occasions, you may need to use the `getline' command. The
+`getline' command is valuable, both because it can do explicit input
+from any number of files, and because the files used with it do not
+have to be named on the `awk' command line (*note Getline::).
+
+* Menu:
+
+* Records:: Controlling how data is split into records.
+* Fields:: An introduction to fields.
+* Nonconstant Fields:: Nonconstant Field Numbers.
+* Changing Fields:: Changing the Contents of a Field.
+* Field Separators:: The field separator and how to change it.
+* Constant Size:: Reading constant width data.
+* Multiple Line:: Reading multi-line records.
+* Getline:: Reading files under explicit program control
+ using the `getline' function.
+
+\1f
+File: gawk.info, Node: Records, Next: Fields, Up: Reading Files
+
+3.1 How Input Is Split into Records
+===================================
+
+The `awk' utility divides the input for your `awk' program into records
+and fields. `awk' keeps track of the number of records that have been
+read so far from the current input file. This value is stored in a
+built-in variable called `FNR'. It is reset to zero when a new file is
+started. Another built-in variable, `NR', is the total number of input
+records read so far from all data files. It starts at zero, but is
+never automatically reset to zero.
+
+Records are separated by a character called the "record separator". By
+default, the record separator is the newline character. This is why
+records are, by default, single lines. A different character can be
+used for the record separator by assigning the character to the
+built-in variable `RS'.
+
+Like any other variable, the value of `RS' can be changed in the `awk'
+program with the assignment operator, `=' (*note Assignment Ops::).
+The new record-separator character should be enclosed in quotation
+marks, which indicate a string constant. Often the right time to do
+this is at the beginning of execution, before any input is processed,
+so that the very first record is read with the proper separator. To do
+this, use the special `BEGIN' pattern (*note BEGIN/END::). For example:
+
+ awk 'BEGIN { RS = "/" }
+ { print $0 }' BBS-list
+
+changes the value of `RS' to `"/"', before reading any input. This is
+a string whose first character is a slash; as a result, records are
+separated by slashes. Then the input file is read, and the second rule
+in the `awk' program (the action with no pattern) prints each record.
+Because each `print' statement adds a newline at the end of its output,
+this `awk' program copies the input with each slash changed to a
+newline. Here are the results of running the program on `BBS-list':
+
+ $ awk 'BEGIN { RS = "/" }
+ > { print $0 }' BBS-list
+ -| aardvark 555-5553 1200
+ -| 300 B
+ -| alpo-net 555-3412 2400
+ -| 1200
+ -| 300 A
+ -| barfly 555-7685 1200
+ -| 300 A
+ -| bites 555-1675 2400
+ -| 1200
+ -| 300 A
+ -| camelot 555-0542 300 C
+ -| core 555-2912 1200
+ -| 300 C
+ -| fooey 555-1234 2400
+ -| 1200
+ -| 300 B
+ -| foot 555-6699 1200
+ -| 300 B
+ -| macfoo 555-6480 1200
+ -| 300 A
+ -| sdace 555-3430 2400
+ -| 1200
+ -| 300 A
+ -| sabafoo 555-2127 1200
+ -| 300 C
+ -|
+
+Note that the entry for the `camelot' BBS is not split. In the
+original data file (*note Sample Data Files::), the line looks like
+this:
+
+ camelot 555-0542 300 C
+
+It has one baud rate only, so there are no slashes in the record,
+unlike the others which have two or more baud rates. In fact, this
+record is treated as part of the record for the `core' BBS; the newline
+separating them in the output is the original newline in the data file,
+not the one added by `awk' when it printed the record!
+
+Another way to change the record separator is on the command line,
+using the variable-assignment feature (*note Other Arguments::):
+
+ awk '{ print $0 }' RS="/" BBS-list
+
+This sets `RS' to `/' before processing `BBS-list'.
+
+Using an unusual character such as `/' for the record separator
+produces correct behavior in the vast majority of cases. However, the
+following (extreme) pipeline prints a surprising `1':
+
+ $ echo | awk 'BEGIN { RS = "a" } ; { print NF }'
+ -| 1
+
+There is one field, consisting of a newline. The value of the built-in
+variable `NF' is the number of fields in the current record.
+
+Reaching the end of an input file terminates the current input record,
+even if the last character in the file is not the character in `RS'.
+(d.c.)
+
+The empty string `""' (a string without any characters) has a special
+meaning as the value of `RS'. It means that records are separated by
+one or more blank lines and nothing else. *Note Multiple Line::, for
+more details.
+
+If you change the value of `RS' in the middle of an `awk' run, the new
+value is used to delimit subsequent records, but the record currently
+being processed, as well as records already processed, are not affected.
+
+After the end of the record has been determined, `gawk' sets the
+variable `RT' to the text in the input that matched `RS'. When using
+`gawk', the value of `RS' is not limited to a one-character string. It
+can be any regular expression (*note Regexp::). In general, each record
+ends at the next string that matches the regular expression; the next
+record starts at the end of the matching string. This general rule is
+actually at work in the usual case, where `RS' contains just a newline:
+a record ends at the beginning of the next matching string (the next
+newline in the input), and the following record starts just after the
+end of this string (at the first character of the following line). The
+newline, because it matches `RS', is not part of either record.
+
+When `RS' is a single character, `RT' contains the same single
+character. However, when `RS' is a regular expression, `RT' contains
+the actual input text that matched the regular expression.
+
+The following example illustrates both of these features. It sets `RS'
+equal to a regular expression that matches either a newline or a series
+of one or more uppercase letters with optional leading and/or trailing
+whitespace:
+
+ $ echo record 1 AAAA record 2 BBBB record 3 |
+ > gawk 'BEGIN { RS = "\n|( *[[:upper:]]+ *)" }
+ > { print "Record =", $0, "and RT =", RT }'
+ -| Record = record 1 and RT = AAAA
+ -| Record = record 2 and RT = BBBB
+ -| Record = record 3 and RT =
+ -|
+
+The final line of output has an extra blank line. This is because the
+value of `RT' is a newline, and the `print' statement supplies its own
+terminating newline. *Note Simple Sed::, for a more useful example of
+`RS' as a regexp and `RT'.
+
+If you set `RS' to a regular expression that allows optional trailing
+text, such as `RS = "abc(XYZ)?"' it is possible, due to implementation
+constraints, that `gawk' may match the leading part of the regular
+expression, but not the trailing part, particularly if the input text
+that could match the trailing part is fairly long. `gawk' attempts to
+avoid this problem, but currently, there's no guarantee that this will
+never happen.
+
+ NOTE: Remember that in `awk', the `^' and `$' anchor
+ metacharacters match the beginning and end of a _string_, and not
+ the beginning and end of a _line_. As a result, something like
+ `RS = "^[[:upper:]]"' can only match at the beginning of a file.
+ This is because `gawk' views the input file as one long string
+ that happens to contain newline characters in it. It is thus best
+ to avoid anchor characters in the value of `RS'.
+
+The use of `RS' as a regular expression and the `RT' variable are
+`gawk' extensions; they are not available in compatibility mode (*note
+Options::). In compatibility mode, only the first character of the
+value of `RS' is used to determine the end of the record.
+
+Advanced Notes: `RS = "\0"' Is Not Portable
+-------------------------------------------
+
+There are times when you might want to treat an entire data file as a
+single record. The only way to make this happen is to give `RS' a
+value that you know doesn't occur in the input file. This is hard to
+do in a general way, such that a program always works for arbitrary
+input files.
+
+You might think that for text files, the NUL character, which consists
+of a character with all bits equal to zero, is a good value to use for
+`RS' in this case:
+
+ BEGIN { RS = "\0" } # whole file becomes one record?
+
+`gawk' in fact accepts this, and uses the NUL character for the record
+separator. However, this usage is _not_ portable to other `awk'
+implementations.
+
+All other `awk' implementations(1) store strings internally as C-style
+strings. C strings use the NUL character as the string terminator. In
+effect, this means that `RS = "\0"' is the same as `RS = ""'.
+(d.c.)
+
+The best way to treat a whole file as a single record is to simply read
+the file in, one record at a time, concatenating each record onto the
+end of the previous ones.
+
+---------- Footnotes ----------
+
+(1) At least that we know about.
+
+\1f
+File: gawk.info, Node: Fields, Next: Nonconstant Fields, Prev: Records, Up: Reading Files
+
+3.2 Examining Fields
+====================
+
+When `awk' reads an input record, the record is automatically "parsed"
+or separated by the interpreter into chunks called "fields". By
+default, fields are separated by "whitespace", like words in a line.
+Whitespace in `awk' means any string of one or more spaces, tabs, or
+newlines;(1) other characters, such as formfeed, vertical tab, etc.
+that are considered whitespace by other languages, are _not_ considered
+whitespace by `awk'.
+
+The purpose of fields is to make it more convenient for you to refer to
+these pieces of the record. You don't have to use them--you can
+operate on the whole record if you want--but fields are what make
+simple `awk' programs so powerful.
+
+A dollar-sign (`$') is used to refer to a field in an `awk' program,
+followed by the number of the field you want. Thus, `$1' refers to the
+first field, `$2' to the second, and so on. (Unlike the Unix shells,
+the field numbers are not limited to single digits. `$127' is the one
+hundred twenty-seventh field in the record.) For example, suppose the
+following is a line of input:
+
+ This seems like a pretty nice example.
+
+Here the first field, or `$1', is `This', the second field, or `$2', is
+`seems', and so on. Note that the last field, `$7', is `example.'.
+Because there is no space between the `e' and the `.', the period is
+considered part of the seventh field.
+
+`NF' is a built-in variable whose value is the number of fields in the
+current record. `awk' automatically updates the value of `NF' each
+time it reads a record. No matter how many fields there are, the last
+field in a record can be represented by `$NF'. So, `$NF' is the same
+as `$7', which is `example.'. If you try to reference a field beyond
+the last one (such as `$8' when the record has only seven fields), you
+get the empty string. (If used in a numeric operation, you get zero.)
+
+The use of `$0', which looks like a reference to the "zero-th" field, is
+a special case: it represents the whole input record when you are not
+interested in specific fields. Here are some more examples:
+
+ $ awk '$1 ~ /foo/ { print $0 }' BBS-list
+ -| fooey 555-1234 2400/1200/300 B
+ -| foot 555-6699 1200/300 B
+ -| macfoo 555-6480 1200/300 A
+ -| sabafoo 555-2127 1200/300 C
+
+This example prints each record in the file `BBS-list' whose first
+field contains the string `foo'. The operator `~' is called a
+"matching operator" (*note Regexp Usage::); it tests whether a string
+(here, the field `$1') matches a given regular expression.
+
+By contrast, the following example looks for `foo' in _the entire
+record_ and prints the first field and the last field for each matching
+input record:
+
+ $ awk '/foo/ { print $1, $NF }' BBS-list
+ -| fooey B
+ -| foot B
+ -| macfoo A
+ -| sabafoo C
+
+---------- Footnotes ----------
+
+(1) In POSIX `awk', newlines are not considered whitespace for
+separating fields.
+
+\1f
+File: gawk.info, Node: Nonconstant Fields, Next: Changing Fields, Prev: Fields, Up: Reading Files
+
+3.3 Nonconstant Field Numbers
+=============================
+
+The number of a field does not need to be a constant. Any expression in
+the `awk' language can be used after a `$' to refer to a field. The
+value of the expression specifies the field number. If the value is a
+string, rather than a number, it is converted to a number. Consider
+this example:
+
+ awk '{ print $NR }'
+
+Recall that `NR' is the number of records read so far: one in the first
+record, two in the second, etc. So this example prints the first field
+of the first record, the second field of the second record, and so on.
+For the twentieth record, field number 20 is printed; most likely, the
+record has fewer than 20 fields, so this prints a blank line. Here is
+another example of using expressions as field numbers:
+
+ awk '{ print $(2*2) }' BBS-list
+
+`awk' evaluates the expression `(2*2)' and uses its value as the number
+of the field to print. The `*' sign represents multiplication, so the
+expression `2*2' evaluates to four. The parentheses are used so that
+the multiplication is done before the `$' operation; they are necessary
+whenever there is a binary operator in the field-number expression.
+This example, then, prints the hours of operation (the fourth field)
+for every line of the file `BBS-list'. (All of the `awk' operators are
+listed, in order of decreasing precedence, in *Note Precedence::.)
+
+If the field number you compute is zero, you get the entire record.
+Thus, `$(2-2)' has the same value as `$0'. Negative field numbers are
+not allowed; trying to reference one usually terminates the program.
+(The POSIX standard does not define what happens when you reference a
+negative field number. `gawk' notices this and terminates your
+program. Other `awk' implementations may behave differently.)
+
+As mentioned in *Note Fields::, `awk' stores the current record's
+number of fields in the built-in variable `NF' (also *note Built-in
+Variables::). The expression `$NF' is not a special feature--it is the
+direct consequence of evaluating `NF' and using its value as a field
+number.
+
+\1f
+File: gawk.info, Node: Changing Fields, Next: Field Separators, Prev: Nonconstant Fields, Up: Reading Files
+
+3.4 Changing the Contents of a Field
+====================================
+
+The contents of a field, as seen by `awk', can be changed within an
+`awk' program; this changes what `awk' perceives as the current input
+record. (The actual input is untouched; `awk' _never_ modifies the
+input file.) Consider the following example and its output:
+
+ $ awk '{ nboxes = $3 ; $3 = $3 - 10
+ > print nboxes, $3 }' inventory-shipped
+ -| 25 15
+ -| 32 22
+ -| 24 14
+ ...
+
+The program first saves the original value of field three in the
+variable `nboxes'. The `-' sign represents subtraction, so this
+program reassigns field three, `$3', as the original value of field
+three minus ten: `$3 - 10'. (*Note Arithmetic Ops::.) Then it prints
+the original and new values for field three. (Someone in the warehouse
+made a consistent mistake while inventorying the red boxes.)
+
+For this to work, the text in field `$3' must make sense as a number;
+the string of characters must be converted to a number for the computer
+to do arithmetic on it. The number resulting from the subtraction is
+converted back to a string of characters that then becomes field three.
+*Note Conversion::.
+
+When the value of a field is changed (as perceived by `awk'), the text
+of the input record is recalculated to contain the new field where the
+old one was. In other words, `$0' changes to reflect the altered
+field. Thus, this program prints a copy of the input file, with 10
+subtracted from the second field of each line:
+
+ $ awk '{ $2 = $2 - 10; print $0 }' inventory-shipped
+ -| Jan 3 25 15 115
+ -| Feb 5 32 24 226
+ -| Mar 5 24 34 228
+ ...
+
+It is also possible to also assign contents to fields that are out of
+range. For example:
+
+ $ awk '{ $6 = ($5 + $4 + $3 + $2)
+ > print $6 }' inventory-shipped
+ -| 168
+ -| 297
+ -| 301
+ ...
+
+We've just created `$6', whose value is the sum of fields `$2', `$3',
+`$4', and `$5'. The `+' sign represents addition. For the file
+`inventory-shipped', `$6' represents the total number of parcels
+shipped for a particular month.
+
+Creating a new field changes `awk''s internal copy of the current input
+record, which is the value of `$0'. Thus, if you do `print $0' after
+adding a field, the record printed includes the new field, with the
+appropriate number of field separators between it and the previously
+existing fields.
+
+This recomputation affects and is affected by `NF' (the number of
+fields; *note Fields::). For example, the value of `NF' is set to the
+number of the highest field you create. The exact format of `$0' is
+also affected by a feature that has not been discussed yet: the "output
+field separator", `OFS', used to separate the fields (*note Output
+Separators::).
+
+Note, however, that merely _referencing_ an out-of-range field does
+_not_ change the value of either `$0' or `NF'. Referencing an
+out-of-range field only produces an empty string. For example:
+
+ if ($(NF+1) != "")
+ print "can't happen"
+ else
+ print "everything is normal"
+
+should print `everything is normal', because `NF+1' is certain to be
+out of range. (*Note If Statement::, for more information about
+`awk''s `if-else' statements. *Note Typing and Comparison::, for more
+information about the `!=' operator.)
+
+It is important to note that making an assignment to an existing field
+changes the value of `$0' but does not change the value of `NF', even
+when you assign the empty string to a field. For example:
+
+ $ echo a b c d | awk '{ OFS = ":"; $2 = ""
+ > print $0; print NF }'
+ -| a::c:d
+ -| 4
+
+The field is still there; it just has an empty value, denoted by the
+two colons between `a' and `c'. This example shows what happens if you
+create a new field:
+
+ $ echo a b c d | awk '{ OFS = ":"; $2 = ""; $6 = "new"
+ > print $0; print NF }'
+ -| a::c:d::new
+ -| 6
+
+The intervening field, `$5', is created with an empty value (indicated
+by the second pair of adjacent colons), and `NF' is updated with the
+value six.
+
+Decrementing `NF' throws away the values of the fields after the new
+value of `NF' and recomputes `$0'. (d.c.) Here is an example:
+
+ $ echo a b c d e f | awk '{ print "NF =", NF;
+ > NF = 3; print $0 }'
+ -| NF = 6
+ -| a b c
+
+*Caution:* Some versions of `awk' don't rebuild `$0' when `NF' is
+decremented. Caveat emptor.
+
+Finally, there are times when it is convenient to force `awk' to
+rebuild the entire record, using the current value of the fields and
+`OFS'. To do this, use the seemingly innocuous assignment:
+
+ $1 = $1 # force record to be reconstituted
+ print $0 # or whatever else with $0
+
+This forces `awk' rebuild the record. It does help to add a comment,
+as we've shown here.
+
+There is a flip side to the relationship between `$0' and the fields.
+Any assignment to `$0' causes the record to be reparsed into fields
+using the _current_ value of `FS'. This also applies to any built-in
+function that updates `$0', such as `sub' and `gsub' (*note String
+Functions::).
+
+\1f
+File: gawk.info, Node: Field Separators, Next: Constant Size, Prev: Changing Fields, Up: Reading Files
+
+3.5 Specifying How Fields Are Separated
+=======================================
+
+* Menu:
+
+* Regexp Field Splitting:: Using regexps as the field separator.
+* Single Character Fields:: Making each character a separate field.
+* Command Line Field Separator:: Setting `FS' from the command-line.
+* Field Splitting Summary:: Some final points and a summary table.
+
+The "field separator", which is either a single character or a regular
+expression, controls the way `awk' splits an input record into fields.
+`awk' scans the input record for character sequences that match the
+separator; the fields themselves are the text between the matches.
+
+In the examples that follow, we use the bullet symbol (*) to represent
+spaces in the output. If the field separator is `oo', then the
+following line:
+
+ moo goo gai pan
+
+is split into three fields: `m', `*g', and `*gai*pan'. Note the
+leading spaces in the values of the second and third fields.
+
+The field separator is represented by the built-in variable `FS'.
+Shell programmers take note: `awk' does _not_ use the name `IFS' that
+is used by the POSIX-compliant shells (such as the Unix Bourne shell,
+`sh', or `bash').
+
+The value of `FS' can be changed in the `awk' program with the
+assignment operator, `=' (*note Assignment Ops::). Often the right
+time to do this is at the beginning of execution before any input has
+been processed, so that the very first record is read with the proper
+separator. To do this, use the special `BEGIN' pattern (*note
+BEGIN/END::). For example, here we set the value of `FS' to the string
+`","':
+
+ awk 'BEGIN { FS = "," } ; { print $2 }'
+
+Given the input line:
+
+ John Q. Smith, 29 Oak St., Walamazoo, MI 42139
+
+this `awk' program extracts and prints the string `*29*Oak*St.'.
+
+Sometimes the input data contains separator characters that don't
+separate fields the way you thought they would. For instance, the
+person's name in the example we just used might have a title or suffix
+attached, such as:
+
+ John Q. Smith, LXIX, 29 Oak St., Walamazoo, MI 42139
+
+The same program would extract `*LXIX', instead of `*29*Oak*St.'. If
+you were expecting the program to print the address, you would be
+surprised. The moral is to choose your data layout and separator
+characters carefully to prevent such problems. (If the data is not in
+a form that is easy to process, perhaps you can massage it first with a
+separate `awk' program.)
+
+Fields are normally separated by whitespace sequences (spaces, tabs,
+and newlines), not by single spaces. Two spaces in a row do not
+delimit an empty field. The default value of the field separator `FS'
+is a string containing a single space, `" "'. If `awk' interpreted
+this value in the usual way, each space character would separate
+fields, so two spaces in a row would make an empty field between them.
+The reason this does not happen is that a single space as the value of
+`FS' is a special case--it is taken to specify the default manner of
+delimiting fields.
+
+If `FS' is any other single character, such as `","', then each
+occurrence of that character separates two fields. Two consecutive
+occurrences delimit an empty field. If the character occurs at the
+beginning or the end of the line, that too delimits an empty field. The
+space character is the only single character that does not follow these
+rules.
+
+\1f
+File: gawk.info, Node: Regexp Field Splitting, Next: Single Character Fields, Up: Field Separators
+
+3.5.1 Using Regular Expressions to Separate Fields
+--------------------------------------------------
+
+The previous node discussed the use of single characters or simple
+strings as the value of `FS'. More generally, the value of `FS' may be
+a string containing any regular expression. In this case, each match
+in the record for the regular expression separates fields. For
+example, the assignment:
+
+ FS = ", \t"
+
+makes every area of an input line that consists of a comma followed by a
+space and a TAB into a field separator. (`\t' is an "escape sequence"
+that stands for a TAB; *note Escape Sequences::, for the complete list
+of similar escape sequences.)
+
+For a less trivial example of a regular expression, try using single
+spaces to separate fields the way single commas are used. `FS' can be
+set to `"[ ]"' (left bracket, space, right bracket). This regular
+expression matches a single space and nothing else (*note Regexp::).
+
+There is an important difference between the two cases of `FS = " "' (a
+single space) and `FS = "[ \t\n]+"' (a regular expression matching one
+or more spaces, tabs, or newlines). For both values of `FS', fields
+are separated by "runs" (multiple adjacent occurrences) of spaces, tabs,
+and/or newlines. However, when the value of `FS' is `" "', `awk' first
+strips leading and trailing whitespace from the record and then decides
+where the fields are. For example, the following pipeline prints `b':
+
+ $ echo ' a b c d ' | awk '{ print $2 }'
+ -| b
+
+However, this pipeline prints `a' (note the extra spaces around each
+letter):
+
+ $ echo ' a b c d ' | awk 'BEGIN { FS = "[ \t\n]+" }
+ > { print $2 }'
+ -| a
+
+In this case, the first field is "null" or empty.
+
+The stripping of leading and trailing whitespace also comes into play
+whenever `$0' is recomputed. For instance, study this pipeline:
+
+ $ echo ' a b c d' | awk '{ print; $2 = $2; print }'
+ -| a b c d
+ -| a b c d
+
+The first `print' statement prints the record as it was read, with
+leading whitespace intact. The assignment to `$2' rebuilds `$0' by
+concatenating `$1' through `$NF' together, separated by the value of
+`OFS'. Because the leading whitespace was ignored when finding `$1',
+it is not part of the new `$0'. Finally, the last `print' statement
+prints the new `$0'.
+
+\1f
+File: gawk.info, Node: Single Character Fields, Next: Command Line Field Separator, Prev: Regexp Field Splitting, Up: Field Separators
+
+3.5.2 Making Each Character a Separate Field
+--------------------------------------------
+
+There are times when you may want to examine each character of a record
+separately. This can be done in `gawk' by simply assigning the null
+string (`""') to `FS'. In this case, each individual character in the
+record becomes a separate field. For example:
+
+ $ echo a b | gawk 'BEGIN { FS = "" }
+ > {
+ > for (i = 1; i <= NF; i = i + 1)
+ > print "Field", i, "is", $i
+ > }'
+ -| Field 1 is a
+ -| Field 2 is
+ -| Field 3 is b
+
+Traditionally, the behavior of `FS' equal to `""' was not defined. In
+this case, most versions of Unix `awk' simply treat the entire record
+as only having one field. (d.c.) In compatibility mode (*note
+Options::), if `FS' is the null string, then `gawk' also behaves this
+way.
+
+\1f
+File: gawk.info, Node: Command Line Field Separator, Next: Field Splitting Summary, Prev: Single Character Fields, Up: Field Separators
+
+3.5.3 Setting `FS' from the Command Line
+----------------------------------------
+
+`FS' can be set on the command line. Use the `-F' option to do so.
+For example:
+
+ awk -F, 'PROGRAM' INPUT-FILES
+
+sets `FS' to the `,' character. Notice that the option uses an
+uppercase `F' instead of a lowercase `f'. The latter option (`-f')
+specifies a file containing an `awk' program. Case is significant in
+command-line options: the `-F' and `-f' options have nothing to do with
+each other. You can use both options at the same time to set the `FS'
+variable _and_ get an `awk' program from a file.
+
+The value used for the argument to `-F' is processed in exactly the
+same way as assignments to the built-in variable `FS'. Any special
+characters in the field separator must be escaped appropriately. For
+example, to use a `\' as the field separator on the command line, you
+would have to type:
+
+ # same as FS = "\\"
+ awk -F\\\\ '...' files ...
+
+Because `\' is used for quoting in the shell, `awk' sees `-F\\'. Then
+`awk' processes the `\\' for escape characters (*note Escape
+Sequences::), finally yielding a single `\' to use for the field
+separator.
+
+As a special case, in compatibility mode (*note Options::), if the
+argument to `-F' is `t', then `FS' is set to the TAB character. If you
+type `-F\t' at the shell, without any quotes, the `\' gets deleted, so
+`awk' figures that you really want your fields to be separated with
+tabs and not `t's. Use `-v FS="t"' or `-F"[t]"' on the command line if
+you really do want to separate your fields with `t's.
+
+For example, let's use an `awk' program file called `baud.awk' that
+contains the pattern `/300/' and the action `print $1':
+
+ /300/ { print $1 }
+
+Let's also set `FS' to be the `-' character and run the program on the
+file `BBS-list'. The following command prints a list of the names of
+the bulletin boards that operate at 300 baud and the first three digits
+of their phone numbers:
+
+ $ awk -F- -f baud.awk BBS-list
+ -| aardvark 555
+ -| alpo
+ -| barfly 555
+ -| bites 555
+ -| camelot 555
+ -| core 555
+ -| fooey 555
+ -| foot 555
+ -| macfoo 555
+ -| sdace 555
+ -| sabafoo 555
+
+Note the second line of output. The second line in the original file
+looked like this:
+
+ alpo-net 555-3412 2400/1200/300 A
+
+The `-' as part of the system's name was used as the field separator,
+instead of the `-' in the phone number that was originally intended.
+This demonstrates why you have to be careful in choosing your field and
+record separators.
+
+Perhaps the most common use of a single character as the field
+separator occurs when processing the Unix system password file. On
+many Unix systems, each user has a separate entry in the system password
+file, one line per user. The information in these lines is separated
+by colons. The first field is the user's logon name and the second is
+the user's (encrypted or shadow) password. A password file entry might
+look like this:
+
+ arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/bash
+
+The following program searches the system password file and prints the
+entries for users who have no password:
+
+ awk -F: '$2 == ""' /etc/passwd
+
+\1f
+File: gawk.info, Node: Field Splitting Summary, Prev: Command Line Field Separator, Up: Field Separators
+
+3.5.4 Field-Splitting Summary
+-----------------------------
+
+It is important to remember that when you assign a string constant as
+the value of `FS', it undergoes normal `awk' string processing. For
+example, with Unix `awk' and `gawk', the assignment `FS = "\.."'
+assigns the character string `".."' to `FS' (the backslash is
+stripped). This creates a regexp meaning "fields are separated by
+occurrences of any two characters." If instead you want fields to be
+separated by a literal period followed by any single character, use `FS
+= "\\.."'.
+
+The following table summarizes how fields are split, based on the value
+of `FS' (`==' means "is equal to"):
+
+`FS == " "'
+ Fields are separated by runs of whitespace. Leading and trailing
+ whitespace are ignored. This is the default.
+
+`FS == ANY OTHER SINGLE CHARACTER'
+ Fields are separated by each occurrence of the character. Multiple
+ successive occurrences delimit empty fields, as do leading and
+ trailing occurrences. The character can even be a regexp
+ metacharacter; it does not need to be escaped.
+
+`FS == REGEXP'
+ Fields are separated by occurrences of characters that match
+ REGEXP. Leading and trailing matches of REGEXP delimit empty
+ fields.
+
+`FS == ""'
+ Each individual character in the record becomes a separate field.
+ (This is a `gawk' extension; it is not specified by the POSIX
+ standard.)
+
+Advanced Notes: Changing `FS' Does Not Affect the Fields
+--------------------------------------------------------
+
+According to the POSIX standard, `awk' is supposed to behave as if each
+record is split into fields at the time it is read. In particular,
+this means that if you change the value of `FS' after a record is read,
+the value of the fields (i.e., how they were split) should reflect the
+old value of `FS', not the new one.
+
+However, many implementations of `awk' do not work this way. Instead,
+they defer splitting the fields until a field is actually referenced.
+The fields are split using the _current_ value of `FS'! (d.c.) This
+behavior can be difficult to diagnose. The following example
+illustrates the difference between the two methods. (The `sed'(1)
+command prints just the first line of `/etc/passwd'.)
+
+ sed 1q /etc/passwd | awk '{ FS = ":" ; print $1 }'
+
+which usually prints:
+
+ root
+
+on an incorrect implementation of `awk', while `gawk' prints something
+like:
+
+ root:nSijPlPhZZwgE:0:0:Root:/:
+
+Advanced Notes: `FS' and `IGNORECASE'
+-------------------------------------
+
+The `IGNORECASE' variable (*note User-modified::) affects field
+splitting _only_ when the value of `FS' is a regexp. It has no effect
+when `FS' is a single character, even if that character is a letter.
+Thus, in the following code:
+
+ FS = "c"
+ IGNORECASE = 1
+ $0 = "aCa"
+ print $1
+
+The output is `aCa'. If you really want to split fields on an
+alphabetic character while ignoring case, use a regexp that will do it
+for you. E.g., `FS = "[c]"'. In this case, `IGNORECASE' will take
+effect.
+
+---------- Footnotes ----------
+
+(1) The `sed' utility is a "stream editor." Its behavior is also
+defined by the POSIX standard.
+
+\1f
+File: gawk.info, Node: Constant Size, Next: Multiple Line, Prev: Field Separators, Up: Reading Files
+
+3.6 Reading Fixed-Width Data
+============================
+
+(This minor node discusses an advanced feature of `awk'. If you are a
+novice `awk' user, you might want to skip it on the first reading.)
+
+`gawk' version 2.13 introduced a facility for dealing with fixed-width
+fields with no distinctive field separator. For example, data of this
+nature arises in the input for old Fortran programs where numbers are
+run together, or in the output of programs that did not anticipate the
+use of their output as input for other programs.
+
+An example of the latter is a table where all the columns are lined up
+by the use of a variable number of spaces and _empty fields are just
+spaces_. Clearly, `awk''s normal field splitting based on `FS' does
+not work well in this case. Although a portable `awk' program can use
+a series of `substr' calls on `$0' (*note String Functions::), this is
+awkward and inefficient for a large number of fields.
+
+The splitting of an input record into fixed-width fields is specified by
+assigning a string containing space-separated numbers to the built-in
+variable `FIELDWIDTHS'. Each number specifies the width of the field,
+_including_ columns between fields. If you want to ignore the columns
+between fields, you can specify the width as a separate field that is
+subsequently ignored. It is a fatal error to supply a field width that
+is not a positive number. The following data is the output of the Unix
+`w' utility. It is useful to illustrate the use of `FIELDWIDTHS':
+
+ 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
+
+The following program takes the above input, converts the idle time to
+number of seconds, and prints out the first two fields and the
+calculated idle time:
+
+ NOTE: This program uses a number of `awk' features that haven't
+ been introduced yet.
+
+ BEGIN { FIELDWIDTHS = "9 6 10 6 7 7 35" }
+ NR > 2 {
+ idle = $4
+ sub(/^ */, "", idle) # strip leading spaces
+ if (idle == "")
+ idle = 0
+ if (idle ~ /:/) {
+ split(idle, t, ":")
+ idle = t[1] * 60 + t[2]
+ }
+ if (idle ~ /days/)
+ idle *= 24 * 60 * 60
+
+ print $1, $2, idle
+ }
+
+Running the program on the data produces the following results:
+
+ hzuo ttyV0 0
+ hzang ttyV3 50
+ eklye ttyV5 0
+ dportein ttyV6 107
+ gierd ttyD3 1
+ dave ttyD4 0
+ brent ttyp0 286
+ dave ttyq4 1296000
+
+Another (possibly more practical) example of fixed-width input data is
+the input from a deck of balloting cards. In some parts of the United
+States, voters mark their choices by punching holes in computer cards.
+These cards are then processed to count the votes for any particular
+candidate or on any particular issue. Because a voter may choose not to
+vote on some issue, any column on the card may be empty. An `awk'
+program for processing such data could use the `FIELDWIDTHS' feature to
+simplify reading the data. (Of course, getting `gawk' to run on a
+system with card readers is another story!)
+
+Assigning a value to `FS' causes `gawk' to use `FS' for field splitting
+again. Use `FS = FS' to make this happen, without having to know the
+current value of `FS'. In order to tell which kind of field splitting
+is in effect, use `PROCINFO["FS"]' (*note Auto-set::). The value is
+`"FS"' if regular field splitting is being used, or it is
+`"FIELDWIDTHS"' if fixed-width field splitting is being used:
+
+ if (PROCINFO["FS"] == "FS")
+ REGULAR FIELD SPLITTING ...
+ else
+ FIXED-WIDTH FIELD SPLITTING ...
+
+This information is useful when writing a function that needs to
+temporarily change `FS' or `FIELDWIDTHS', read some records, and then
+restore the original settings (*note Passwd Functions::, for an example
+of such a function).
+
+\1f
+File: gawk.info, Node: Multiple Line, Next: Getline, Prev: Constant Size, Up: Reading Files
+
+3.7 Multiple-Line Records
+=========================
+
+In some databases, a single line cannot conveniently hold all the
+information in one entry. In such cases, you can use multiline
+records. The first step in doing this is to choose your data format.
+
+One technique is to use an unusual character or string to separate
+records. For example, you could use the formfeed character (written
+`\f' in `awk', as in C) to separate them, making each record a page of
+the file. To do this, just set the variable `RS' to `"\f"' (a string
+containing the formfeed character). Any other character could equally
+well be used, as long as it won't be part of the data in a record.
+
+Another technique is to have blank lines separate records. By a special
+dispensation, an empty string as the value of `RS' indicates that
+records are separated by one or more blank lines. When `RS' is set to
+the empty string, each record always ends at the first blank line
+encountered. The next record doesn't start until the first nonblank
+line that follows. No matter how many blank lines appear in a row, they
+all act as one record separator. (Blank lines must be completely
+empty; lines that contain only whitespace do not count.)
+
+You can achieve the same effect as `RS = ""' by assigning the string
+`"\n\n+"' to `RS'. This regexp matches the newline at the end of the
+record and one or more blank lines after the record. In addition, a
+regular expression always matches the longest possible sequence when
+there is a choice (*note Leftmost Longest::). So the next record
+doesn't start until the first nonblank line that follows--no matter how
+many blank lines appear in a row, they are considered one record
+separator.
+
+There is an important difference between `RS = ""' and `RS = "\n\n+"'.
+In the first case, leading newlines in the input data file are ignored,
+and if a file ends without extra blank lines after the last record, the
+final newline is removed from the record. In the second case, this
+special processing is not done. (d.c.)
+
+Now that the input is separated into records, the second step is to
+separate the fields in the record. One way to do this is to divide each
+of the lines into fields in the normal manner. This happens by default
+as the result of a special feature. When `RS' is set to the empty
+string, _and_ `FS' is a set to a single character, the newline
+character _always_ acts as a field separator. This is in addition to
+whatever field separations result from `FS'.(1)
+
+The original motivation for this special exception was probably to
+provide useful behavior in the default case (i.e., `FS' is equal to
+`" "'). This feature can be a problem if you really don't want the
+newline character to separate fields, because there is no way to
+prevent it. However, you can work around this by using the `split'
+function to break up the record manually (*note String Functions::).
+If you have a single character field separator, you can work around the
+special feature in a different way, by making `FS' into a regexp for
+that single character. For example, if the field separator is a
+percent character, instead of `FS = "%"', use `FS = "[%]"'.
+
+Another way to separate fields is to put each field on a separate line:
+to do this, just set the variable `FS' to the string `"\n"'. (This
+single character seperator matches a single newline.) A practical
+example of a data file organized this way might be a mailing list,
+where each entry is separated by blank lines. Consider a mailing list
+in a file named `addresses', which looks like this:
+
+ Jane Doe
+ 123 Main Street
+ Anywhere, SE 12345-6789
+
+ John Smith
+ 456 Tree-lined Avenue
+ Smallville, MW 98765-4321
+ ...
+
+A simple program to process this file is as follows:
+
+ # addrs.awk --- simple mailing list program
+
+ # Records are separated by blank lines.
+ # Each line is one field.
+ BEGIN { RS = "" ; FS = "\n" }
+
+ {
+ print "Name is:", $1
+ print "Address is:", $2
+ print "City and State are:", $3
+ print ""
+ }
+
+Running the program produces the following output:
+
+ $ awk -f addrs.awk addresses
+ -| Name is: Jane Doe
+ -| Address is: 123 Main Street
+ -| City and State are: Anywhere, SE 12345-6789
+ -|
+ -| Name is: John Smith
+ -| Address is: 456 Tree-lined Avenue
+ -| City and State are: Smallville, MW 98765-4321
+ -|
+ ...
+
+*Note Labels Program::, for a more realistic program that deals with
+address lists. The following table summarizes how records are split,
+based on the value of `RS'. (`==' means "is equal to.")
+
+`RS == "\n"'
+ Records are separated by the newline character (`\n'). In effect,
+ every line in the data file is a separate record, including blank
+ lines. This is the default.
+
+`RS == ANY SINGLE CHARACTER'
+ Records are separated by each occurrence of the character.
+ Multiple successive occurrences delimit empty records.
+
+`RS == ""'
+ Records are separated by runs of blank lines. The newline
+ character always serves as a field separator, in addition to
+ whatever value `FS' may have. Leading and trailing newlines in a
+ file are ignored.
+
+`RS == REGEXP'
+ Records are separated by occurrences of characters that match
+ REGEXP. Leading and trailing matches of REGEXP delimit empty
+ records. (This is a `gawk' extension; it is not specified by the
+ POSIX standard.)
+
+In all cases, `gawk' sets `RT' to the input text that matched the value
+specified by `RS'.
+
+---------- Footnotes ----------
+
+(1) When `FS' is the null string (`""') or a regexp, this special
+feature of `RS' does not apply. It does apply to the default field
+separator of a single space: `FS = " "'.
+
+\1f
+File: gawk.info, Node: Getline, Prev: Multiple Line, Up: Reading Files
+
+3.8 Explicit Input with `getline'
+=================================
+
+So far we have been getting our input data from `awk''s main input
+stream--either the standard input (usually your terminal, sometimes the
+output from another program) or from the files specified on the command
+line. The `awk' language has a special built-in command called
+`getline' that can be used to read input under your explicit control.
+
+The `getline' command is used in several different ways and should
+_not_ be used by beginners. The examples that follow the explanation
+of the `getline' command include material that has not been covered
+yet. Therefore, come back and study the `getline' command _after_ you
+have reviewed the rest of this Info file and have a good knowledge of
+how `awk' works.
+
+The `getline' command returns one if it finds a record and zero if it
+encounters the end of the file. If there is some error in getting a
+record, such as a file that cannot be opened, then `getline' returns
+-1. In this case, `gawk' sets the variable `ERRNO' to a string
+describing the error that occurred.
+
+In the following examples, COMMAND stands for a string value that
+represents a shell command.
+
+* Menu:
+
+* Plain Getline:: Using `getline' with no arguments.
+* Getline/Variable:: Using `getline' into a variable.
+* Getline/File:: Using `getline' from a file.
+* Getline/Variable/File:: Using `getline' into a variable from a
+ file.
+* Getline/Pipe:: Using `getline' from a pipe.
+* Getline/Variable/Pipe:: Using `getline' into a variable from a
+ pipe.
+* Getline/Coprocess:: Using `getline' from a coprocess.
+* Getline/Variable/Coprocess:: Using `getline' into a variable from a
+ coprocess.
+* Getline Notes:: Important things to know about `getline'.
+* Getline Summary:: Summary of `getline' Variants.
+
+\1f
+File: gawk.info, Node: Plain Getline, Next: Getline/Variable, Up: Getline
+
+3.8.1 Using `getline' with No Arguments
+---------------------------------------
+
+The `getline' command can be used without arguments to read input from
+the current input file. All it does in this case is read the next
+input record and split it up into fields. This is useful if you've
+finished processing the current record, but want to do some special
+processing on the next record _right now_. For example:
+
+ {
+ if ((t = index($0, "/*")) != 0) {
+ # value of `tmp' will be "" if t is 1
+ tmp = substr($0, 1, t - 1)
+ u = index(substr($0, t + 2), "*/")
+ while (u == 0) {
+ if (getline <= 0) {
+ m = "unexpected EOF or error"
+ m = (m ": " ERRNO)
+ print m > "/dev/stderr"
+ exit
+ }
+ t = -1
+ u = index($0, "*/")
+ }
+ # substr expression will be "" if */
+ # occurred at end of line
+ $0 = tmp substr($0, u + 2)
+ }
+ print $0
+ }
+
+This `awk' program deletes all C-style comments (`/* ... */') from the
+input. By replacing the `print $0' with other statements, you could
+perform more complicated processing on the decommented input, such as
+searching for matches of a regular expression. (This program has a
+subtle problem--it does not work if one comment ends and another begins
+on the same line.)
+
+This form of the `getline' command sets `NF', `NR', `FNR', and the
+value of `$0'.
+
+ NOTE: The new value of `$0' is used to test the patterns of any
+ subsequent rules. The original value of `$0' that triggered the
+ rule that executed `getline' is lost. By contrast, the `next'
+ statement reads a new record but immediately begins processing it
+ normally, starting with the first rule in the program. *Note Next
+ Statement::.
+
+\1f
+File: gawk.info, Node: Getline/Variable, Next: Getline/File, Prev: Plain Getline, Up: Getline
+
+3.8.2 Using `getline' into a Variable
+-------------------------------------
+
+You can use `getline VAR' to read the next record from `awk''s input
+into the variable VAR. No other processing is done. For example,
+suppose the next line is a comment or a special string, and you want to
+read it without triggering any rules. This form of `getline' allows
+you to read that line and store it in a variable so that the main
+read-a-line-and-check-each-rule loop of `awk' never sees it. The
+following example swaps every two lines of input:
+
+ {
+ if ((getline tmp) > 0) {
+ print tmp
+ print $0
+ } else
+ print $0
+ }
+
+It takes the following list:
+
+ wan
+ tew
+ free
+ phore
+
+and produces these results:
+
+ tew
+ wan
+ phore
+ free
+
+The `getline' command used in this way sets only the variables `NR' and
+`FNR' (and of course, VAR). The record is not split into fields, so
+the values of the fields (including `$0') and the value of `NF' do not
+change.
+
+\1f
+File: gawk.info, Node: Getline/File, Next: Getline/Variable/File, Prev: Getline/Variable, Up: Getline
+
+3.8.3 Using `getline' from a File
+---------------------------------
+
+Use `getline < FILE' to read the next record from FILE. Here FILE is a
+string-valued expression that specifies the file name. `< FILE' is
+called a "redirection" because it directs input to come from a
+different place. For example, the following program reads its input
+record from the file `secondary.input' when it encounters a first field
+with a value equal to 10 in the current input file:
+
+ {
+ if ($1 == 10) {
+ getline < "secondary.input"
+ print
+ } else
+ print
+ }
+
+Because the main input stream is not used, the values of `NR' and `FNR'
+are not changed. However, the record it reads is split into fields in
+the normal manner, so the values of `$0' and the other fields are
+changed, resulting in a new value of `NF'.
+
+According to POSIX, `getline < EXPRESSION' is ambiguous if EXPRESSION
+contains unparenthesized operators other than `$'; for example,
+`getline < dir "/" file' is ambiguous because the concatenation
+operator is not parenthesized. You should write it as `getline < (dir
+"/" file)' if you want your program to be portable to other `awk'
+implementations.
+
+\1f
+File: gawk.info, Node: Getline/Variable/File, Next: Getline/Pipe, Prev: Getline/File, Up: Getline
+
+3.8.4 Using `getline' into a Variable from a File
+-------------------------------------------------
+
+Use `getline VAR < FILE' to read input from the file FILE, and put it
+in the variable VAR. As above, FILE is a string-valued expression that
+specifies the file from which to read.
+
+In this version of `getline', none of the built-in variables are
+changed and the record is not split into fields. The only variable
+changed is VAR. For example, the following program copies all the
+input files to the output, except for records that say
+`@include FILENAME'. Such a record is replaced by the contents of the
+file FILENAME:
+
+ {
+ if (NF == 2 && $1 == "@include") {
+ while ((getline line < $2) > 0)
+ print line
+ close($2)
+ } else
+ print
+ }
+
+Note here how the name of the extra input file is not built into the
+program; it is taken directly from the data, specifically from the
+second field on the `@include' line.
+
+The `close' function is called to ensure that if two identical
+`@include' lines appear in the input, the entire specified file is
+included twice. *Note Close Files And Pipes::.
+
+One deficiency of this program is that it does not process nested
+`@include' statements (i.e., `@include' statements in included files)
+the way a true macro preprocessor would. *Note Igawk Program::, for a
+program that does handle nested `@include' statements.
+
+\1f
+File: gawk.info, Node: Getline/Pipe, Next: Getline/Variable/Pipe, Prev: Getline/Variable/File, Up: Getline
+
+3.8.5 Using `getline' from a Pipe
+---------------------------------
+
+The output of a command can also be piped into `getline', using
+`COMMAND | getline'. In this case, the string COMMAND is run as a
+shell command and its output is piped into `awk' to be used as input.
+This form of `getline' reads one record at a time from the pipe. For
+example, the following program copies its input to its output, except
+for lines that begin with `@execute', which are replaced by the output
+produced by running the rest of the line as a shell command:
+
+ {
+ if ($1 == "@execute") {
+ tmp = substr($0, 10)
+ while ((tmp | getline) > 0)
+ print
+ close(tmp)
+ } else
+ print
+ }
+
+The `close' function is called to ensure that if two identical
+`@execute' lines appear in the input, the command is run for each one.
+*Note Close Files And Pipes::. Given the input:
+
+ foo
+ bar
+ baz
+ @execute who
+ bletch
+
+the program might produce:
+
+ foo
+ bar
+ baz
+ arnold ttyv0 Jul 13 14:22
+ miriam ttyp0 Jul 13 14:23 (murphy:0)
+ bill ttyp1 Jul 13 14:23 (murphy:0)
+ bletch
+
+Notice that this program ran the command `who' and printed the previous
+result. (If you try this program yourself, you will of course get
+different results, depending upon who is logged in on your system.)
+
+This variation of `getline' splits the record into fields, sets the
+value of `NF', and recomputes the value of `$0'. The values of `NR'
+and `FNR' are not changed.
+
+According to POSIX, `EXPRESSION | getline' is ambiguous if EXPRESSION
+contains unparenthesized operators other than `$'--for example,
+`"echo " "date" | getline' is ambiguous because the concatenation
+operator is not parenthesized. You should write it as `("echo "
+"date") | getline' if you want your program to be portable to other
+`awk' implementations.
+
+\1f
+File: gawk.info, Node: Getline/Variable/Pipe, Next: Getline/Coprocess, Prev: Getline/Pipe, Up: Getline
+
+3.8.6 Using `getline' into a Variable from a Pipe
+-------------------------------------------------
+
+When you use `COMMAND | getline VAR', the output of COMMAND is sent
+through a pipe to `getline' and into the variable VAR. For example, the
+following program reads the current date and time into the variable
+`current_time', using the `date' utility, and then prints it:
+
+ BEGIN {
+ "date" | getline current_time
+ close("date")
+ print "Report printed on " current_time
+ }
+
+In this version of `getline', none of the built-in variables are
+changed and the record is not split into fields.
+
+According to POSIX, `EXPRESSION | getline VAR' is ambiguous if
+EXPRESSION contains unparenthesized operators other than `$'; for
+example, `"echo " "date" | getline VAR' is ambiguous because the
+concatenation operator is not parenthesized. You should write it as
+`("echo " "date") | getline VAR' if you want your program to be
+portable to other `awk' implementations.
+
+\1f
+File: gawk.info, Node: Getline/Coprocess, Next: Getline/Variable/Coprocess, Prev: Getline/Variable/Pipe, Up: Getline
+
+3.8.7 Using `getline' from a Coprocess
+--------------------------------------
+
+Input into `getline' from a pipe is a one-way operation. The command
+that is started with `COMMAND | getline' only sends data _to_ your
+`awk' program.
+
+On occasion, you might want to send data to another program for
+processing and then read the results back. `gawk' allows you start a
+"coprocess", with which two-way communications are possible. This is
+done with the `|&' operator. Typically, you write data to the
+coprocess first and then read results back, as shown in the following:
+
+ print "SOME QUERY" |& "db_server"
+ "db_server" |& getline
+
+which sends a query to `db_server' and then reads the results.
+
+The values of `NR' and `FNR' are not changed, because the main input
+stream is not used. However, the record is split into fields in the
+normal manner, thus changing the values of `$0', of the other fields,
+and of `NF'.
+
+Coprocesses are an advanced feature. They are discussed here only
+because this is the minor node on `getline'. *Note Two-way I/O::,
+where coprocesses are discussed in more detail.
+
+\1f
+File: gawk.info, Node: Getline/Variable/Coprocess, Next: Getline Notes, Prev: Getline/Coprocess, Up: Getline
+
+3.8.8 Using `getline' into a Variable from a Coprocess
+------------------------------------------------------
+
+When you use `COMMAND |& getline VAR', the output from the coprocess
+COMMAND is sent through a two-way pipe to `getline' and into the
+variable VAR.
+
+In this version of `getline', none of the built-in variables are
+changed and the record is not split into fields. The only variable
+changed is VAR.
+
+Coprocesses are an advanced feature. They are discussed here only
+because this is the minor node on `getline'. *Note Two-way I/O::,
+where coprocesses are discussed in more detail.
+
+\1f
+File: gawk.info, Node: Getline Notes, Next: Getline Summary, Prev: Getline/Variable/Coprocess, Up: Getline
+
+3.8.9 Points to Remember About `getline'
+----------------------------------------
+
+Here are some miscellaneous points about `getline' that you should bear
+in mind:
+
+ * When `getline' changes the value of `$0' and `NF', `awk' does
+ _not_ automatically jump to the start of the program and start
+ testing the new record against every pattern. However, the new
+ record is tested against any subsequent rules.
+
+ * Many `awk' implementations limit the number of pipelines that an
+ `awk' program may have open to just one. In `gawk', there is no
+ such limit. You can open as many pipelines (and coprocesses) as
+ the underlying operating system permits.
+
+ * An interesting side effect occurs if you use `getline' without a
+ redirection inside a `BEGIN' rule. Because an unredirected
+ `getline' reads from the command-line data files, the first
+ `getline' command causes `awk' to set the value of `FILENAME'.
+ Normally, `FILENAME' does not have a value inside `BEGIN' rules,
+ because you have not yet started to process the command-line data
+ files. (d.c.) (*Note BEGIN/END::, also *note Auto-set::.)
+
+ * Using `FILENAME' with `getline' (`getline < FILENAME') is likely
+ to be a source for confusion. `awk' opens a separate input stream
+ from the current input file. However, by not using a variable,
+ `$0' and `NR' are still updated. If you're doing this, it's
+ probably by accident, and you should reconsider what it is you're
+ trying to accomplish.
+
+\1f
+File: gawk.info, Node: Getline Summary, Prev: Getline Notes, Up: Getline
+
+3.8.10 Summary of `getline' Variants
+------------------------------------
+
+*Note table-getline-variants:: summarizes the eight variants of
+`getline', listing which built-in variables are set by each one.
+
+Variant Effect
+--------------------------------------------------------------------------
+`getline' Sets `$0', `NF', `FNR', and `NR'
+--------------------------------------------------------------------------
+`getline' VAR Sets VAR, `FNR', and `NR'
+--------------------------------------------------------------------------
+`getline <' FILE Sets `$0' and `NF'
+--------------------------------------------------------------------------
+`getline VAR < FILE' Sets VAR
+--------------------------------------------------------------------------
+COMMAND `| getline' Sets `$0' and `NF'
+--------------------------------------------------------------------------
+COMMAND `| getline' VAR Sets VAR
+--------------------------------------------------------------------------
+COMMAND `|& getline' Sets `$0' and `NF'. This is a `gawk' extension
+--------------------------------------------------------------------------
+COMMAND `|& getline' VAR Sets VAR. This is a `gawk' extension
+--------------------------------------------------------------------------
+
+Table 3.1: getline Variants and What They Set
+
+\1f
+File: gawk.info, Node: Printing, Next: Expressions, Prev: Reading Files, Up: Top
+
+4 Printing Output
+*****************
+
+One of the most common programming actions is to "print", or output,
+some or all of the input. Use the `print' statement for simple output,
+and the `printf' statement for fancier formatting. The `print'
+statement is not limited when computing _which_ values to print.
+However, with two exceptions, you cannot specify _how_ to print
+them--how many columns, whether to use exponential notation or not, and
+so on. (For the exceptions, *note Output Separators::, and *Note
+OFMT::.) For printing with specifications, you need the `printf'
+statement (*note Printf::).
+
+ Besides basic and formatted printing, this major node also covers
+I/O redirections to files and pipes, introduces the special file names
+that `gawk' processes internally, and discusses the `close' built-in
+function.
+
+* Menu:
+
+* Print:: The `print' statement.
+* Print Examples:: Simple examples of `print' statements.
+* Output Separators:: The output separators and how to change them.
+* OFMT:: Controlling Numeric Output With `print'.
+* Printf:: The `printf' statement.
+* Redirection:: How to redirect output to multiple files and
+ pipes.
+* Special Files:: File name interpretation in `gawk'.
+ `gawk' allows access to inherited file
+ descriptors.
+* Close Files And Pipes:: Closing Input and Output Files and Pipes.
+
+\1f
+File: gawk.info, Node: Print, Next: Print Examples, Up: Printing
+
+4.1 The `print' Statement
+=========================
+
+The `print' statement is used to produce output with simple,
+standardized formatting. Specify only the strings or numbers to print,
+in a list separated by commas. They are output, separated by single
+spaces, followed by a newline. The statement looks like this:
+
+ print ITEM1, ITEM2, ...
+
+The entire list of items may be optionally enclosed in parentheses. The
+parentheses are necessary if any of the item expressions uses the `>'
+relational operator; otherwise it could be confused with a redirection
+(*note Redirection::).
+
+The items to print can be constant strings or numbers, fields of the
+current record (such as `$1'), variables, or any `awk' expression.
+Numeric values are converted to strings and then printed.
+
+The simple statement `print' with no items is equivalent to `print $0':
+it prints the entire current record. To print a blank line, use `print
+""', where `""' is the empty string. To print a fixed piece of text,
+use a string constant, such as `"Don't Panic"', as one item. If you
+forget to use the double-quote characters, your text is taken as an
+`awk' expression, and you will probably get an error. Keep in mind
+that a space is printed between any two items.
+
+\1f
+File: gawk.info, Node: Print Examples, Next: Output Separators, Prev: Print, Up: Printing
+
+4.2 Examples of `print' Statements
+==================================
+
+Each `print' statement makes at least one line of output. However, it
+isn't limited to only one line. If an item value is a string that
+contains a newline, the newline is output along with the rest of the
+string. A single `print' statement can make any number of lines this
+way.
+
+The following is an example of printing a string that contains embedded
+newlines (the `\n' is an escape sequence, used to represent the newline
+character; *note Escape Sequences::):
+
+ $ awk 'BEGIN { print "line one\nline two\nline three" }'
+ -| line one
+ -| line two
+ -| line three
+
+The next example, which is run on the `inventory-shipped' file, prints
+the first two fields of each input record, with a space between them:
+
+ $ awk '{ print $1, $2 }' inventory-shipped
+ -| Jan 13
+ -| Feb 15
+ -| Mar 15
+ ...
+
+A common mistake in using the `print' statement is to omit the comma
+between two items. This often has the effect of making the items run
+together in the output, with no space. The reason for this is that
+juxtaposing two string expressions in `awk' means to concatenate them.
+Here is the same program, without the comma:
+
+ $ awk '{ print $1 $2 }' inventory-shipped
+ -| Jan13
+ -| Feb15
+ -| Mar15
+ ...
+
+To someone unfamiliar with the `inventory-shipped' file, neither
+example's output makes much sense. A heading line at the beginning
+would make it clearer. Let's add some headings to our table of months
+(`$1') and green crates shipped (`$2'). We do this using the `BEGIN'
+pattern (*note BEGIN/END::) so that the headings are only printed once:
+
+ awk 'BEGIN { print "Month Crates"
+ print "----- ------" }
+ { print $1, $2 }' inventory-shipped
+
+When run, the program prints the following:
+
+ Month Crates
+ ----- ------
+ Jan 13
+ Feb 15
+ Mar 15
+ ...
+
+The only problem, however, is that the headings and the table data
+don't line up! We can fix this by printing some spaces between the two
+fields:
+
+ awk 'BEGIN { print "Month Crates"
+ print "----- ------" }
+ { print $1, " ", $2 }' inventory-shipped
+
+Lining up columns this way can get pretty complicated when there are
+many columns to fix. Counting spaces for two or three columns is
+simple, but any more than this can take up a lot of time. This is why
+the `printf' statement was created (*note Printf::); one of its
+specialties is lining up columns of data.
+
+ NOTE: You can continue either a `print' or `printf' statement
+ simply by putting a newline after any comma (*note
+ Statements/Lines::).
+
+\1f
+File: gawk.info, Node: Output Separators, Next: OFMT, Prev: Print Examples, Up: Printing
+
+4.3 Output Separators
+=====================
+
+As mentioned previously, a `print' statement contains a list of items
+separated by commas. In the output, the items are normally separated
+by single spaces. However, this doesn't need to be the case; a single
+space is only the default. Any string of characters may be used as the
+"output field separator" by setting the built-in variable `OFS'. The
+initial value of this variable is the string `" "'--that is, a single
+space.
+
+The output from an entire `print' statement is called an "output
+record". Each `print' statement outputs one output record, and then
+outputs a string called the "output record separator" (or `ORS'). The
+initial value of `ORS' is the string `"\n"'; i.e., a newline character.
+Thus, each `print' statement normally makes a separate line.
+
+In order to change how output fields and records are separated, assign
+new values to the variables `OFS' and `ORS'. The usual place to do
+this is in the `BEGIN' rule (*note BEGIN/END::), so that it happens
+before any input is processed. It can also be done with assignments on
+the command line, before the names of the input files, or using the
+`-v' command-line option (*note Options::). The following example
+prints the first and second fields of each input record, separated by a
+semicolon, with a blank line added after each newline:
+
+ $ awk 'BEGIN { OFS = ";"; ORS = "\n\n" }
+ > { print $1, $2 }' BBS-list
+ -| aardvark;555-5553
+ -|
+ -| alpo-net;555-3412
+ -|
+ -| barfly;555-7685
+ ...
+
+If the value of `ORS' does not contain a newline, the program's output
+is run together on a single line.
+
+\1f
+File: gawk.info, Node: OFMT, Next: Printf, Prev: Output Separators, Up: Printing
+
+4.4 Controlling Numeric Output with `print'
+===========================================
+
+When the `print' statement is used to print numeric values, `awk'
+internally converts the number to a string of characters and prints
+that string. `awk' uses the `sprintf' function to do this conversion
+(*note String Functions::). For now, it suffices to say that the
+`sprintf' function accepts a "format specification" that tells it how
+to format numbers (or strings), and that there are a number of
+different ways in which numbers can be formatted. The different format
+specifications are discussed more fully in *Note Control Letters::.
+
+The built-in variable `OFMT' contains the default format specification
+that `print' uses with `sprintf' when it wants to convert a number to a
+string for printing. The default value of `OFMT' is `"%.6g"'. The way
+`print' prints numbers can be changed by supplying different format
+specifications as the value of `OFMT', as shown in the following
+example:
+
+ $ awk 'BEGIN {
+ > OFMT = "%.0f" # print numbers as integers (rounds)
+ > print 17.23, 17.54 }'
+ -| 17 18
+
+According to the POSIX standard, `awk''s behavior is undefined if
+`OFMT' contains anything but a floating-point conversion specification.
+(d.c.)
+
+\1f
+File: gawk.info, Node: Printf, Next: Redirection, Prev: OFMT, Up: Printing
+
+4.5 Using `printf' Statements for Fancier Printing
+==================================================
+
+For more precise control over the output format than what is normally
+provided by `print', use `printf'. `printf' can be used to specify the
+width to use for each item, as well as various formatting choices for
+numbers (such as what output base to use, whether to print an exponent,
+whether to print a sign, and how many digits to print after the decimal
+point). This is done by supplying a string, called the "format
+string", that controls how and where to print the other arguments.
+
+* Menu:
+
+* Basic Printf:: Syntax of the `printf' statement.
+* Control Letters:: Format-control letters.
+* Format Modifiers:: Format-specification modifiers.
+* Printf Examples:: Several examples.
+
+\1f
+File: gawk.info, Node: Basic Printf, Next: Control Letters, Up: Printf
+
+4.5.1 Introduction to the `printf' Statement
+--------------------------------------------
+
+A simple `printf' statement looks like this:
+
+ printf FORMAT, ITEM1, ITEM2, ...
+
+The entire list of arguments may optionally be enclosed in parentheses.
+The parentheses are necessary if any of the item expressions use the
+`>' relational operator; otherwise, it can be confused with a
+redirection (*note Redirection::).
+
+The difference between `printf' and `print' is the FORMAT argument.
+This is an expression whose value is taken as a string; it specifies
+how to output each of the other arguments. It is called the "format
+string".
+
+The format string is very similar to that in the ISO C library function
+`printf'. Most of FORMAT is text to output verbatim. Scattered among
+this text are "format specifiers"--one per item. Each format specifier
+says to output the next item in the argument list at that place in the
+format.
+
+The `printf' statement does not automatically append a newline to its
+output. It outputs only what the format string specifies. So if a
+newline is needed, you must include one in the format string. The
+output separator variables `OFS' and `ORS' have no effect on `printf'
+statements. For example:
+
+ $ awk 'BEGIN {
+ > ORS = "\nOUCH!\n"; OFS = "+"
+ > msg = "Dont Panic!"
+ > printf "%s\n", msg
+ > }'
+ -| Dont Panic!
+
+Here, neither the `+' nor the `OUCH' appear when the message is printed.
+
+\1f
+File: gawk.info, Node: Control Letters, Next: Format Modifiers, Prev: Basic Printf, Up: Printf
+
+4.5.2 Format-Control Letters
+----------------------------
+
+A format specifier starts with the character `%' and ends with a
+"format-control letter"--it tells the `printf' statement how to output
+one item. The format-control letter specifies what _kind_ of value to
+print. The rest of the format specifier is made up of optional
+"modifiers" that control _how_ to print the value, such as the field
+width. Here is a list of the format-control letters:
+
+`%c'
+ This prints a number as an ASCII character; thus, `printf "%c",
+ 65' outputs the letter `A'. (The output for a string value is the
+ first character of the string.)
+
+`%d, %i'
+ These are equivalent; they both print a decimal integer. (The
+ `%i' specification is for compatibility with ISO C.)
+
+`%e, %E'
+ These print a number in scientific (exponential) notation; for
+ example:
+
+ printf "%4.3e\n", 1950
+
+ prints `1.950e+03', with a total of four significant figures,
+ three of which follow the decimal point. (The `4.3' represents
+ two modifiers, discussed in the next node.) `%E' uses `E' instead
+ of `e' in the output.
+
+`%f'
+ This prints a number in floating-point notation. For example:
+
+ printf "%4.3f", 1950
+
+ prints `1950.000', with a total of four significant figures, three
+ of which follow the decimal point. (The `4.3' represents two
+ modifiers, discussed in the next node.)
+
+ On systems supporting IEEE 754 floating point format, values
+ representing negative infinity are formatted as `-inf' or
+ `-infinity', and positive infinity as `inf' and `-infinity'. The
+ special "not a number" value formats as `-nan' or `nan'.
+
+`%F'
+ Like `%f' but the infinity and "not a number" values are spelled
+ using uppercase letters.
+
+ The `%F' format is a POSIX extension to ISO C; not all systems
+ support. On those that don't, `gawk' uses `%f' instead.
+
+`%g, %G'
+ These print a number in either scientific notation or in
+ floating-point notation, whichever uses fewer characters; if the
+ result is printed in scientific notation, `%G' uses `E' instead of
+ `e'.
+
+`%o'
+ This prints an unsigned octal integer.
+
+`%s'
+ This prints a string.
+
+`%u'
+ This prints an unsigned decimal integer. (This format is of
+ marginal use, because all numbers in `awk' are floating-point; it
+ is provided primarily for compatibility with C.)
+
+`%x, %X'
+ These print an unsigned hexadecimal integer; `%X' uses the letters
+ `A' through `F' instead of `a' through `f'.
+
+`%%'
+ This isn't a format-control letter, but it does have meaning--the
+ sequence `%%' outputs one `%'; it does not consume an argument and
+ it ignores any modifiers.
+
+ NOTE: When using the integer format-control letters for values
+ that are outside the range of the widest C integer type, `gawk'
+ switches to the the `%g' format specifier. If `--lint' is provided
+ on the command line (*note Options::), `gawk' warns about this.
+ Other versions of `awk' may print invalid values or do something
+ else entirely. (d.c.)
+
+\1f
+File: gawk.info, Node: Format Modifiers, Next: Printf Examples, Prev: Control Letters, Up: Printf
+
+4.5.3 Modifiers for `printf' Formats
+------------------------------------
+
+A format specification can also include "modifiers" that can control
+how much of the item's value is printed, as well as how much space it
+gets. The modifiers come between the `%' and the format-control letter.
+We will use the bullet symbol "*" in the following examples to represent
+spaces in the output. Here are the possible modifiers, in the order in
+which they may appear:
+
+`N$'
+ An integer constant followed by a `$' is a "positional specifier".
+ Normally, format specifications are applied to arguments in the
+ order given in the format string. With a positional specifier,
+ the format specification is applied to a specific argument,
+ instead of what would be the next argument in the list.
+ Positional specifiers begin counting with one. Thus:
+
+ printf "%s %s\n", "don't", "panic"
+ printf "%2$s %1$s\n", "panic", "don't"
+
+ prints the famous friendly message twice.
+
+ At first glance, this feature doesn't seem to be of much use. It
+ is in fact a `gawk' extension, intended for use in translating
+ messages at runtime. *Note Printf Ordering::, which describes how
+ and why to use positional specifiers. For now, we will not use
+ them.
+
+`-'
+ The minus sign, used before the width modifier (see later on in
+ this table), says to left-justify the argument within its
+ specified width. Normally, the argument is printed
+ right-justified in the specified width. Thus:
+
+ printf "%-4s", "foo"
+
+ prints `foo*'.
+
+`SPACE'
+ For numeric conversions, prefix positive values with a space and
+ negative values with a minus sign.
+
+`+'
+ The plus sign, used before the width modifier (see later on in
+ this table), says to always supply a sign for numeric conversions,
+ even if the data to format is positive. The `+' overrides the
+ space modifier.
+
+`#'
+ Use an "alternate form" for certain control letters. For `%o',
+ supply a leading zero. For `%x' and `%X', supply a leading `0x'
+ or `0X' for a nonzero result. For `%e', `%E', and `%f', the
+ result always contains a decimal point. For `%g' and `%G',
+ trailing zeros are not removed from the result.
+
+`0'
+ A leading `0' (zero) acts as a flag that indicates that output
+ should be padded with zeros instead of spaces. This applies even
+ to non-numeric output formats. (d.c.) This flag only has an
+ effect when the field width is wider than the value to print.
+
+`''
+ A single quote or apostrohe character is a POSIX extension to ISO
+ C. It indicates that the integer part of a floating point value,
+ or the entire part of an integer decimal value, should have a
+ thousands-separator character in it. This only works in locales
+ that support such characters. For example:
+
+ $ cat thousands.awk Show source program
+ -| BEGIN { printf "%'d\n", 1234567 }
+ $ LC_ALL=C gawk -f thousands.awk Run it in "C" locale
+ -| 1234567
+ $ LC_ALL=en_US.UTF-8 gawk -f thousands.awk Run in US English UTF locale
+ -| 1,234,567
+
+ For more information about locales and internationalization issues,
+ see *Note Locales::.
+
+ NOTE: The `'' flag is a nice feature, but its use complicates
+ things: it now becomes difficult to use it in command-line
+ programs. For information on appropriate quoting tricks, see
+ *Note Quoting::.
+
+`WIDTH'
+ This is a number specifying the desired minimum width of a field.
+ Inserting any number between the `%' sign and the format-control
+ character forces the field to expand to this width. The default
+ way to do this is to pad with spaces on the left. For example:
+
+ printf "%4s", "foo"
+
+ prints `*foo'.
+
+ The value of WIDTH is a minimum width, not a maximum. If the item
+ value requires more than WIDTH characters, it can be as wide as
+ necessary. Thus, the following:
+
+ printf "%4s", "foobar"
+
+ prints `foobar'.
+
+ Preceding the WIDTH with a minus sign causes the output to be
+ padded with spaces on the right, instead of on the left.
+
+`.PREC'
+ A period followed by an integer constant specifies the precision
+ to use when printing. The meaning of the precision varies by
+ control letter:
+
+ `%e', `%E', `%f'
+ Number of digits to the right of the decimal point.
+
+ `%g', `%G'
+ Maximum number of significant digits.
+
+ `%d', `%i', `%o', `%u', `%x', `%X'
+ Minimum number of digits to print.
+
+ `%s'
+ Maximum number of characters from the string that should
+ print.
+
+ Thus, the following:
+
+ printf "%.4s", "foobar"
+
+ prints `foob'.
+
+The C library `printf''s dynamic WIDTH and PREC capability (for
+example, `"%*.*s"') is supported. Instead of supplying explicit WIDTH
+and/or PREC values in the format string, they are passed in the
+argument list. For example:
+
+ w = 5
+ p = 3
+ s = "abcdefg"
+ printf "%*.*s\n", w, p, s
+
+is exactly equivalent to:
+
+ s = "abcdefg"
+ printf "%5.3s\n", s
+
+Both programs output `**abc'. Earlier versions of `awk' did not
+support this capability. If you must use such a version, you may
+simulate this feature by using concatenation to build up the format
+string, like so:
+
+ w = 5
+ p = 3
+ s = "abcdefg"
+ printf "%" w "." p "s\n", s
+
+This is not particularly easy to read but it does work.
+
+C programmers may be used to supplying additional `l', `L', and `h'
+modifiers in `printf' format strings. These are not valid in `awk'.
+Most `awk' implementations silently ignore these modifiers. If
+`--lint' is provided on the command line (*note Options::), `gawk'
+warns about their use. If `--posix' is supplied, their use is a fatal
+error.
+
+\1f
+File: gawk.info, Node: Printf Examples, Prev: Format Modifiers, Up: Printf
+
+4.5.4 Examples Using `printf'
+-----------------------------
+
+The following is a simple example of how to use `printf' to make an
+aligned table:
+
+ awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list
+
+This command prints the names of the bulletin boards (`$1') in the file
+`BBS-list' as a string of 10 characters that are left-justified. It
+also prints the phone numbers (`$2') next on the line. This produces
+an aligned two-column table of names and phone numbers, as shown here:
+
+ $ awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list
+ -| aardvark 555-5553
+ -| alpo-net 555-3412
+ -| barfly 555-7685
+ -| bites 555-1675
+ -| camelot 555-0542
+ -| core 555-2912
+ -| fooey 555-1234
+ -| foot 555-6699
+ -| macfoo 555-6480
+ -| sdace 555-3430
+ -| sabafoo 555-2127
+
+In this case, the phone numbers had to be printed as strings because
+the numbers are separated by a dash. Printing the phone numbers as
+numbers would have produced just the first three digits: `555'. This
+would have been pretty confusing.
+
+It wasn't necessary to specify a width for the phone numbers because
+they are last on their lines. They don't need to have spaces after
+them.
+
+The table could be made to look even nicer by adding headings to the
+tops of the columns. This is done using the `BEGIN' pattern (*note
+BEGIN/END::) so that the headers are only printed once, at the
+beginning of the `awk' program:
+
+ awk 'BEGIN { print "Name Number"
+ print "---- ------" }
+ { printf "%-10s %s\n", $1, $2 }' BBS-list
+
+The above example mixed `print' and `printf' statements in the same
+program. Using just `printf' statements can produce the same results:
+
+ awk 'BEGIN { printf "%-10s %s\n", "Name", "Number"
+ printf "%-10s %s\n", "----", "------" }
+ { printf "%-10s %s\n", $1, $2 }' BBS-list
+
+Printing each column heading with the same format specification used
+for the column elements ensures that the headings are aligned just like
+the columns.
+
+The fact that the same format specification is used three times can be
+emphasized by storing it in a variable, like this:
+
+ awk 'BEGIN { format = "%-10s %s\n"
+ printf format, "Name", "Number"
+ printf format, "----", "------" }
+ { printf format, $1, $2 }' BBS-list
+
+At this point, it would be a worthwhile exercise to use the `printf'
+statement to line up the headings and table data for the
+`inventory-shipped' example that was covered earlier in the minor node
+on the `print' statement (*note Print::).
+
+\1f
+File: gawk.info, Node: Redirection, Next: Special Files, Prev: Printf, Up: Printing
+
+4.6 Redirecting Output of `print' and `printf'
+==============================================
+
+So far, the output from `print' and `printf' has gone to the standard
+output, usually the terminal. Both `print' and `printf' can also send
+their output to other places. This is called "redirection".
+
+A redirection appears after the `print' or `printf' statement.
+Redirections in `awk' are written just like redirections in shell
+commands, except that they are written inside the `awk' program.
+
+There are four forms of output redirection: output to a file, output
+appended to a file, output through a pipe to another command, and output
+to a coprocess. They are all shown for the `print' statement, but they
+work identically for `printf':
+
+`print ITEMS > OUTPUT-FILE'
+ This type of redirection prints the items into the output file
+ named OUTPUT-FILE. The file name OUTPUT-FILE can be any
+ expression. Its value is changed to a string and then used as a
+ file name (*note Expressions::).
+
+ When this type of redirection is used, the OUTPUT-FILE is erased
+ before the first output is written to it. Subsequent writes to
+ the same OUTPUT-FILE do not erase OUTPUT-FILE, but append to it.
+ (This is different from how you use redirections in shell scripts.)
+ If OUTPUT-FILE does not exist, it is created. For example, here
+ is how an `awk' program can write a list of BBS names to one file
+ named `name-list', and a list of phone numbers to another file
+ named `phone-list':
+
+ $ awk '{ print $2 > "phone-list"
+ > print $1 > "name-list" }' BBS-list
+ $ cat phone-list
+ -| 555-5553
+ -| 555-3412
+ ...
+ $ cat name-list
+ -| aardvark
+ -| alpo-net
+ ...
+
+ Each output file contains one name or number per line.
+
+`print ITEMS >> OUTPUT-FILE'
+ This type of redirection prints the items into the pre-existing
+ output file named OUTPUT-FILE. The difference between this and the
+ single-`>' redirection is that the old contents (if any) of
+ OUTPUT-FILE are not erased. Instead, the `awk' output is appended
+ to the file. If OUTPUT-FILE does not exist, then it is created.
+
+`print ITEMS | COMMAND'
+ It is also possible to send output to another program through a
+ pipe instead of into a file. This type of redirection opens a
+ pipe to COMMAND, and writes the values of ITEMS through this pipe
+ to another process created to execute COMMAND.
+
+ The redirection argument COMMAND is actually an `awk' expression.
+ Its value is converted to a string whose contents give the shell
+ command to be run. For example, the following produces two files,
+ one unsorted list of BBS names, and one list sorted in reverse
+ alphabetical order:
+
+ awk '{ print $1 > "names.unsorted"
+ command = "sort -r > names.sorted"
+ print $1 | command }' BBS-list
+
+ The unsorted list is written with an ordinary redirection, while
+ the sorted list is written by piping through the `sort' utility.
+
+ The next example uses redirection to mail a message to the mailing
+ list `bug-system'. This might be useful when trouble is
+ encountered in an `awk' script run periodically for system
+ maintenance:
+
+ report = "mail bug-system"
+ print "Awk script failed:", $0 | report
+ m = ("at record number " FNR " of " FILENAME)
+ print m | report
+ close(report)
+
+ The message is built using string concatenation and saved in the
+ variable `m'. It's then sent down the pipeline to the `mail'
+ program. (The parentheses group the items to concatenate--see
+ *Note Concatenation::.)
+
+ The `close' function is called here because it's a good idea to
+ close the pipe as soon as all the intended output has been sent to
+ it. *Note Close Files And Pipes::, for more information.
+
+ This example also illustrates the use of a variable to represent a
+ FILE or COMMAND--it is not necessary to always use a string
+ constant. Using a variable is generally a good idea, because
+ `awk' requires that the string value be spelled identically every
+ time.
+
+`print ITEMS |& COMMAND'
+ This type of redirection prints the items to the input of COMMAND.
+ The difference between this and the single-`|' redirection is that
+ the output from COMMAND can be read with `getline'. Thus COMMAND
+ is a "coprocess", which works together with, but subsidiary to,
+ the `awk' program.
+
+ This feature is a `gawk' extension, and is not available in POSIX
+ `awk'. *Note Two-way I/O::, for a more complete discussion.
+
+Redirecting output using `>', `>>', `|', or `|&' asks the system to
+open a file, pipe, or coprocess only if the particular FILE or COMMAND
+you specify has not already been written to by your program or if it
+has been closed since it was last written to.
+
+It is a common error to use `>' redirection for the first `print' to a
+file, and then to use `>>' for subsequent output:
+
+ # clear the file
+ print "Don't panic" > "guide.txt"
+ ...
+ # append
+ print "Avoid improbability generators" >> "guide.txt"
+
+This is indeed how redirections must be used from the shell. But in
+`awk', it isn't necessary. In this kind of case, a program should use
+`>' for all the `print' statements, since the output file is only
+opened once.
+
+Many `awk' implementations limit the number of pipelines that an `awk'
+program may have open to just one! In `gawk', there is no such limit.
+`gawk' allows a program to open as many pipelines as the underlying
+operating system permits.
+
+Advanced Notes: Piping into `sh'
+--------------------------------
+
+A particularly powerful way to use redirection is to build command lines
+and pipe them into the shell, `sh'. For example, suppose you have a
+list of files brought over from a system where all the file names are
+stored in uppercase, and you wish to rename them to have names in all
+lowercase. The following program is both simple and efficient:
+
+ { printf("mv %s %s\n", $0, tolower($0)) | "sh" }
+
+ END { close("sh") }
+
+The `tolower' function returns its argument string with all uppercase
+characters converted to lowercase (*note String Functions::). The
+program builds up a list of command lines, using the `mv' utility to
+rename the files. It then sends the list to the shell for execution.
+
+\1f
+File: gawk.info, Node: Special Files, Next: Close Files And Pipes, Prev: Redirection, Up: Printing
+
+4.7 Special File Names in `gawk'
+================================
+
+`gawk' provides a number of special file names that it interprets
+internally. These file names provide access to standard file
+descriptors, process-related information, and TCP/IP networking.
+
+* Menu:
+
+* Special FD:: Special files for I/O.
+* Special Process:: Special files for process information.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+
+\1f
+File: gawk.info, Node: Special FD, Next: Special Process, Up: Special Files
+
+4.7.1 Special Files for Standard Descriptors
+--------------------------------------------
+
+Running programs conventionally have three input and output streams
+already available to them for reading and writing. These are known as
+the "standard input", "standard output", and "standard error output".
+These streams are, by default, connected to your terminal, but they are
+often redirected with the shell, via the `<', `<<', `>', `>>', `>&',
+and `|' operators. Standard error is typically used for writing error
+messages; the reason there are two separate streams, standard output
+and standard error, is so that they can be redirected separately.
+
+In other implementations of `awk', the only way to write an error
+message to standard error in an `awk' program is as follows:
+
+ print "Serious error detected!" | "cat 1>&2"
+
+This works by opening a pipeline to a shell command that can access the
+standard error stream that it inherits from the `awk' process. This is
+far from elegant, and it is also inefficient, because it requires a
+separate process. So people writing `awk' programs often don't do
+this. Instead, they send the error messages to the terminal, like this:
+
+ print "Serious error detected!" > "/dev/tty"
+
+This usually has the same effect but not always: although the standard
+error stream is usually the terminal, it can be redirected; when that
+happens, writing to the terminal is not correct. In fact, if `awk' is
+run from a background job, it may not have a terminal at all. Then
+opening `/dev/tty' fails.
+
+`gawk' provides special file names for accessing the three standard
+streams, as well as any other inherited open files. If the file name
+matches one of these special names when `gawk' redirects input or
+output, then it directly uses the stream that the file name stands for.
+These special file names work for all operating systems that `gawk' has
+been ported to, not just those that are POSIX-compliant:
+
+`/dev/stdin'
+ The standard input (file descriptor 0).
+
+`/dev/stdout'
+ The standard output (file descriptor 1).
+
+`/dev/stderr'
+ The standard error output (file descriptor 2).
+
+`/dev/fd/N'
+ The file associated with file descriptor N. Such a file must be
+ opened by the program initiating the `awk' execution (typically
+ the shell). Unless special pains are taken in the shell from which
+ `gawk' is invoked, only descriptors 0, 1, and 2 are available.
+
+The file names `/dev/stdin', `/dev/stdout', and `/dev/stderr' are
+aliases for `/dev/fd/0', `/dev/fd/1', and `/dev/fd/2', respectively.
+However, they are more self-explanatory. The proper way to write an
+error message in a `gawk' program is to use `/dev/stderr', like this:
+
+ print "Serious error detected!" > "/dev/stderr"
+
+Note the use of quotes around the file name. Like any other
+redirection, the value must be a string. It is a common error to omit
+the quotes, which leads to confusing results.
+
+\1f
+File: gawk.info, Node: Special Process, Next: Special Network, Prev: Special FD, Up: Special Files
+
+4.7.2 Special Files for Process-Related Information
+---------------------------------------------------
+
+`gawk' also provides special file names that give access to information
+about the running `gawk' process. Each of these "files" provides a
+single record of information. To read them more than once, they must
+first be closed with the `close' function (*note Close Files And
+Pipes::). The file names are:
+
+`/dev/pid'
+ Reading this file returns the process ID of the current process,
+ in decimal form, terminated with a newline.
+
+`/dev/ppid'
+ Reading this file returns the parent process ID of the current
+ process, in decimal form, terminated with a newline.
+
+`/dev/pgrpid'
+ Reading this file returns the process group ID of the current
+ process, in decimal form, terminated with a newline.
+
+`/dev/user'
+ Reading this file returns a single record terminated with a
+ newline. The fields are separated with spaces. The fields
+ represent the following information:
+
+ `$1'
+ The return value of the `getuid' system call (the real user
+ ID number).
+
+ `$2'
+ The return value of the `geteuid' system call (the effective
+ user ID number).
+
+ `$3'
+ The return value of the `getgid' system call (the real group
+ ID number).
+
+ `$4'
+ The return value of the `getegid' system call (the effective
+ group ID number).
+
+ If there are any additional fields, they are the group IDs
+ returned by the `getgroups' system call. (Multiple groups may not
+ be supported on all systems.)
+
+These special file names may be used on the command line as data files,
+as well as for I/O redirections within an `awk' program. They may not
+be used as source files with the `-f' option.
+
+ NOTE: The special files that provide process-related information
+ are now considered obsolete and will disappear entirely in the
+ next release of `gawk'. `gawk' prints a warning message every
+ time you use one of these files. To obtain process-related
+ information, use the `PROCINFO' array. *Note Auto-set::.
+
+\1f
+File: gawk.info, Node: Special Network, Next: Special Caveats, Prev: Special Process, Up: Special Files
+
+4.7.3 Special Files for Network Communications
+----------------------------------------------
+
+Starting with version 3.1 of `gawk', `awk' programs can open a two-way
+TCP/IP connection, acting as either a client or a server. This is done
+using a special file name of the form:
+
+ `/inet/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT'
+
+The PROTOCOL is one of `tcp', `udp', or `raw', and the other fields
+represent the other essential pieces of information for making a
+networking connection. These file names are used with the `|&'
+operator for communicating with a coprocess (*note Two-way I/O::).
+This is an advanced feature, mentioned here only for completeness.
+Full discussion is delayed until *Note TCP/IP Networking::.
+
+\1f
+File: gawk.info, Node: Special Caveats, Prev: Special Network, Up: Special Files
+
+4.7.4 Special File Name Caveats
+-------------------------------
+
+Here is a list of things to bear in mind when using the special file
+names that `gawk' provides:
+
+ * Recognition of these special file names is disabled if `gawk' is in
+ compatibility mode (*note Options::).
+
+ * The special files that provide process-related information are now
+ considered obsolete and will disappear entirely in the next
+ release of `gawk'. `gawk' prints a warning message every time you
+ use one of these files. To obtain process-related information,
+ use the `PROCINFO' array. *Note Built-in Variables::.
+
+ * Starting with version 3.1, `gawk' _always_ interprets these
+ special file names.(1) For example, using `/dev/fd/4' for output
+ actually writes on file descriptor 4, and not on a new file
+ descriptor that is `dup''ed from file descriptor 4. Most of the
+ time this does not matter; however, it is important to _not_ close
+ any of the files related to file descriptors 0, 1, and 2. Doing
+ so results in unpredictable behavior.
+
+---------- Footnotes ----------
+
+(1) Older versions of `gawk' would interpret these names internally
+only if the system did not actually have a `/dev/fd' directory or any
+of the other special files listed earlier. Usually this didn't make a
+difference, but sometimes it did; thus, it was decided to make `gawk''s
+behavior consistent on all systems and to have it always interpret the
+special file names itself.
+
+\1f
+File: gawk.info, Node: Close Files And Pipes, Prev: Special Files, Up: Printing
+
+4.8 Closing Input and Output Redirections
+=========================================
+
+If the same file name or the same shell command is used with `getline'
+more than once during the execution of an `awk' program (*note
+Getline::), the file is opened (or the command is executed) the first
+time only. At that time, the first record of input is read from that
+file or command. The next time the same file or command is used with
+`getline', another record is read from it, and so on.
+
+Similarly, when a file or pipe is opened for output, the file name or
+command associated with it is remembered by `awk', and subsequent
+writes to the same file or command are appended to the previous writes.
+The file or pipe stays open until `awk' exits.
+
+This implies that special steps are necessary in order to read the same
+file again from the beginning, or to rerun a shell command (rather than
+reading more output from the same command). The `close' function makes
+these things possible:
+
+ close(FILENAME)
+
+or:
+
+ close(COMMAND)
+
+The argument FILENAME or COMMAND can be any expression. Its value must
+_exactly_ match the string that was used to open the file or start the
+command (spaces and other "irrelevant" characters included). For
+example, if you open a pipe with this:
+
+ "sort -r names" | getline foo
+
+then you must close it with this:
+
+ close("sort -r names")
+
+Once this function call is executed, the next `getline' from that file
+or command, or the next `print' or `printf' to that file or command,
+reopens the file or reruns the command. Because the expression that
+you use to close a file or pipeline must exactly match the expression
+used to open the file or run the command, it is good practice to use a
+variable to store the file name or command. The previous example
+becomes the following:
+
+ sortcom = "sort -r names"
+ sortcom | getline foo
+ ...
+ close(sortcom)
+
+This helps avoid hard-to-find typographical errors in your `awk'
+programs. Here are some of the reasons for closing an output file:
+
+ * To write a file and read it back later on in the same `awk'
+ program. Close the file after writing it, then begin reading it
+ with `getline'.
+
+ * To write numerous files, successively, in the same `awk' program.
+ If the files aren't closed, eventually `awk' may exceed a system
+ limit on the number of open files in one process. It is best to
+ close each one when the program has finished writing it.
+
+ * To make a command finish. When output is redirected through a
+ pipe, the command reading the pipe normally continues to try to
+ read input as long as the pipe is open. Often this means the
+ command cannot really do its work until the pipe is closed. For
+ example, if output is redirected to the `mail' program, the
+ message is not actually sent until the pipe is closed.
+
+ * To run the same program a second time, with the same arguments.
+ This is not the same thing as giving more input to the first run!
+
+ For example, suppose a program pipes output to the `mail' program.
+ If it outputs several lines redirected to this pipe without closing
+ it, they make a single message of several lines. By contrast, if
+ the program closes the pipe after each line of output, then each
+ line makes a separate message.
+
+If you use more files than the system allows you to have open, `gawk'
+attempts to multiplex the available open files among your data files.
+`gawk''s ability to do this depends upon the facilities of your
+operating system, so it may not always work. It is therefore both good
+practice and good portability advice to always use `close' on your
+files when you are done with them. In fact, if you are using a lot of
+pipes, it is essential that you close commands when done. For example,
+consider something like this:
+
+ {
+ ...
+ command = ("grep " $1 " /some/file | my_prog -q " $3)
+ while ((command | getline) > 0) {
+ PROCESS OUTPUT OF command
+ }
+ # need close(command) here
+ }
+
+This example creates a new pipeline based on data in _each_ record.
+Without the call to `close' indicated in the comment, `awk' creates
+child processes to run the commands, until it eventually runs out of
+file descriptors for more pipelines.
+
+Even though each command has finished (as indicated by the end-of-file
+return status from `getline'), the child process is not terminated;(1)
+more importantly, the file descriptor for the pipe is not closed and
+released until `close' is called or `awk' exits.
+
+`close' will silently do nothing if given an argument that does not
+represent a file, pipe or coprocess that was opened with a redirection.
+
+Note also that `close(FILENAME)' has no "magic" effects on the implicit
+loop that reads through the files named on the command line. It is,
+more likely, a close of a file that was never opened, so `awk' silently
+does nothing.
+
+When using the `|&' operator to communicate with a coprocess, it is
+occasionally useful to be able to close one end of the two-way pipe
+without closing the other. This is done by supplying a second argument
+to `close'. As in any other call to `close', the first argument is the
+name of the command or special file used to start the coprocess. The
+second argument should be a string, with either of the values `"to"' or
+`"from"'. Case does not matter. As this is an advanced feature, a
+more complete discussion is delayed until *Note Two-way I/O::, which
+discusses it in more detail and gives an example.
+
+Advanced Notes: Using `close''s Return Value
+--------------------------------------------
+
+In many versions of Unix `awk', the `close' function is actually a
+statement. It is a syntax error to try and use the return value from
+`close': (d.c.)
+
+ command = "..."
+ command | getline info
+ retval = close(command) # syntax error in most Unix awks
+
+`gawk' treats `close' as a function. The return value is -1 if the
+argument names something that was never opened with a redirection, or
+if there is a system problem closing the file or process. In these
+cases, `gawk' sets the built-in variable `ERRNO' to a string describing
+the problem.
+
+In `gawk', when closing a pipe or coprocess (input or output), the
+return value is the exit status of the command.(2) Otherwise, it is the
+return value from the system's `close' or `fclose' C functions when
+closing input or output files, respectively. This value is zero if the
+close succeeds, or -1 if it fails.
+
+The POSIX standard is very vague; it says that `close' returns zero on
+success and non-zero otherwise. In general, different implementations
+vary in what they report when closing pipes; thus the return value
+cannot be used portably. (d.c.)
+
+---------- Footnotes ----------
+
+(1) The technical terminology is rather morbid. The finished child is
+called a "zombie," and cleaning up after it is referred to as "reaping."
+
+(2) This is a full 16-bit value as returned by the `wait' system call.
+See the system manual pages for information on how to decode this value.
+
+\1f
+File: gawk.info, Node: Expressions, Next: Patterns and Actions, Prev: Printing, Up: Top
+
+5 Expressions
+*************
+
+Expressions are the basic building blocks of `awk' patterns and
+actions. An expression evaluates to a value that you can print, test,
+or pass to a function. Additionally, an expression can assign a new
+value to a variable or a field by using an assignment operator.
+
+An expression can serve as a pattern or action statement on its own.
+Most other kinds of statements contain one or more expressions that
+specify the data on which to operate. As in other languages,
+expressions in `awk' include variables, array references, constants,
+and function calls, as well as combinations of these with various
+operators.
+
+* Menu:
+
+* Constants:: String, numeric and regexp constants.
+* Using Constant Regexps:: When and how to use a regexp constant.
+* Variables:: Variables give names to values for later use.
+* Conversion:: The conversion of strings to numbers and vice
+ versa.
+* Arithmetic Ops:: Arithmetic operations (`+', `-',
+ etc.)
+* Concatenation:: Concatenating strings.
+* Assignment Ops:: Changing the value of a variable or a field.
+* Increment Ops:: Incrementing the numeric value of a variable.
+* Truth Values:: What is ``true'' and what is ``false''.
+* Typing and Comparison:: How variables acquire types and how this
+ affects comparison of numbers and strings with
+ `<', etc.
+* Boolean Ops:: Combining comparison expressions using boolean
+ operators `||' (``or''), `&&'
+ (``and'') and `!' (``not'').
+* Conditional Exp:: Conditional expressions select between two
+ subexpressions under control of a third
+ subexpression.
+* Function Calls:: A function call is an expression.
+* Precedence:: How various operators nest.
+
+\1f
+File: gawk.info, Node: Constants, Next: Using Constant Regexps, Up: Expressions
+
+5.1 Constant Expressions
+========================
+
+The simplest type of expression is the "constant", which always has the
+same value. There are three types of constants: numeric, string, and
+regular expression.
+
+Each is used in the appropriate context when you need a data value that
+isn't going to change. Numeric constants can have different forms, but
+are stored identically internally.
+
+* Menu:
+
+* Scalar Constants:: Numeric and string constants.
+* Nondecimal-numbers:: What are octal and hex numbers.
+* Regexp Constants:: Regular Expression constants.
+
+\1f
+File: gawk.info, Node: Scalar Constants, Next: Nondecimal-numbers, Up: Constants
+
+5.1.1 Numeric and String Constants
+----------------------------------
+
+A "numeric constant" stands for a number. This number can be an
+integer, a decimal fraction, or a number in scientific (exponential)
+notation.(1) Here are some examples of numeric constants that all have
+the same value:
+
+ 105
+ 1.05e+2
+ 1050e-1
+
+A string constant consists of a sequence of characters enclosed in
+double-quotation marks. For example:
+
+ "parrot"
+
+represents the string whose contents are `parrot'. Strings in `gawk'
+can be of any length, and they can contain any of the possible
+eight-bit ASCII characters including ASCII NUL (character code zero).
+Other `awk' implementations may have difficulty with some character
+codes.
+
+---------- Footnotes ----------
+
+(1) The internal representation of all numbers, including integers,
+uses double-precision floating-point numbers. On most modern systems,
+these are in IEEE 754 standard format.
+
+\1f
+File: gawk.info, Node: Nondecimal-numbers, Next: Regexp Constants, Prev: Scalar Constants, Up: Constants
+
+5.1.2 Octal and Hexadecimal Numbers
+-----------------------------------
+
+In `awk', all numbers are in decimal; i.e., base 10. Many other
+programming languages allow you to specify numbers in other bases, often
+octal (base 8) and hexadecimal (base 16). In octal, the numbers go 0,
+1, 2, 3, 4, 5, 6, 7, 10, 11, 12, etc. Just as `11', in decimal, is 1
+times 10 plus 1, so `11', in octal, is 1 times 8, plus 1. This equals 9
+in decimal. In hexadecimal, there are 16 digits. Since the everyday
+decimal number system only has ten digits (`0'-`9'), the letters `a'
+through `f' are used to represent the rest. (Case in the letters is
+usually irrelevant; hexadecimal `a' and `A' have the same value.)
+Thus, `11', in hexadecimal, is 1 times 16 plus 1, which equals 17 in
+decimal.
+
+Just by looking at plain `11', you can't tell what base it's in. So,
+in C, C++, and other languages derived from C, there is a special
+notation to help signify the base. Octal numbers start with a leading
+`0', and hexadecimal numbers start with a leading `0x' or `0X':
+
+`11'
+ Decimal value 11.
+
+`011'
+ Octal 11, decimal value 9.
+
+`0x11'
+ Hexadecimal 11, decimal value 17.
+
+This example shows the difference:
+
+ $ gawk 'BEGIN { printf "%d, %d, %d\n", 011, 11, 0x11 }'
+ -| 9, 11, 17
+
+Being able to use octal and hexadecimal constants in your programs is
+most useful when working with data that cannot be represented
+conveniently as characters or as regular numbers, such as binary data
+of various sorts.
+
+`gawk' allows the use of octal and hexadecimal constants in your
+program text. However, such numbers in the input data are not treated
+differently; doing so by default would break old programs. (If you
+really need to do this, use the `--non-decimal-data' command-line
+option; *note Nondecimal Data::.) If you have octal or hexadecimal
+data, you can use the `strtonum' function (*note String Functions::) to
+convert the data into a number. Most of the time, you will want to use
+octal or hexadecimal constants when working with the built-in bit
+manipulation functions; see *Note Bitwise Functions::, for more
+information.
+
+Unlike some early C implementations, `8' and `9' are not valid in octal
+constants; e.g., `gawk' treats `018' as decimal 18:
+
+ $ gawk 'BEGIN { print "021 is", 021 ; print 018 }'
+ -| 021 is 17
+ -| 18
+
+Octal and hexadecimal source code constants are a `gawk' extension. If
+`gawk' is in compatibility mode (*note Options::), they are not
+available.
+
+Advanced Notes: A Constant's Base Does Not Affect Its Value
+-----------------------------------------------------------
+
+Once a numeric constant has been converted internally into a number,
+`gawk' no longer remembers what the original form of the constant was;
+the internal value is always used. This has particular consequences
+for conversion of numbers to strings:
+
+ $ gawk 'BEGIN { printf "0x11 is <%s>\n", 0x11 }'
+ -| 0x11 is <17>
+
+\1f
+File: gawk.info, Node: Regexp Constants, Prev: Nondecimal-numbers, Up: Constants
+
+5.1.4 Regular Expression Constants
+----------------------------------
+
+A regexp constant is a regular expression description enclosed in
+slashes, such as `/^beginning and end$/'. Most regexps used in `awk'
+programs are constant, but the `~' and `!~' matching operators can also
+match computed or "dynamic" regexps (which are just ordinary strings or
+variables that contain a regexp).
+
+\1f
+File: gawk.info, Node: Using Constant Regexps, Next: Variables, Prev: Constants, Up: Expressions
+
+5.2 Using Regular Expression Constants
+======================================
+
+When used on the righthand side of the `~' or `!~' operators, a regexp
+constant merely stands for the regexp that is to be matched. However,
+regexp constants (such as `/foo/') may be used like simple expressions.
+When a regexp constant appears by itself, it has the same meaning as if
+it appeared in a pattern, i.e., `($0 ~ /foo/)' (d.c.) *Note Expression
+Patterns::. This means that the following two code segments:
+
+ if ($0 ~ /barfly/ || $0 ~ /camelot/)
+ print "found"
+
+and:
+
+ if (/barfly/ || /camelot/)
+ print "found"
+
+are exactly equivalent. One rather bizarre consequence of this rule is
+that the following Boolean expression is valid, but does not do what
+the user probably intended:
+
+ # note that /foo/ is on the left of the ~
+ if (/foo/ ~ $1) print "found foo"
+
+This code is "obviously" testing `$1' for a match against the regexp
+`/foo/'. But in fact, the expression `/foo/ ~ $1' actually means `($0
+~ /foo/) ~ $1'. In other words, first match the input record against
+the regexp `/foo/'. The result is either zero or one, depending upon
+the success or failure of the match. That result is then matched
+against the first field in the record. Because it is unlikely that you
+would ever really want to make this kind of test, `gawk' issues a
+warning when it sees this construct in a program. Another consequence
+of this rule is that the assignment statement:
+
+ matches = /foo/
+
+assigns either zero or one to the variable `matches', depending upon
+the contents of the current input record. This feature of the language
+has never been well documented until the POSIX specification.
+
+Constant regular expressions are also used as the first argument for
+the `gensub', `sub', and `gsub' functions, and as the second argument
+of the `match' function (*note String Functions::). Modern
+implementations of `awk', including `gawk', allow the third argument of
+`split' to be a regexp constant, but some older implementations do not.
+(d.c.) This can lead to confusion when attempting to use regexp
+constants as arguments to user-defined functions (*note User-defined::).
+For example:
+
+ function mysub(pat, repl, str, global)
+ {
+ if (global)
+ gsub(pat, repl, str)
+ else
+ sub(pat, repl, str)
+ return str
+ }
+
+ {
+ ...
+ text = "hi! hi yourself!"
+ mysub(/hi/, "howdy", text, 1)
+ ...
+ }
+
+In this example, the programmer wants to pass a regexp constant to the
+user-defined function `mysub', which in turn passes it on to either
+`sub' or `gsub'. However, what really happens is that the `pat'
+parameter is either one or zero, depending upon whether or not `$0'
+matches `/hi/'. `gawk' issues a warning when it sees a regexp constant
+used as a parameter to a user-defined function, since passing a truth
+value in this way is probably not what was intended.
+
+\1f
+File: gawk.info, Node: Variables, Next: Conversion, Prev: Using Constant Regexps, Up: Expressions
+
+5.3 Variables
+=============
+
+Variables are ways of storing values at one point in your program for
+use later in another part of your program. They can be manipulated
+entirely within the program text, and they can also be assigned values
+on the `awk' command line.
+
+* Menu:
+
+* Using Variables:: Using variables in your programs.
+* Assignment Options:: Setting variables on the command-line and a
+ summary of command-line syntax. This is an
+ advanced method of input.
+
+\1f
+File: gawk.info, Node: Using Variables, Next: Assignment Options, Up: Variables
+
+5.3.1 Using Variables in a Program
+----------------------------------
+
+Variables let you give names to values and refer to them later.
+Variables have already been used in many of the examples. The name of
+a variable must be a sequence of letters, digits, or underscores, and
+it may not begin with a digit. Case is significant in variable names;
+`a' and `A' are distinct variables.
+
+A variable name is a valid expression by itself; it represents the
+variable's current value. Variables are given new values with
+"assignment operators", "increment operators", and "decrement
+operators". *Note Assignment Ops::.
+
+A few variables have special built-in meanings, such as `FS' (the field
+separator), and `NF' (the number of fields in the current input
+record). *Note Built-in Variables::, for a list of the built-in
+variables. These built-in variables can be used and assigned just like
+all other variables, but their values are also used or changed
+automatically by `awk'. All built-in variables' names are entirely
+uppercase.
+
+Variables in `awk' can be assigned either numeric or string values.
+The kind of value a variable holds can change over the life of a
+program. By default, variables are initialized to the empty string,
+which is zero if converted to a number. There is no need to
+"initialize" each variable explicitly in `awk', which is what you would
+do in C and in most other traditional languages.
+
+\1f
+File: gawk.info, Node: Assignment Options, Prev: Using Variables, Up: Variables
+
+5.3.2 Assigning Variables on the Command Line
+---------------------------------------------
+
+Any `awk' variable can be set by including a "variable assignment"
+among the arguments on the command line when `awk' is invoked (*note
+Other Arguments::). Such an assignment has the following form:
+
+ VARIABLE=TEXT
+
+With it, a variable is set either at the beginning of the `awk' run or
+in between input files. When the assignment is preceded with the `-v'
+option, as in the following:
+
+ -v VARIABLE=TEXT
+
+the variable is set at the very beginning, even before the `BEGIN'
+rules are run. The `-v' option and its assignment must precede all the
+file name arguments, as well as the program text. (*Note Options::,
+for more information about the `-v' option.) Otherwise, the variable
+assignment is performed at a time determined by its position among the
+input file arguments--after the processing of the preceding input file
+argument. For example:
+
+ awk '{ print $n }' n=4 inventory-shipped n=2 BBS-list
+
+prints the value of field number `n' for all input records. Before the
+first file is read, the command line sets the variable `n' equal to
+four. This causes the fourth field to be printed in lines from the
+file `inventory-shipped'. After the first file has finished, but
+before the second file is started, `n' is set to two, so that the
+second field is printed in lines from `BBS-list':
+
+ $ awk '{ print $n }' n=4 inventory-shipped n=2 BBS-list
+ -| 15
+ -| 24
+ ...
+ -| 555-5553
+ -| 555-3412
+ ...
+
+Command-line arguments are made available for explicit examination by
+the `awk' program in the `ARGV' array (*note ARGC and ARGV::). `awk'
+processes the values of command-line assignments for escape sequences
+(*note Escape Sequences::). (d.c.)
+
+\1f
+File: gawk.info, Node: Conversion, Next: Arithmetic Ops, Prev: Variables, Up: Expressions
+
+5.4 Conversion of Strings and Numbers
+=====================================
+
+Strings are converted to numbers and numbers are converted to strings,
+if the context of the `awk' program demands it. For example, if the
+value of either `foo' or `bar' in the expression `foo + bar' happens to
+be a string, it is converted to a number before the addition is
+performed. If numeric values appear in string concatenation, they are
+converted to strings. Consider the following:
+
+ two = 2; three = 3
+ print (two three) + 4
+
+This prints the (numeric) value 27. The numeric values of the
+variables `two' and `three' are converted to strings and concatenated
+together. The resulting string is converted back to the number 23, to
+which 4 is then added.
+
+If, for some reason, you need to force a number to be converted to a
+string, concatenate the empty string, `""', with that number. To force
+a string to be converted to a number, add zero to that string. A
+string is converted to a number by interpreting any numeric prefix of
+the string as numerals: `"2.5"' converts to 2.5, `"1e3"' converts to
+1000, and `"25fix"' has a numeric value of 25. Strings that can't be
+interpreted as valid numbers convert to zero.
+
+The exact manner in which numbers are converted into strings is
+controlled by the `awk' built-in variable `CONVFMT' (*note Built-in
+Variables::). Numbers are converted using the `sprintf' function with
+`CONVFMT' as the format specifier (*note String Functions::).
+
+`CONVFMT''s default value is `"%.6g"', which prints a value with at
+least six significant digits. For some applications, you might want to
+change it to specify more precision. On most modern machines, 17
+digits is enough to capture a floating-point number's value exactly,
+most of the time.(1)
+
+Strange results can occur if you set `CONVFMT' to a string that doesn't
+tell `sprintf' how to format floating-point numbers in a useful way.
+For example, if you forget the `%' in the format, `awk' converts all
+numbers to the same constant string. As a special case, if a number is
+an integer, then the result of converting it to a string is _always_ an
+integer, no matter what the value of `CONVFMT' may be. Given the
+following code fragment:
+
+ CONVFMT = "%2.2f"
+ a = 12
+ b = a ""
+
+`b' has the value `"12"', not `"12.00"'. (d.c.)
+
+Prior to the POSIX standard, `awk' used the value of `OFMT' for
+converting numbers to strings. `OFMT' specifies the output format to
+use when printing numbers with `print'. `CONVFMT' was introduced in
+order to separate the semantics of conversion from the semantics of
+printing. Both `CONVFMT' and `OFMT' have the same default value:
+`"%.6g"'. In the vast majority of cases, old `awk' programs do not
+change their behavior. However, these semantics for `OFMT' are
+something to keep in mind if you must port your new style program to
+older implementations of `awk'. We recommend that instead of changing
+your programs, just port `gawk' itself. *Note Print::, for more
+information on the `print' statement.
+
+Finally, once again, where you are can matter when it comes to
+converting between numbers and strings. In *Note Locales::, we
+mentioned that the local character set and language (the locale) can
+affect how `gawk' matches characters. The locale also affects numeric
+formats. In particular, for `awk' programs, it affects the decimal
+point character. The `"C"' locale, and most English-language locales,
+use the period character (`.') as the decimal point. However, many (if
+not most) European and non-English locales use the comma (`,') as the
+decimal point character.
+
+The POSIX standard says that `awk' always uses the period as the decimal
+point when reading the `awk' program source code, and for command-line
+variable assignments (*note Other Arguments::). However, when
+interpreting input data, for `print' and `printf' output, and for
+number to string conversion, the local decimal point character is used.
+As of version 3.1.3, `gawk' fully complies with this aspect of the
+standard. Here are some examples indicating the difference in behavior,
+on a GNU/Linux system:
+
+ $ gawk 'BEGIN { printf "%g\n", 3.1415927 }'
+ -| 3.14159
+ $ LC_ALL=en_DK gawk 'BEGIN { printf "%g\n", 3.1415927 }'
+ -| 3,14159
+ $ echo 4,321 | gawk '{ print $1 + 1 }'
+ -| 5
+ $ echo 4,321 | LC_ALL=en_DK gawk '{ print $1 + 1 }'
+ -| 5,321
+
+The `en_DK' locale is for English in Denmark, where the comma acts as
+the decimal point separator. In the normal `"C"' locale, `gawk' treats
+`4,321' as `4', while in the Danish locale, it's treated as the full
+number, `4.321'.
+
+---------- Footnotes ----------
+
+(1) Pathological cases can require up to 752 digits (!), but we doubt
+that you need to worry about this.
+
+\1f
+File: gawk.info, Node: Arithmetic Ops, Next: Concatenation, Prev: Conversion, Up: Expressions
+
+5.5 Arithmetic Operators
+========================
+
+The `awk' language uses the common arithmetic operators when evaluating
+expressions. All of these arithmetic operators follow normal
+precedence rules and work as you would expect them to.
+
+The following example uses a file named `grades', which contains a list
+of student names as well as three test scores per student (it's a small
+class):
+
+ Pat 100 97 58
+ Sandy 84 72 93
+ Chris 72 92 89
+
+This programs takes the file `grades' and prints the average of the
+scores:
+
+ $ awk '{ sum = $2 + $3 + $4 ; avg = sum / 3
+ > print $1, avg }' grades
+ -| Pat 85
+ -| Sandy 83
+ -| Chris 84.3333
+
+The following list provides the arithmetic operators in `awk', in order
+from the highest precedence to the lowest:
+
+`- X'
+ Negation.
+
+`+ X'
+ Unary plus; the expression is converted to a number.
+
+`X ^ Y'
+`X ** Y'
+ Exponentiation; X raised to the Y power. `2 ^ 3' has the value
+ eight; the character sequence `**' is equivalent to `^'.
+
+`X * Y'
+ Multiplication.
+
+`X / Y'
+ Division; because all numbers in `awk' are floating-point
+ numbers, the result is _not_ rounded to an integer--`3 / 4' has
+ the value 0.75. (It is a common mistake, especially for C
+ programmers, to forget that _all_ numbers in `awk' are
+ floating-point, and that division of integer-looking constants
+ produces a real number, not an integer.)
+
+`X % Y'
+ Remainder; further discussion is provided in the text, just after
+ this list.
+
+`X + Y'
+ Addition.
+
+`X - Y'
+ Subtraction.
+
+Unary plus and minus have the same precedence, the multiplication
+operators all have the same precedence, and addition and subtraction
+have the same precedence.
+
+When computing the remainder of `X % Y', the quotient is rounded toward
+zero to an integer and multiplied by Y. This result is subtracted from
+X; this operation is sometimes known as "trunc-mod." The following
+relation always holds:
+
+ b * int(a / b) + (a % b) == a
+
+One possibly undesirable effect of this definition of remainder is that
+`X % Y' is negative if X is negative. Thus:
+
+ -17 % 8 = -1
+
+In other `awk' implementations, the signedness of the remainder may be
+machine-dependent.
+
+ NOTE: The POSIX standard only specifies the use of `^' for
+ exponentiation. For maximum portability, do not use the `**'
+ operator.
+
+\1f
+File: gawk.info, Node: Concatenation, Next: Assignment Ops, Prev: Arithmetic Ops, Up: Expressions
+
+5.6 String Concatenation
+========================
+
+ It seemed like a good idea at the time.
+ Brian Kernighan
+
+There is only one string operation: concatenation. It does not have a
+specific operator to represent it. Instead, concatenation is performed
+by writing expressions next to one another, with no operator. For
+example:
+
+ $ awk '{ print "Field number one: " $1 }' BBS-list
+ -| Field number one: aardvark
+ -| Field number one: alpo-net
+ ...
+
+Without the space in the string constant after the `:', the line runs
+together. For example:
+
+ $ awk '{ print "Field number one:" $1 }' BBS-list
+ -| Field number one:aardvark
+ -| Field number one:alpo-net
+ ...
+
+Because string concatenation does not have an explicit operator, it is
+often necessary to insure that it happens at the right time by using
+parentheses to enclose the items to concatenate. For example, the
+following code fragment does not concatenate `file' and `name' as you
+might expect:
+
+ file = "file"
+ name = "name"
+ print "something meaningful" > file name
+
+It is necessary to use the following:
+
+ print "something meaningful" > (file name)
+
+Parentheses should be used around concatenation in all but the most
+common contexts, such as on the righthand side of `='. Be careful
+about the kinds of expressions used in string concatenation. In
+particular, the order of evaluation of expressions used for
+concatenation is undefined in the `awk' language. Consider this
+example:
+
+ BEGIN {
+ a = "don't"
+ print (a " " (a = "panic"))
+ }
+
+It is not defined whether the assignment to `a' happens before or after
+the value of `a' is retrieved for producing the concatenated value.
+The result could be either `don't panic', or `panic panic'. The
+precedence of concatenation, when mixed with other operators, is often
+counter-intuitive. Consider this example:
+
+ $ awk 'BEGIN { print -12 " " -24 }'
+ -| -12-24
+
+This "obviously" is concatenating -12, a space, and -24. But where did
+the space disappear to? The answer lies in the combination of operator
+precedences and `awk''s automatic conversion rules. To get the desired
+result, write the program in the following manner:
+
+ $ awk 'BEGIN { print -12 " " (-24) }'
+ -| -12 -24
+
+This forces `awk' to treat the `-' on the `-24' as unary. Otherwise,
+it's parsed as follows:
+
+ -12 (`" "' - 24)
+ => -12 (0 - 24)
+ => -12 (-24)
+ => -12-24
+
+As mentioned earlier, when doing concatenation, _parenthesize_.
+Otherwise, you're never quite sure what you'll get.
+
+\1f
+File: gawk.info, Node: Assignment Ops, Next: Increment Ops, Prev: Concatenation, Up: Expressions
+
+5.7 Assignment Expressions
+==========================
+
+An "assignment" is an expression that stores a (usually different)
+value into a variable. For example, let's assign the value one to the
+variable `z':
+
+ z = 1
+
+After this expression is executed, the variable `z' has the value one.
+Whatever old value `z' had before the assignment is forgotten.
+
+Assignments can also store string values. For example, the following
+stores the value `"this food is good"' in the variable `message':
+
+ thing = "food"
+ predicate = "good"
+ message = "this " thing " is " predicate
+
+This also illustrates string concatenation. The `=' sign is called an
+"assignment operator". It is the simplest assignment operator because
+the value of the righthand operand is stored unchanged. Most operators
+(addition, concatenation, and so on) have no effect except to compute a
+value. If the value isn't used, there's no reason to use the operator.
+An assignment operator is different; it does produce a value, but even
+if you ignore it, the assignment still makes itself felt through the
+alteration of the variable. We call this a "side effect".
+
+The lefthand operand of an assignment need not be a variable (*note
+Variables::); it can also be a field (*note Changing Fields::) or an
+array element (*note Arrays::). These are all called "lvalues", which
+means they can appear on the lefthand side of an assignment operator.
+The righthand operand may be any expression; it produces the new value
+that the assignment stores in the specified variable, field, or array
+element. (Such values are called "rvalues".)
+
+It is important to note that variables do _not_ have permanent types.
+A variable's type is simply the type of whatever value it happens to
+hold at the moment. In the following program fragment, the variable
+`foo' has a numeric value at first, and a string value later on:
+
+ foo = 1
+ print foo
+ foo = "bar"
+ print foo
+
+When the second assignment gives `foo' a string value, the fact that it
+previously had a numeric value is forgotten.
+
+String values that do not begin with a digit have a numeric value of
+zero. After executing the following code, the value of `foo' is five:
+
+ foo = "a string"
+ foo = foo + 5
+
+ NOTE: Using a variable as a number and then later as a string can
+ be confusing and is poor programming style. The previous two
+ examples illustrate how `awk' works, _not_ how you should write
+ your programs!
+
+An assignment is an expression, so it has a value--the same value that
+is assigned. Thus, `z = 1' is an expression with the value one. One
+consequence of this is that you can write multiple assignments together,
+such as:
+
+ x = y = z = 5
+
+This example stores the value five in all three variables (`x', `y',
+and `z'). It does so because the value of `z = 5', which is five, is
+stored into `y' and then the value of `y = z = 5', which is five, is
+stored into `x'.
+
+Assignments may be used anywhere an expression is called for. For
+example, it is valid to write `x != (y = 1)' to set `y' to one, and
+then test whether `x' equals one. But this style tends to make
+programs hard to read; such nesting of assignments should be avoided,
+except perhaps in a one-shot program.
+
+Aside from `=', there are several other assignment operators that do
+arithmetic with the old value of the variable. For example, the
+operator `+=' computes a new value by adding the righthand value to the
+old value of the variable. Thus, the following assignment adds five to
+the value of `foo':
+
+ foo += 5
+
+This is equivalent to the following:
+
+ foo = foo + 5
+
+Use whichever makes the meaning of your program clearer.
+
+There are situations where using `+=' (or any assignment operator) is
+_not_ the same as simply repeating the lefthand operand in the
+righthand expression. For example:
+
+ # Thanks to Pat Rankin for this example
+ BEGIN {
+ foo[rand()] += 5
+ for (x in foo)
+ print x, foo[x]
+
+ bar[rand()] = bar[rand()] + 5
+ for (x in bar)
+ print x, bar[x]
+ }
+
+The indices of `bar' are practically guaranteed to be different, because
+`rand' returns different values each time it is called. (Arrays and
+the `rand' function haven't been covered yet. *Note Arrays::, and see
+*Note Numeric Functions::, for more information). This example
+illustrates an important fact about assignment operators: the lefthand
+expression is only evaluated _once_. It is up to the implementation as
+to which expression is evaluated first, the lefthand or the righthand.
+Consider this example:
+
+ i = 1
+ a[i += 2] = i + 1
+
+The value of `a[3]' could be either two or four.
+
+*Note table-assign-ops:: lists the arithmetic assignment operators. In
+each case, the righthand operand is an expression whose value is
+converted to a number.
+
+Operator Effect
+--------------------------------------------------------------------------
+LVALUE `+=' INCREMENT Adds INCREMENT to the value of LVALUE.
+--------------------------------------------------------------------------
+LVALUE `-=' DECREMENT Subtracts DECREMENT from the value of LVALUE.
+--------------------------------------------------------------------------
+LVALUE `*=' Multiplies the value of LVALUE by COEFFICIENT.
+COEFFICIENT
+--------------------------------------------------------------------------
+LVALUE `/=' DIVISOR Divides the value of LVALUE by DIVISOR.
+--------------------------------------------------------------------------
+LVALUE `%=' MODULUS Sets LVALUE to its remainder by MODULUS.
+--------------------------------------------------------------------------
+LVALUE `^=' POWER
+--------------------------------------------------------------------------
+LVALUE `**=' POWER Raises LVALUE to the power POWER.
+--------------------------------------------------------------------------
+
+Table 5.1: Arithmetic Assignment Operators
+
+ NOTE: Only the `^=' operator is specified by POSIX. For maximum
+ portability, do not use the `**=' operator.
+
+Advanced Notes: Syntactic Ambiguities Between `/=' and Regular Expressions
+--------------------------------------------------------------------------
+
+There is a syntactic ambiguity between the `/=' assignment operator and
+regexp constants whose first character is an `='. (d.c.) This is most
+notable in commercial `awk' versions. For example:
+
+ $ awk /==/ /dev/null
+ error--> awk: syntax error at source line 1
+ error--> context is
+ error--> >>> /= <<<
+ error--> awk: bailing out at source line 1
+
+A workaround is:
+
+ awk '/[=]=/' /dev/null
+
+`gawk' does not have this problem, nor do the other freely available
+versions described in *Note Other Versions::.
+
+\1f
+File: gawk.info, Node: Increment Ops, Next: Truth Values, Prev: Assignment Ops, Up: Expressions
+
+5.8 Increment and Decrement Operators
+=====================================
+
+"Increment" and "decrement operators" increase or decrease the value of
+a variable by one. An assignment operator can do the same thing, so
+the increment operators add no power to the `awk' language; however,
+they are convenient abbreviations for very common operations.
+
+The operator used for adding one is written `++'. It can be used to
+increment a variable either before or after taking its value. To
+pre-increment a variable `v', write `++v'. This adds one to the value
+of `v'--that new value is also the value of the expression. (The
+assignment expression `v += 1' is completely equivalent.) Writing the
+`++' after the variable specifies post-increment. This increments the
+variable value just the same; the difference is that the value of the
+increment expression itself is the variable's _old_ value. Thus, if
+`foo' has the value four, then the expression `foo++' has the value
+four, but it changes the value of `foo' to five. In other words, the
+operator returns the old value of the variable, but with the side
+effect of incrementing it.
+
+The post-increment `foo++' is nearly the same as writing `(foo += 1) -
+1'. It is not perfectly equivalent because all numbers in `awk' are
+floating-point--in floating-point, `foo + 1 - 1' does not necessarily
+equal `foo'. But the difference is minute as long as you stick to
+numbers that are fairly small (less than 10e12).
+
+Fields and array elements are incremented just like variables. (Use
+`$(i++)' when you want to do a field reference and a variable increment
+at the same time. The parentheses are necessary because of the
+precedence of the field reference operator `$'.)
+
+The decrement operator `--' works just like `++', except that it
+subtracts one instead of adding it. As with `++', it can be used before
+the lvalue to pre-decrement or after it to post-decrement. Following
+is a summary of increment and decrement expressions:
+
+`++LVALUE'
+ This expression increments LVALUE, and the new value becomes the
+ value of the expression.
+
+`LVALUE++'
+ This expression increments LVALUE, but the value of the expression
+ is the _old_ value of LVALUE.
+
+`--LVALUE'
+ This expression is like `++LVALUE', but instead of adding, it
+ subtracts. It decrements LVALUE and delivers the value that is
+ the result.
+
+`LVALUE--'
+ This expression is like `LVALUE++', but instead of adding, it
+ subtracts. It decrements LVALUE. The value of the expression is
+ the _old_ value of LVALUE.
+
+Advanced Notes: Operator Evaluation Order
+-----------------------------------------
+
+ Doctor, doctor! It hurts when I do this!
+ So don't do that!
+ Groucho Marx
+
+What happens for something like the following?
+
+ b = 6
+ print b += b++
+
+Or something even stranger?
+
+ b = 6
+ b += ++b + b++
+ print b
+
+In other words, when do the various side effects prescribed by the
+postfix operators (`b++') take effect? When side effects happen is
+"implementation defined". In other words, it is up to the particular
+version of `awk'. The result for the first example may be 12 or 13,
+and for the second, it may be 22 or 23.
+
+In short, doing things like this is not recommended and definitely not
+anything that you can rely upon for portability. You should avoid such
+things in your own programs.
+
+\1f
+File: gawk.info, Node: Truth Values, Next: Typing and Comparison, Prev: Increment Ops, Up: Expressions
+
+5.9 True and False in `awk'
+===========================
+
+Many programming languages have a special representation for the
+concepts of "true" and "false." Such languages usually use the special
+constants `true' and `false', or perhaps their uppercase equivalents.
+However, `awk' is different. It borrows a very simple concept of true
+and false from C. In `awk', any nonzero numeric value _or_ any
+nonempty string value is true. Any other value (zero or the null
+string `""') is false. The following program prints `A strange truth
+value' three times:
+
+ BEGIN {
+ if (3.1415927)
+ print "A strange truth value"
+ if ("Four Score And Seven Years Ago")
+ print "A strange truth value"
+ if (j = 57)
+ print "A strange truth value"
+ }
+
+There is a surprising consequence of the "nonzero or non-null" rule:
+the string constant `"0"' is actually true, because it is non-null.
+(d.c.)
+
+\1f
+File: gawk.info, Node: Typing and Comparison, Next: Boolean Ops, Prev: Truth Values, Up: Expressions
+
+5.10 Variable Typing and Comparison Expressions
+===============================================
+
+ The Guide is definitive. Reality is frequently inaccurate.
+ The Hitchhiker's Guide to the Galaxy
+
+Unlike other programming languages, `awk' variables do not have a fixed
+type. Instead, they can be either a number or a string, depending upon
+the value that is assigned to them.
+
+The 1992 POSIX standard introduced the concept of a "numeric string",
+which is simply a string that looks like a number--for example,
+`" +2"'. This concept is used for determining the type of a variable.
+The type of the variable is important because the types of two variables
+determine how they are compared. In `gawk', variable typing follows
+these rules:
+
+ * A numeric constant or the result of a numeric operation has the
+ NUMERIC attribute.
+
+ * A string constant or the result of a string operation has the
+ STRING attribute.
+
+ * Fields, `getline' input, `FILENAME', `ARGV' elements, `ENVIRON'
+ elements, and the elements of an array created by `split' that are
+ numeric strings have the STRNUM attribute. Otherwise, they have
+ the STRING attribute. Uninitialized variables also have the
+ STRNUM attribute.
+
+ * Attributes propagate across assignments but are not changed by any
+ use.
+
+The last rule is particularly important. In the following program, `a'
+has numeric type, even though it is later used in a string operation:
+
+ BEGIN {
+ a = 12.345
+ b = a " is a cute number"
+ print b
+ }
+
+When two operands are compared, either string comparison or numeric
+comparison may be used. This depends upon the attributes of the
+operands, according to the following symmetric matrix:
+
+ +---------------------------------------------
+ | STRING NUMERIC STRNUM
+ -------+---------------------------------------------
+ |
+ STRING | string string string
+ |
+ NUMERIC | string numeric numeric
+ |
+ STRNUM | string numeric numeric
+ -------+---------------------------------------------
+
+The basic idea is that user input that looks numeric--and _only_ user
+input--should be treated as numeric, even though it is actually made of
+characters and is therefore also a string. Thus, for example, the
+string constant `" +3.14"' is a string, even though it looks numeric,
+and is _never_ treated as number for comparison purposes.
+
+In short, when one operand is a "pure" string, such as a string
+constant, then a string comparison is performed. Otherwise, a numeric
+comparison is performed.(1)
+
+"Comparison expressions" compare strings or numbers for relationships
+such as equality. They are written using "relational operators", which
+are a superset of those in C. *Note table-relational-ops:: describes
+them.
+
+Expression Result
+--------------------------------------------------------------------------
+X `<' Y True if X is less than Y.
+--------------------------------------------------------------------------
+X `<=' Y True if X is less than or equal to Y.
+--------------------------------------------------------------------------
+X `>' Y True if X is greater than Y.
+--------------------------------------------------------------------------
+X `>=' Y True if X is greater than or equal to Y.
+--------------------------------------------------------------------------
+X `==' Y True if X is equal to Y.
+--------------------------------------------------------------------------
+X `!=' Y True if X is not equal to Y.
+--------------------------------------------------------------------------
+X `~' Y True if the string X matches the regexp denoted by Y.
+--------------------------------------------------------------------------
+X `!~' Y True if the string X does not match the regexp
+ denoted by Y.
+--------------------------------------------------------------------------
+SUBSCRIPT `in' True if the array ARRAY has an element with the
+ARRAY subscript SUBSCRIPT.
+--------------------------------------------------------------------------
+
+Table 5.2: Relational Operators
+
+ Comparison expressions have the value one if true and zero if false.
+When comparing operands of mixed types, numeric operands are converted
+to strings using the value of `CONVFMT' (*note Conversion::).
+
+ Strings are compared by comparing the first character of each, then
+the second character of each, and so on. Thus, `"10"' is less than
+`"9"'. If there are two strings where one is a prefix of the other,
+the shorter string is less than the longer one. Thus, `"abc"' is less
+than `"abcd"'.
+
+ It is very easy to accidentally mistype the `==' operator and leave
+off one of the `=' characters. The result is still valid `awk' code,
+but the program does not do what is intended:
+
+ if (a = b) # oops! should be a == b
+ ...
+ else
+ ...
+
+Unless `b' happens to be zero or the null string, the `if' part of the
+test always succeeds. Because the operators are so similar, this kind
+of error is very difficult to spot when scanning the source code.
+
+The following table of expressions illustrates the kind of comparison
+`gawk' performs, as well as what the result of the comparison is:
+
+`1.5 <= 2.0'
+ numeric comparison (true)
+
+`"abc" >= "xyz"'
+ string comparison (false)
+
+`1.5 != " +2"'
+ string comparison (true)
+
+`"1e2" < "3"'
+ string comparison (true)
+
+`a = 2; b = "2"'
+`a == b'
+ string comparison (true)
+
+`a = 2; b = " +2"'
+
+`a == b'
+ string comparison (false)
+
+In the next example:
+
+ $ echo 1e2 3 | awk '{ print ($1 < $2) ? "true" : "false" }'
+ -| false
+
+the result is `false' because both `$1' and `$2' are user input. They
+are numeric strings--therefore both have the STRNUM attribute,
+dictating a numeric comparison. The purpose of the comparison rules
+and the use of numeric strings is to attempt to produce the behavior
+that is "least surprising," while still "doing the right thing."
+String comparisons and regular expression comparisons are very
+different. For example:
+
+ x == "foo"
+
+has the value one, or is true if the variable `x' is precisely `foo'.
+By contrast:
+
+ x ~ /foo/
+
+has the value one if `x' contains `foo', such as `"Oh, what a fool am
+I!"'.
+
+The righthand operand of the `~' and `!~' operators may be either a
+regexp constant (`/.../') or an ordinary expression. In the latter
+case, the value of the expression as a string is used as a dynamic
+regexp (*note Regexp Usage::; also *note Computed Regexps::).
+
+In modern implementations of `awk', a constant regular expression in
+slashes by itself is also an expression. The regexp `/REGEXP/' is an
+abbreviation for the following comparison expression:
+
+ $0 ~ /REGEXP/
+
+One special place where `/foo/' is _not_ an abbreviation for `$0 ~
+/foo/' is when it is the righthand operand of `~' or `!~'. *Note Using
+Constant Regexps::, where this is discussed in more detail.
+
+---------- Footnotes ----------
+
+(1) The POSIX standard is under revision. The revised standard's rules
+for typing and comparison are the same as just described for `gawk'.
+
+\1f
+File: gawk.info, Node: Boolean Ops, Next: Conditional Exp, Prev: Typing and Comparison, Up: Expressions
+
+5.11 Boolean Expressions
+========================
+
+A "Boolean expression" is a combination of comparison expressions or
+matching expressions, using the Boolean operators "or" (`||'), "and"
+(`&&'), and "not" (`!'), along with parentheses to control nesting.
+The truth value of the Boolean expression is computed by combining the
+truth values of the component expressions. Boolean expressions are
+also referred to as "logical expressions". The terms are equivalent.
+
+Boolean expressions can be used wherever comparison and matching
+expressions can be used. They can be used in `if', `while', `do', and
+`for' statements (*note Statements::). They have numeric values (one
+if true, zero if false) that come into play if the result of the
+Boolean expression is stored in a variable or used in arithmetic.
+
+In addition, every Boolean expression is also a valid pattern, so you
+can use one as a pattern to control the execution of rules. The
+Boolean operators are:
+
+`BOOLEAN1 && BOOLEAN2'
+ True if both BOOLEAN1 and BOOLEAN2 are true. For example, the
+ following statement prints the current input record if it contains
+ both `2400' and `foo':
+
+ if ($0 ~ /2400/ && $0 ~ /foo/) print
+
+ The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is true.
+ This can make a difference when BOOLEAN2 contains expressions that
+ have side effects. In the case of `$0 ~ /foo/ && ($2 == bar++)',
+ the variable `bar' is not incremented if there is no substring
+ `foo' in the record.
+
+`BOOLEAN1 || BOOLEAN2'
+ True if at least one of BOOLEAN1 or BOOLEAN2 is true. For
+ example, the following statement prints all records in the input
+ that contain _either_ `2400' or `foo' or both:
+
+ if ($0 ~ /2400/ || $0 ~ /foo/) print
+
+ The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is false.
+ This can make a difference when BOOLEAN2 contains expressions
+ that have side effects.
+
+`! BOOLEAN'
+ True if BOOLEAN is false. For example, the following program
+ prints `no home!' in the unusual event that the `HOME' environment
+ variable is not defined:
+
+ BEGIN { if (! ("HOME" in ENVIRON))
+ print "no home!" }
+
+ (The `in' operator is described in *Note Reference to Elements::.)
+
+The `&&' and `||' operators are called "short-circuit" operators
+because of the way they work. Evaluation of the full expression is
+"short-circuited" if the result can be determined part way through its
+evaluation.
+
+Statements that use `&&' or `||' can be continued simply by putting a
+newline after them. But you cannot put a newline in front of either of
+these operators without using backslash continuation (*note
+Statements/Lines::).
+
+The actual value of an expression using the `!' operator is either one
+or zero, depending upon the truth value of the expression it is applied
+to. The `!' operator is often useful for changing the sense of a flag
+variable from false to true and back again. For example, the following
+program is one way to print lines in between special bracketing lines:
+
+ $1 == "START" { interested = ! interested; next }
+ interested == 1 { print }
+ $1 == "END" { interested = ! interested; next }
+
+The variable `interested', as with all `awk' variables, starts out
+initialized to zero, which is also false. When a line is seen whose
+first field is `START', the value of `interested' is toggled to true,
+using `!'. The next rule prints lines as long as `interested' is true.
+When a line is seen whose first field is `END', `interested' is toggled
+back to false.
+
+ NOTE: The `next' statement is discussed in *Note Next Statement::.
+ `next' tells `awk' to skip the rest of the rules, get the next
+ record, and start processing the rules over again at the top. The
+ reason it's there is to avoid printing the bracketing `START' and
+ `END' lines.
+
+\1f
+File: gawk.info, Node: Conditional Exp, Next: Function Calls, Prev: Boolean Ops, Up: Expressions
+
+5.12 Conditional Expressions
+============================
+
+A "conditional expression" is a special kind of expression that has
+three operands. It allows you to use one expression's value to select
+one of two other expressions. The conditional expression is the same
+as in the C language, as shown here:
+
+ SELECTOR ? IF-TRUE-EXP : IF-FALSE-EXP
+
+There are three subexpressions. The first, SELECTOR, is always
+computed first. If it is "true" (not zero or not null), then
+IF-TRUE-EXP is computed next and its value becomes the value of the
+whole expression. Otherwise, IF-FALSE-EXP is computed next and its
+value becomes the value of the whole expression. For example, the
+following expression produces the absolute value of `x':
+
+ x >= 0 ? x : -x
+
+Each time the conditional expression is computed, only one of
+IF-TRUE-EXP and IF-FALSE-EXP is used; the other is ignored. This is
+important when the expressions have side effects. For example, this
+conditional expression examines element `i' of either array `a' or
+array `b', and increments `i':
+
+ x == y ? a[i++] : b[i++]
+
+This is guaranteed to increment `i' exactly once, because each time
+only one of the two increment expressions is executed and the other is
+not. *Note Arrays::, for more information about arrays.
+
+As a minor `gawk' extension, a statement that uses `?:' can be
+continued simply by putting a newline after either character. However,
+putting a newline in front of either character does not work without
+using backslash continuation (*note Statements/Lines::). If `--posix'
+is specified (*note Options::), then this extension is disabled.
+
+\1f
+File: gawk.info, Node: Function Calls, Next: Precedence, Prev: Conditional Exp, Up: Expressions
+
+5.13 Function Calls
+===================
+
+A "function" is a name for a particular calculation. This enables you
+to ask for it by name at any point in the program. For example, the
+function `sqrt' computes the square root of a number.
+
+A fixed set of functions are "built-in", which means they are available
+in every `awk' program. The `sqrt' function is one of these. *Note
+Built-in::, for a list of built-in functions and their descriptions.
+In addition, you can define functions for use in your program. *Note
+User-defined::, for instructions on how to do this.
+
+The way to use a function is with a "function call" expression, which
+consists of the function name followed immediately by a list of
+"arguments" in parentheses. The arguments are expressions that provide
+the raw materials for the function's calculations. When there is more
+than one argument, they are separated by commas. If there are no
+arguments, just write `()' after the function name. The following
+examples show function calls with and without arguments:
+
+ sqrt(x^2 + y^2) one argument
+ atan2(y, x) two arguments
+ rand() no arguments
+
+*Caution:* Do not put any space between the function name and the
+open-parenthesis! A user-defined function name looks just like the
+name of a variable--a space would make the expression look like
+concatenation of a variable with an expression inside parentheses.
+
+With built-in functions, space before the parenthesis is harmless, but
+it is best not to get into the habit of using space to avoid mistakes
+with user-defined functions. Each function expects a particular number
+of arguments. For example, the `sqrt' function must be called with a
+single argument, the number of which to take the square root:
+
+ sqrt(ARGUMENT)
+
+Some of the built-in functions have one or more optional arguments. If
+those arguments are not supplied, the functions use a reasonable
+default value. *Note Built-in::, for full details. If arguments are
+omitted in calls to user-defined functions, then those arguments are
+treated as local variables and initialized to the empty string (*note
+User-defined::).
+
+Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it. In this
+example, the value of `sqrt(ARGUMENT)' is the square root of ARGUMENT.
+A function can also have side effects, such as assigning values to
+certain variables or doing I/O. The following program reads numbers,
+one number per line, and prints the square root of each one:
+
+ $ awk '{ print "The square root of", $1, "is", sqrt($1) }'
+ 1
+ -| The square root of 1 is 1
+ 3
+ -| The square root of 3 is 1.73205
+ 5
+ -| The square root of 5 is 2.23607
+ Ctrl-d
+
+\1f
+File: gawk.info, Node: Precedence, Prev: Function Calls, Up: Expressions
+
+5.14 Operator Precedence (How Operators Nest)
+=============================================
+
+"Operator precedence" determines how operators are grouped when
+different operators appear close by in one expression. For example,
+`*' has higher precedence than `+'; thus, `a + b * c' means to multiply
+`b' and `c', and then add `a' to the product (i.e., `a + (b * c)').
+
+The normal precedence of the operators can be overruled by using
+parentheses. Think of the precedence rules as saying where the
+parentheses are assumed to be. In fact, it is wise to always use
+parentheses whenever there is an unusual combination of operators,
+because other people who read the program may not remember what the
+precedence is in this case. Even experienced programmers occasionally
+forget the exact rules, which leads to mistakes. Explicit parentheses
+help prevent any such mistakes.
+
+When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment, conditional, and
+exponentiation operators, which group in the opposite order. Thus, `a
+- b + c' groups as `(a - b) + c' and `a = b = c' groups as `a = (b =
+c)'.
+
+The precedence of prefix unary operators does not matter as long as only
+unary operators are involved, because there is only one way to interpret
+them: innermost first. Thus, `$++i' means `$(++i)' and `++$x' means
+`++($x)'. However, when another operator follows the operand, then the
+precedence of the unary operators can matter. `$x^2' means `($x)^2',
+but `-x^2' means `-(x^2)', because `-' has lower precedence than `^',
+whereas `$' has higher precedence. This table presents `awk''s
+operators, in order of highest to lowest precedence:
+
+`(...)'
+ Grouping.
+
+`$'
+ Field.
+
+`++ --'
+ Increment, decrement.
+
+`^ **'
+ Exponentiation. These operators group right-to-left.
+
+`+ - !'
+ Unary plus, minus, logical "not."
+
+`* / %'
+ Multiplication, division, modulus.
+
+`+ -'
+ Addition, subtraction.
+
+`String Concatenation'
+ No special symbol is used to indicate concatenation. The operands
+ are simply written side by side (*note Concatenation::).
+
+`< <= == !='
+`> >= >> | |&'
+ Relational and redirection. The relational operators and the
+ redirections have the same precedence level. Characters such as
+ `>' serve both as relationals and as redirections; the context
+ distinguishes between the two meanings.
+
+ Note that the I/O redirection operators in `print' and `printf'
+ statements belong to the statement level, not to expressions. The
+ redirection does not produce an expression that could be the
+ operand of another operator. As a result, it does not make sense
+ to use a redirection operator near another operator of lower
+ precedence without parentheses. Such combinations (for example,
+ `print foo > a ? b : c'), result in syntax errors. The correct
+ way to write this statement is `print foo > (a ? b : c)'.
+
+`~ !~'
+ Matching, nonmatching.
+
+`in'
+ Array membership.
+
+`&&'
+ Logical "and".
+
+`||'
+ Logical "or".
+
+`?:'
+ Conditional. This operator groups right-to-left.
+
+`= += -= *='
+`/= %= ^= **='
+ Assignment. These operators group right to left.
+
+ NOTE: The `|&', `**', and `**=' operators are not specified by
+ POSIX. For maximum portability, do not use them.
+
+\1f
+File: gawk.info, Node: Patterns and Actions, Next: Arrays, Prev: Expressions, Up: Top
+
+6 Patterns, Actions, and Variables
+**********************************
+
+As you have already seen, each `awk' statement consists of a pattern
+with an associated action. This major node describes how you build
+patterns and actions, what kinds of things you can do within actions,
+and `awk''s built-in variables.
+
+The pattern-action rules and the statements available for use within
+actions form the core of `awk' programming. In a sense, everything
+covered up to here has been the foundation that programs are built on
+top of. Now it's time to start building something useful.
+
+* Menu:
+
+* Pattern Overview:: What goes into a pattern.
+* Using Shell Variables:: How to use shell variables with `awk'.
+* Action Overview:: What goes into an action.
+* Statements:: Describes the various control statements in
+ detail.
+* Built-in Variables:: Summarizes the built-in variables.
+
+\1f
+File: gawk.info, Node: Pattern Overview, Next: Using Shell Variables, Up: Patterns and Actions
+
+6.1 Pattern Elements
+====================
+
+* Menu:
+
+* Regexp Patterns:: Using regexps as patterns.
+* Expression Patterns:: Any expression can be used as a pattern.
+* Ranges:: Pairs of patterns specify record ranges.
+* BEGIN/END:: Specifying initialization and cleanup rules.
+* Empty:: The empty pattern, which matches every record.
+
+Patterns in `awk' control the execution of rules--a rule is executed
+when its pattern matches the current input record. The following is a
+summary of the types of `awk' patterns:
+
+`/REGULAR EXPRESSION/'
+ A regular expression. It matches when the text of the input record
+ fits the regular expression. (*Note Regexp::.)
+
+`EXPRESSION'
+ A single expression. It matches when its value is nonzero (if a
+ number) or non-null (if a string). (*Note Expression Patterns::.)
+
+`PAT1, PAT2'
+ A pair of patterns separated by a comma, specifying a range of
+ records. The range includes both the initial record that matches
+ PAT1 and the final record that matches PAT2. (*Note Ranges::.)
+
+`BEGIN'
+`END'
+ Special patterns for you to supply startup or cleanup actions for
+ your `awk' program. (*Note BEGIN/END::.)
+
+`EMPTY'
+ The empty pattern matches every input record. (*Note Empty::.)
+
+\1f
+File: gawk.info, Node: Regexp Patterns, Next: Expression Patterns, Up: Pattern Overview
+
+6.1.1 Regular Expressions as Patterns
+-------------------------------------
+
+Regular expressions are one of the first kinds of patterns presented in
+this book. This kind of pattern is simply a regexp constant in the
+pattern part of a rule. Its meaning is `$0 ~ /PATTERN/'. The pattern
+matches when the input record matches the regexp. For example:
+
+ /foo|bar|baz/ { buzzwords++ }
+ END { print buzzwords, "buzzwords seen" }
+
+\1f
+File: gawk.info, Node: Expression Patterns, Next: Ranges, Prev: Regexp Patterns, Up: Pattern Overview
+
+6.1.2 Expressions as Patterns
+-----------------------------
+
+Any `awk' expression is valid as an `awk' pattern. The pattern matches
+if the expression's value is nonzero (if a number) or non-null (if a
+string). The expression is reevaluated each time the rule is tested
+against a new input record. If the expression uses fields such as
+`$1', the value depends directly on the new input record's text;
+otherwise, it depends on only what has happened so far in the execution
+of the `awk' program.
+
+Comparison expressions, using the comparison operators described in
+*Note Typing and Comparison::, are a very common kind of pattern.
+Regexp matching and nonmatching are also very common expressions. The
+left operand of the `~' and `!~' operators is a string. The right
+operand is either a constant regular expression enclosed in slashes
+(`/REGEXP/'), or any expression whose string value is used as a dynamic
+regular expression (*note Computed Regexps::). The following example
+prints the second field of each input record whose first field is
+precisely `foo':
+
+ $ awk '$1 == "foo" { print $2 }' BBS-list
+
+(There is no output, because there is no BBS site with the exact name
+`foo'.) Contrast this with the following regular expression match,
+which accepts any record with a first field that contains `foo':
+
+ $ awk '$1 ~ /foo/ { print $2 }' BBS-list
+ -| 555-1234
+ -| 555-6699
+ -| 555-6480
+ -| 555-2127
+
+A regexp constant as a pattern is also a special case of an expression
+pattern. The expression `/foo/' has the value one if `foo' appears in
+the current input record. Thus, as a pattern, `/foo/' matches any
+record containing `foo'.
+
+Boolean expressions are also commonly used as patterns. Whether the
+pattern matches an input record depends on whether its subexpressions
+match. For example, the following command prints all the records in
+`BBS-list' that contain both `2400' and `foo':
+
+ $ awk '/2400/ && /foo/' BBS-list
+ -| fooey 555-1234 2400/1200/300 B
+
+The following command prints all records in `BBS-list' that contain
+_either_ `2400' or `foo' (or both, of course):
+
+ $ awk '/2400/ || /foo/' BBS-list
+ -| alpo-net 555-3412 2400/1200/300 A
+ -| bites 555-1675 2400/1200/300 A
+ -| fooey 555-1234 2400/1200/300 B
+ -| foot 555-6699 1200/300 B
+ -| macfoo 555-6480 1200/300 A
+ -| sdace 555-3430 2400/1200/300 A
+ -| sabafoo 555-2127 1200/300 C
+
+The following command prints all records in `BBS-list' that do _not_
+contain the string `foo':
+
+ $ awk '! /foo/' BBS-list
+ -| aardvark 555-5553 1200/300 B
+ -| alpo-net 555-3412 2400/1200/300 A
+ -| barfly 555-7685 1200/300 A
+ -| bites 555-1675 2400/1200/300 A
+ -| camelot 555-0542 300 C
+ -| core 555-2912 1200/300 C
+ -| sdace 555-3430 2400/1200/300 A
+
+The subexpressions of a Boolean operator in a pattern can be constant
+regular expressions, comparisons, or any other `awk' expressions. Range
+patterns are not expressions, so they cannot appear inside Boolean
+patterns. Likewise, the special patterns `BEGIN' and `END', which
+never match any input record, are not expressions and cannot appear
+inside Boolean patterns.
+
+\1f
+File: gawk.info, Node: Ranges, Next: BEGIN/END, Prev: Expression Patterns, Up: Pattern Overview
+
+6.1.3 Specifying Record Ranges with Patterns
+--------------------------------------------
+
+A "range pattern" is made of two patterns separated by a comma, in the
+form `BEGPAT, ENDPAT'. It is used to match ranges of consecutive input
+records. The first pattern, BEGPAT, controls where the range begins,
+while ENDPAT controls where the pattern ends. For example, the
+following:
+
+ awk '$1 == "on", $1 == "off"' myfile
+
+prints every record in `myfile' between `on'/`off' pairs, inclusive.
+
+A range pattern starts out by matching BEGPAT against every input
+record. When a record matches BEGPAT, the range pattern is "turned on"
+and the range pattern matches this record as well. As long as the
+range pattern stays turned on, it automatically matches every input
+record read. The range pattern also matches ENDPAT against every input
+record; when this succeeds, the range pattern is turned off again for
+the following record. Then the range pattern goes back to checking
+BEGPAT against each record.
+
+The record that turns on the range pattern and the one that turns it
+off both match the range pattern. If you don't want to operate on
+these records, you can write `if' statements in the rule's action to
+distinguish them from the records you are interested in.
+
+It is possible for a pattern to be turned on and off by the same
+record. If the record satisfies both conditions, then the action is
+executed for just that record. For example, suppose there is text
+between two identical markers (e.g., the `%' symbol), each on its own
+line, that should be ignored. A first attempt would be to combine a
+range pattern that describes the delimited text with the `next'
+statement (not discussed yet, *note Next Statement::). This causes
+`awk' to skip any further processing of the current record and start
+over again with the next input record. Such a program looks like this:
+
+ /^%$/,/^%$/ { next }
+ { print }
+
+This program fails because the range pattern is both turned on and
+turned off by the first line, which just has a `%' on it. To
+accomplish this task, write the program in the following manner, using
+a flag:
+
+ /^%$/ { skip = ! skip; next }
+ skip == 1 { next } # skip lines with `skip' set
+
+In a range pattern, the comma (`,') has the lowest precedence of all
+the operators (i.e., it is evaluated last). Thus, the following
+program attempts to combine a range pattern with another, simpler test:
+
+ echo Yes | awk '/1/,/2/ || /Yes/'
+
+The intent of this program is `(/1/,/2/) || /Yes/'. However, `awk'
+interprets this as `/1/, (/2/ || /Yes/)'. This cannot be changed or
+worked around; range patterns do not combine with other patterns:
+
+ $ echo Yes | gawk '(/1/,/2/) || /Yes/'
+ error--> gawk: cmd. line:1: (/1/,/2/) || /Yes/
+ error--> gawk: cmd. line:1: ^ parse error
+ error--> gawk: cmd. line:2: (/1/,/2/) || /Yes/
+ error--> gawk: cmd. line:2: ^ unexpected newline
+
+\1f
+File: gawk.info, Node: BEGIN/END, Next: Empty, Prev: Ranges, Up: Pattern Overview
+
+6.1.4 The `BEGIN' and `END' Special Patterns
+--------------------------------------------
+
+All the patterns described so far are for matching input records. The
+`BEGIN' and `END' special patterns are different. They supply startup
+and cleanup actions for `awk' programs. `BEGIN' and `END' rules must
+have actions; there is no default action for these rules because there
+is no current record when they run. `BEGIN' and `END' rules are often
+referred to as "`BEGIN' and `END' blocks" by long-time `awk'
+programmers.
+
+* Menu:
+
+* Using BEGIN/END:: How and why to use BEGIN/END rules.
+* I/O And BEGIN/END:: I/O issues in BEGIN/END rules.
+
+\1f
+File: gawk.info, Node: Using BEGIN/END, Next: I/O And BEGIN/END, Up: BEGIN/END
+
+6.1.4.1 Startup and Cleanup Actions
+...................................
+
+A `BEGIN' rule is executed once only, before the first input record is
+read. Likewise, an `END' rule is executed once only, after all the
+input is read. For example:
+
+ $ awk '
+ > BEGIN { print "Analysis of \"foo\"" }
+ > /foo/ { ++n }
+ > END { print "\"foo\" appears", n, "times." }' BBS-list
+ -| Analysis of "foo"
+ -| "foo" appears 4 times.
+
+This program finds the number of records in the input file `BBS-list'
+that contain the string `foo'. The `BEGIN' rule prints a title for the
+report. There is no need to use the `BEGIN' rule to initialize the
+counter `n' to zero, since `awk' does this automatically (*note
+Variables::). The second rule increments the variable `n' every time a
+record containing the pattern `foo' is read. The `END' rule prints the
+value of `n' at the end of the run.
+
+The special patterns `BEGIN' and `END' cannot be used in ranges or with
+Boolean operators (indeed, they cannot be used with any operators). An
+`awk' program may have multiple `BEGIN' and/or `END' rules. They are
+executed in the order in which they appear: all the `BEGIN' rules at
+startup and all the `END' rules at termination. `BEGIN' and `END'
+rules may be intermixed with other rules. This feature was added in
+the 1987 version of `awk' and is included in the POSIX standard. The
+original (1978) version of `awk' required the `BEGIN' rule to be placed
+at the beginning of the program, the `END' rule to be placed at the
+end, and only allowed one of each. This is no longer required, but it
+is a good idea to follow this template in terms of program organization
+and readability.
+
+Multiple `BEGIN' and `END' rules are useful for writing library
+functions, because each library file can have its own `BEGIN' and/or
+`END' rule to do its own initialization and/or cleanup. The order in
+which library functions are named on the command line controls the
+order in which their `BEGIN' and `END' rules are executed. Therefore,
+you have to be careful when writing such rules in library files so that
+the order in which they are executed doesn't matter. *Note Options::,
+for more information on using library functions. *Note Library
+Functions::, for a number of useful library functions.
+
+If an `awk' program has only a `BEGIN' rule and no other rules, then
+the program exits after the `BEGIN' rule is run.(1) However, if an
+`END' rule exists, then the input is read, even if there are no other
+rules in the program. This is necessary in case the `END' rule checks
+the `FNR' and `NR' variables.
+
+---------- Footnotes ----------
+
+(1) The original version of `awk' used to keep reading and ignoring
+input until the end of the file was seen.
+
+\1f
+File: gawk.info, Node: I/O And BEGIN/END, Prev: Using BEGIN/END, Up: BEGIN/END
+
+6.1.4.2 Input/Output from `BEGIN' and `END' Rules
+.................................................
+
+There are several (sometimes subtle) points to remember when doing I/O
+from a `BEGIN' or `END' rule. The first has to do with the value of
+`$0' in a `BEGIN' rule. Because `BEGIN' rules are executed before any
+input is read, there simply is no input record, and therefore no
+fields, when executing `BEGIN' rules. References to `$0' and the fields
+yield a null string or zero, depending upon the context. One way to
+give `$0' a real value is to execute a `getline' command without a
+variable (*note Getline::). Another way is simply to assign a value to
+`$0'.
+
+The second point is similar to the first but from the other direction.
+Traditionally, due largely to implementation issues, `$0' and `NF' were
+_undefined_ inside an `END' rule. The POSIX standard specifies that
+`NF' is available in an `END' rule. It contains the number of fields
+from the last input record. Most probably due to an oversight, the
+standard does not say that `$0' is also preserved, although logically
+one would think that it should be. In fact, `gawk' does preserve the
+value of `$0' for use in `END' rules. Be aware, however, that Unix
+`awk', and possibly other implementations, do not.
+
+The third point follows from the first two. The meaning of `print'
+inside a `BEGIN' or `END' rule is the same as always: `print $0'. If
+`$0' is the null string, then this prints an empty line. Many long
+time `awk' programmers use an unadorned `print' in `BEGIN' and `END'
+rules, to mean `print ""', relying on `$0' being null. Although one
+might generally get away with this in `BEGIN' rules, it is a very bad
+idea in `END' rules, at least in `gawk'. It is also poor style, since
+if an empty line is needed in the output, the program should print one
+explicitly.
+
+Finally, the `next' and `nextfile' statements are not allowed in a
+`BEGIN' rule, because the implicit
+read-a-record-and-match-against-the-rules loop has not started yet.
+Similarly, those statements are not valid in an `END' rule, since all
+the input has been read. (*Note Next Statement::, and see *Note
+Nextfile Statement::.)
+
+\1f
+File: gawk.info, Node: Empty, Prev: BEGIN/END, Up: Pattern Overview
+
+6.1.5 The Empty Pattern
+-----------------------
+
+An empty (i.e., nonexistent) pattern is considered to match _every_
+input record. For example, the program:
+
+ awk '{ print $1 }' BBS-list
+
+prints the first field of every record.
+
+\1f
+File: gawk.info, Node: Using Shell Variables, Next: Action Overview, Prev: Pattern Overview, Up: Patterns and Actions
+
+6.2 Using Shell Variables in Programs
+=====================================
+
+`awk' programs are often used as components in larger programs written
+in shell. For example, it is very common to use a shell variable to
+hold a pattern that the `awk' program searches for. There are two ways
+to get the value of the shell variable into the body of the `awk'
+program.
+
+The most common method is to use shell quoting to substitute the
+variable's value into the program inside the script. For example, in
+the following program:
+
+ echo -n "Enter search pattern: "
+ read pattern
+ awk "/$pattern/ "'{ nmatches++ }
+ END { print nmatches, "found" }' /path/to/data
+
+the `awk' program consists of two pieces of quoted text that are
+concatenated together to form the program. The first part is
+double-quoted, which allows substitution of the `pattern' variable
+inside the quotes. The second part is single-quoted.
+
+Variable substitution via quoting works, but can be potentially messy.
+It requires a good understanding of the shell's quoting rules (*note
+Quoting::), and it's often difficult to correctly match up the quotes
+when reading the program.
+
+A better method is to use `awk''s variable assignment feature (*note
+Assignment Options::) to assign the shell variable's value to an `awk'
+variable's value. Then use dynamic regexps to match the pattern (*note
+Computed Regexps::). The following shows how to redo the previous
+example using this technique:
+
+ echo -n "Enter search pattern: "
+ read pattern
+ awk -v pat="$pattern" '$0 ~ pat { nmatches++ }
+ END { print nmatches, "found" }' /path/to/data
+
+Now, the `awk' program is just one single-quoted string. The
+assignment `-v pat="$pattern"' still requires double quotes, in case
+there is whitespace in the value of `$pattern'. The `awk' variable
+`pat' could be named `pattern' too, but that would be more confusing.
+Using a variable also provides more flexibility, since the variable can
+be used anywhere inside the program--for printing, as an array
+subscript, or for any other use--without requiring the quoting tricks
+at every point in the program.
+
+\1f
+File: gawk.info, Node: Action Overview, Next: Statements, Prev: Using Shell Variables, Up: Patterns and Actions
+
+6.3 Actions
+===========
+
+An `awk' program or script consists of a series of rules and function
+definitions interspersed. (Functions are described later. *Note
+User-defined::.) A rule contains a pattern and an action, either of
+which (but not both) may be omitted. The purpose of the "action" is to
+tell `awk' what to do once a match for the pattern is found. Thus, in
+outline, an `awk' program generally looks like this:
+
+ [PATTERN] [{ ACTION }]
+ [PATTERN] [{ ACTION }]
+ ...
+ function NAME(ARGS) { ... }
+ ...
+
+An action consists of one or more `awk' "statements", enclosed in curly
+braces (`{...}'). Each statement specifies one thing to do. The
+statements are separated by newlines or semicolons. The curly braces
+around an action must be used even if the action contains only one
+statement, or if it contains no statements at all. However, if you
+omit the action entirely, omit the curly braces as well. An omitted
+action is equivalent to `{ print $0 }':
+
+ /foo/ { } match `foo', do nothing -- empty action
+ /foo/ match `foo', print the record -- omitted action
+
+The following types of statements are supported in `awk':
+
+Expressions
+ Call functions or assign values to variables (*note
+ Expressions::). Executing this kind of statement simply computes
+ the value of the expression. This is useful when the expression
+ has side effects (*note Assignment Ops::).
+
+Control statements
+ Specify the control flow of `awk' programs. The `awk' language
+ gives you C-like constructs (`if', `for', `while', and `do') as
+ well as a few special ones (*note Statements::).
+
+Compound statements
+ Consist of one or more statements enclosed in curly braces. A
+ compound statement is used in order to put several statements
+ together in the body of an `if', `while', `do', or `for' statement.
+
+Input statements
+ Use the `getline' command (*note Getline::). Also supplied in
+ `awk' are the `next' statement (*note Next Statement::), and the
+ `nextfile' statement (*note Nextfile Statement::).
+
+Output statements
+ Such as `print' and `printf'. *Note Printing::.
+
+Deletion statements
+ For deleting array elements. *Note Delete::.
+
+\1f
+File: gawk.info, Node: Statements, Next: Built-in Variables, Prev: Action Overview, Up: Patterns and Actions
+
+6.4 Control Statements in Actions
+=================================
+
+"Control statements", such as `if', `while', and so on, control the
+flow of execution in `awk' programs. Most of the control statements in
+`awk' are patterned on similar statements in C.
+
+All the control statements start with special keywords, such as `if'
+and `while', to distinguish them from simple expressions. Many control
+statements contain other statements. For example, the `if' statement
+contains another statement that may or may not be executed. The
+contained statement is called the "body". To include more than one
+statement in the body, group them into a single "compound statement"
+with curly braces, separating them with newlines or semicolons.
+
+* Menu:
+
+* If Statement:: Conditionally execute some `awk'
+ statements.
+* While Statement:: Loop until some condition is satisfied.
+* Do Statement:: Do specified action while looping until some
+ condition is satisfied.
+* For Statement:: Another looping statement, that provides
+ initialization and increment clauses.
+* Switch Statement:: Switch/case evaluation for conditional
+ execution of statements based on a value.
+* Break Statement:: Immediately exit the innermost enclosing loop.
+* Continue Statement:: Skip to the end of the innermost enclosing
+ loop.
+* Next Statement:: Stop processing the current input record.
+* Nextfile Statement:: Stop processing the current file.
+* Exit Statement:: Stop execution of `awk'.
+
+\1f
+File: gawk.info, Node: If Statement, Next: While Statement, Up: Statements
+
+6.4.1 The `if'-`else' Statement
+-------------------------------
+
+The `if'-`else' statement is `awk''s decision-making statement. It
+looks like this:
+
+ if (CONDITION) THEN-BODY [else ELSE-BODY]
+
+The CONDITION is an expression that controls what the rest of the
+statement does. If the CONDITION is true, THEN-BODY is executed;
+otherwise, ELSE-BODY is executed. The `else' part of the statement is
+optional. The condition is considered false if its value is zero or
+the null string; otherwise, the condition is true. Refer to the
+following:
+
+ if (x % 2 == 0)
+ print "x is even"
+ else
+ print "x is odd"
+
+In this example, if the expression `x % 2 == 0' is true (that is, if
+the value of `x' is evenly divisible by two), then the first `print'
+statement is executed; otherwise, the second `print' statement is
+executed. If the `else' keyword appears on the same line as THEN-BODY
+and THEN-BODY is not a compound statement (i.e., not surrounded by
+curly braces), then a semicolon must separate THEN-BODY from the `else'.
+To illustrate this, the previous example can be rewritten as:
+
+ if (x % 2 == 0) print "x is even"; else
+ print "x is odd"
+
+If the `;' is left out, `awk' can't interpret the statement and it
+produces a syntax error. Don't actually write programs this way,
+because a human reader might fail to see the `else' if it is not the
+first thing on its line.
+
+\1f
+File: gawk.info, Node: While Statement, Next: Do Statement, Prev: If Statement, Up: Statements
+
+6.4.2 The `while' Statement
+---------------------------
+
+In programming, a "loop" is a part of a program that can be executed
+two or more times in succession. The `while' statement is the simplest
+looping statement in `awk'. It repeatedly executes a statement as long
+as a condition is true. For example:
+
+ while (CONDITION)
+ BODY
+
+BODY is a statement called the "body" of the loop, and CONDITION is an
+expression that controls how long the loop keeps running. The first
+thing the `while' statement does is test the CONDITION. If the
+CONDITION is true, it executes the statement BODY. (The CONDITION is
+true when the value is not zero and not a null string.) After BODY has
+been executed, CONDITION is tested again, and if it is still true, BODY
+is executed again. This process repeats until the CONDITION is no
+longer true. If the CONDITION is initially false, the body of the loop
+is never executed and `awk' continues with the statement following the
+loop. This example prints the first three fields of each record, one
+per line:
+
+ awk '{ i = 1
+ while (i <= 3) {
+ print $i
+ i++
+ }
+ }' inventory-shipped
+
+The body of this loop is a compound statement enclosed in braces,
+containing two statements. The loop works in the following manner:
+first, the value of `i' is set to one. Then, the `while' statement
+tests whether `i' is less than or equal to three. This is true when
+`i' equals one, so the `i'-th field is printed. Then the `i++'
+increments the value of `i' and the loop repeats. The loop terminates
+when `i' reaches four.
+
+A newline is not required between the condition and the body; however
+using one makes the program clearer unless the body is a compound
+statement or else is very simple. The newline after the open-brace
+that begins the compound statement is not required either, but the
+program is harder to read without it.
+
+\1f
+File: gawk.info, Node: Do Statement, Next: For Statement, Prev: While Statement, Up: Statements
+
+6.4.3 The `do'-`while' Statement
+--------------------------------
+
+The `do' loop is a variation of the `while' looping statement. The
+`do' loop executes the BODY once and then repeats the BODY as long as
+the CONDITION is true. It looks like this:
+
+ do
+ BODY
+ while (CONDITION)
+
+Even if the CONDITION is false at the start, the BODY is executed at
+least once (and only once, unless executing BODY makes CONDITION true).
+Contrast this with the corresponding `while' statement:
+
+ while (CONDITION)
+ BODY
+
+This statement does not execute BODY even once if the CONDITION is
+false to begin with. The following is an example of a `do' statement:
+
+ { i = 1
+ do {
+ print $0
+ i++
+ } while (i <= 10)
+ }
+
+This program prints each input record 10 times. However, it isn't a
+very realistic example, since in this case an ordinary `while' would do
+just as well. This situation reflects actual experience; only
+occasionally is there a real use for a `do' statement.
+
+\1f
+File: gawk.info, Node: For Statement, Next: Switch Statement, Prev: Do Statement, Up: Statements
+
+6.4.4 The `for' Statement
+-------------------------
+
+The `for' statement makes it more convenient to count iterations of a
+loop. The general form of the `for' statement looks like this:
+
+ for (INITIALIZATION; CONDITION; INCREMENT)
+ BODY
+
+The INITIALIZATION, CONDITION, and INCREMENT parts are arbitrary `awk'
+expressions, and BODY stands for any `awk' statement.
+
+The `for' statement starts by executing INITIALIZATION. Then, as long
+as the CONDITION is true, it repeatedly executes BODY and then
+INCREMENT. Typically, INITIALIZATION sets a variable to either zero or
+one, INCREMENT adds one to it, and CONDITION compares it against the
+desired number of iterations. For example:
+
+ awk '{ for (i = 1; i <= 3; i++)
+ print $i
+ }' inventory-shipped
+
+This prints the first three fields of each input record, with one field
+per line.
+
+It isn't possible to set more than one variable in the INITIALIZATION
+part without using a multiple assignment statement such as `x = y = 0'.
+This makes sense only if all the initial values are equal. (But it is
+possible to initialize additional variables by writing their
+assignments as separate statements preceding the `for' loop.)
+
+The same is true of the INCREMENT part. Incrementing additional
+variables requires separate statements at the end of the loop. The C
+compound expression, using C's comma operator, is useful in this
+context but it is not supported in `awk'.
+
+Most often, INCREMENT is an increment expression, as in the previous
+example. But this is not required; it can be any expression
+whatsoever. For example, the following statement prints all the powers
+of two between 1 and 100:
+
+ for (i = 1; i <= 100; i *= 2)
+ print i
+
+If there is nothing to be done, any of the three expressions in the
+parentheses following the `for' keyword may be omitted. Thus,
+`for (; x > 0;)' is equivalent to `while (x > 0)'. If the CONDITION is
+omitted, it is treated as true, effectively yielding an "infinite loop"
+(i.e., a loop that never terminates).
+
+In most cases, a `for' loop is an abbreviation for a `while' loop, as
+shown here:
+
+ INITIALIZATION
+ while (CONDITION) {
+ BODY
+ INCREMENT
+ }
+
+The only exception is when the `continue' statement (*note Continue
+Statement::) is used inside the loop. Changing a `for' statement to a
+`while' statement in this way can change the effect of the `continue'
+statement inside the loop.
+
+The `awk' language has a `for' statement in addition to a `while'
+statement because a `for' loop is often both less work to type and more
+natural to think of. Counting the number of iterations is very common
+in loops. It can be easier to think of this counting as part of
+looping rather than as something to do inside the loop.
+
+There is an alternate version of the `for' loop, for iterating over all
+the indices of an array:
+
+ for (i in array)
+ DO SOMETHING WITH array[i]
+
+*Note Scanning an Array::, for more information on this version of the
+`for' loop.
+
+\1f
+File: gawk.info, Node: Switch Statement, Next: Break Statement, Prev: For Statement, Up: Statements
+
+6.4.5 The `switch' Statement
+----------------------------
+
+ NOTE: This node describes an experimental feature added in `gawk'
+ 3.1.3. It is _not_ enabled by default. To enable it, use the
+ `--enable-switch' option to `configure' when `gawk' is being
+ configured and built. *Note Additional Configuration Options::,
+ for more information.
+
+The `switch' statement allows the evaluation of an expression and the
+execution of statements based on a `case' match. Case statements are
+checked for a match in the order they are defined. If no suitable
+`case' is found, the `default' section is executed, if supplied.
+
+Each `case' contains a single constant, be it numeric, string, or
+regexp. The `switch' expression is evaluated, and then each `case''s
+constant is compared against the result in turn. The type of constant
+determines the comparison: numeric or string do the usual comparisons.
+A regexp constant does a regular expression match against the string
+value of the original expression. The general form of the `switch'
+statement looks like this:
+
+ switch (EXPRESSION) {
+ case VALUE OR REGULAR EXPRESSION:
+ CASE-BODY
+ default:
+ DEFAULT-BODY
+ }
+
+Control flow in the `switch' statement works as it does in C. Once a
+match to a given case is made, case statement bodies are executed until
+a `break', `continue', `next', `nextfile' or `exit' is encountered, or
+the end of the `switch' statement itself. For example:
+
+ switch (NR * 2 + 1) {
+ case 3:
+ case "11":
+ print NR - 1
+ break
+
+ case /2[[:digit:]]+/:
+ print NR
+
+ default:
+ print NR + 1
+
+ case -1:
+ print NR * -1
+ }
+
+Note that if none of the statements specified above halt execution of a
+matched `case' statement, execution falls through to the next `case'
+until execution halts. In the above example, for any case value
+starting with `2' followed by one or more digits, the `print' statement
+is executed and then falls through into the `default' section,
+executing its `print' statement. In turn, the -1 case will also be
+executed since the `default' does not halt execution.
+
+\1f
+File: gawk.info, Node: Break Statement, Next: Continue Statement, Prev: Switch Statement, Up: Statements
+
+6.4.6 The `break' Statement
+---------------------------
+
+The `break' statement jumps out of the innermost `for', `while', or
+`do' loop that encloses it. The following example finds the smallest
+divisor of any integer, and also identifies prime numbers:
+
+ # find smallest divisor of num
+ {
+ num = $1
+ for (div = 2; div*div <= num; div++)
+ if (num % div == 0)
+ break
+ if (num % div == 0)
+ printf "Smallest divisor of %d is %d\n", num, div
+ else
+ printf "%d is prime\n", num
+ }
+
+When the remainder is zero in the first `if' statement, `awk'
+immediately "breaks out" of the containing `for' loop. This means that
+`awk' proceeds immediately to the statement following the loop and
+continues processing. (This is very different from the `exit'
+statement, which stops the entire `awk' program. *Note Exit
+Statement::.)
+
+Th following program illustrates how the CONDITION of a `for' or
+`while' statement could be replaced with a `break' inside an `if':
+
+ # find smallest divisor of num
+ {
+ num = $1
+ for (div = 2; ; div++) {
+ if (num % div == 0) {
+ printf "Smallest divisor of %d is %d\n", num, div
+ break
+ }
+ if (div*div > num) {
+ printf "%d is prime\n", num
+ break
+ }
+ }
+ }
+
+The `break' statement has no meaning when used outside the body of a
+loop. However, although it was never documented, historical
+implementations of `awk' treated the `break' statement outside of a
+loop as if it were a `next' statement (*note Next Statement::). Recent
+versions of Unix `awk' no longer allow this usage. `gawk' supports
+this use of `break' only if `--traditional' has been specified on the
+command line (*note Options::). Otherwise, it is treated as an error,
+since the POSIX standard specifies that `break' should only be used
+inside the body of a loop. (d.c.)
+
+\1f
+File: gawk.info, Node: Continue Statement, Next: Next Statement, Prev: Break Statement, Up: Statements
+
+6.4.7 The `continue' Statement
+------------------------------
+
+As with `break', the `continue' statement is used only inside `for',
+`while', and `do' loops. It skips over the rest of the loop body,
+causing the next cycle around the loop to begin immediately. Contrast
+this with `break', which jumps out of the loop altogether.
+
+The `continue' statement in a `for' loop directs `awk' to skip the rest
+of the body of the loop and resume execution with the
+increment-expression of the `for' statement. The following program
+illustrates this fact:
+
+ BEGIN {
+ for (x = 0; x <= 20; x++) {
+ if (x == 5)
+ continue
+ printf "%d ", x
+ }
+ print ""
+ }
+
+This program prints all the numbers from 0 to 20--except for 5, for
+which the `printf' is skipped. Because the increment `x++' is not
+skipped, `x' does not remain stuck at 5. Contrast the `for' loop from
+the previous example with the following `while' loop:
+
+ BEGIN {
+ x = 0
+ while (x <= 20) {
+ if (x == 5)
+ continue
+ printf "%d ", x
+ x++
+ }
+ print ""
+ }
+
+This program loops forever once `x' reaches 5.
+
+The `continue' statement has no meaning when used outside the body of a
+loop. Historical versions of `awk' treated a `continue' statement
+outside a loop the same way they treated a `break' statement outside a
+loop: as if it were a `next' statement (*note Next Statement::).
+Recent versions of Unix `awk' no longer work this way, and `gawk'
+allows it only if `--traditional' is specified on the command line
+(*note Options::). Just like the `break' statement, the POSIX standard
+specifies that `continue' should only be used inside the body of a loop.
+(d.c.)
+
+\1f
+File: gawk.info, Node: Next Statement, Next: Nextfile Statement, Prev: Continue Statement, Up: Statements
+
+6.4.8 The `next' Statement
+--------------------------
+
+The `next' statement forces `awk' to immediately stop processing the
+current record and go on to the next record. This means that no
+further rules are executed for the current record, and the rest of the
+current rule's action isn't executed.
+
+Contrast this with the effect of the `getline' function (*note
+Getline::). That also causes `awk' to read the next record
+immediately, but it does not alter the flow of control in any way
+(i.e., the rest of the current action executes with a new input record).
+
+At the highest level, `awk' program execution is a loop that reads an
+input record and then tests each rule's pattern against it. If you
+think of this loop as a `for' statement whose body contains the rules,
+then the `next' statement is analogous to a `continue' statement. It
+skips to the end of the body of this implicit loop and executes the
+increment (which reads another record).
+
+For example, suppose an `awk' program works only on records with four
+fields, and it shouldn't fail when given bad input. To avoid
+complicating the rest of the program, write a "weed out" rule near the
+beginning, in the following manner:
+
+ NF != 4 {
+ err = sprintf("%s:%d: skipped: NF != 4\n", FILENAME, FNR)
+ print err > "/dev/stderr"
+ next
+ }
+
+Because of the `next' statement, the program's subsequent rules won't
+see the bad record. The error message is redirected to the standard
+error output stream, as error messages should be. For more detail see
+*Note Special Files::.
+
+According to the POSIX standard, the behavior is undefined if the
+`next' statement is used in a `BEGIN' or `END' rule. `gawk' treats it
+as a syntax error. Although POSIX permits it, some other `awk'
+implementations don't allow the `next' statement inside function bodies
+(*note User-defined::). Just as with any other `next' statement, a
+`next' statement inside a function body reads the next record and
+starts processing it with the first rule in the program. If the `next'
+statement causes the end of the input to be reached, then the code in
+any `END' rules is executed. *Note BEGIN/END::.
+
+\1f
+File: gawk.info, Node: Nextfile Statement, Next: Exit Statement, Prev: Next Statement, Up: Statements
+
+6.4.9 Using `gawk''s `nextfile' Statement
+-----------------------------------------
+
+`gawk' provides the `nextfile' statement, which is similar to the
+`next' statement. However, instead of abandoning processing of the
+current record, the `nextfile' statement instructs `gawk' to stop
+processing the current data file.
+
+The `nextfile' statement is a `gawk' extension. In most other `awk'
+implementations, or if `gawk' is in compatibility mode (*note
+Options::), `nextfile' is not special.
+
+Upon execution of the `nextfile' statement, `FILENAME' is updated to
+the name of the next data file listed on the command line, `FNR' is
+reset to one, `ARGIND' is incremented, and processing starts over with
+the first rule in the program. (`ARGIND' hasn't been introduced yet.
+*Note Built-in Variables::.) If the `nextfile' statement causes the
+end of the input to be reached, then the code in any `END' rules is
+executed. *Note BEGIN/END::.
+
+The `nextfile' statement is useful when there are many data files to
+process but it isn't necessary to process every record in every file.
+Normally, in order to move on to the next data file, a program has to
+continue scanning the unwanted records. The `nextfile' statement
+accomplishes this much more efficiently.
+
+While one might think that `close(FILENAME)' would accomplish the same
+as `nextfile', this isn't true. `close' is reserved for closing files,
+pipes, and coprocesses that are opened with redirections. It is not
+related to the main processing that `awk' does with the files listed in
+`ARGV'.
+
+If it's necessary to use an `awk' version that doesn't support
+`nextfile', see *Note Nextfile Function::, for a user-defined function
+that simulates the `nextfile' statement.
+
+The current version of the Bell Laboratories `awk' (*note Other
+Versions::) also supports `nextfile'. However, it doesn't allow the
+`nextfile' statement inside function bodies (*note User-defined::).
+`gawk' does; a `nextfile' inside a function body reads the next record
+and starts processing it with the first rule in the program, just as
+any other `nextfile' statement.
+
+*Caution:* Versions of `gawk' prior to 3.0 used two words (`next
+file') for the `nextfile' statement. In version 3.0, this was changed
+to one word, because the treatment of `file' was inconsistent. When it
+appeared after `next', `file' was a keyword; otherwise, it was a
+regular identifier. The old usage is no longer accepted; `next file'
+generates a syntax error.
+
+\1f
+File: gawk.info, Node: Exit Statement, Prev: Nextfile Statement, Up: Statements
+
+6.4.10 The `exit' Statement
+---------------------------
+
+The `exit' statement causes `awk' to immediately stop executing the
+current rule and to stop processing input; any remaining input is
+ignored. The `exit' statement is written as follows:
+
+ exit [RETURN CODE]
+
+When an `exit' statement is executed from a `BEGIN' rule, the program
+stops processing everything immediately. No input records are read.
+However, if an `END' rule is present, as part of executing the `exit'
+statement, the `END' rule is executed (*note BEGIN/END::). If `exit'
+is used as part of an `END' rule, it causes the program to stop
+immediately.
+
+An `exit' statement that is not part of a `BEGIN' or `END' rule stops
+the execution of any further automatic rules for the current record,
+skips reading any remaining input records, and executes the `END' rule
+if there is one.
+
+In such a case, if you don't want the `END' rule to do its job, set a
+variable to nonzero before the `exit' statement and check that variable
+in the `END' rule. *Note Assert Function::, for an example that does
+this.
+
+If an argument is supplied to `exit', its value is used as the exit
+status code for the `awk' process. If no argument is supplied, `exit'
+returns status zero (success). In the case where an argument is
+supplied to a first `exit' statement, and then `exit' is called a
+second time from an `END' rule with no argument, `awk' uses the
+previously supplied exit value. (d.c.)
+
+For example, suppose an error condition occurs that is difficult or
+impossible to handle. Conventionally, programs report this by exiting
+with a nonzero status. An `awk' program can do this using an `exit'
+statement with a nonzero argument, as shown in the following example:
+
+ BEGIN {
+ if (("date" | getline date_now) <= 0) {
+ print "Can't get system date" > "/dev/stderr"
+ exit 1
+ }
+ print "current date is", date_now
+ close("date")
+ }
+
+\1f
+File: gawk.info, Node: Built-in Variables, Prev: Statements, Up: Patterns and Actions
+
+6.5 Built-in Variables
+======================
+
+Most `awk' variables are available to use for your own purposes; they
+never change unless your program assigns values to them, and they never
+affect anything unless your program examines them. However, a few
+variables in `awk' have special built-in meanings. `awk' examines some
+of these automatically, so that they enable you to tell `awk' how to do
+certain things. Others are set automatically by `awk', so that they
+carry information from the internal workings of `awk' to your program.
+
+This minor node documents all the built-in variables of `gawk', most of
+which are also documented in the chapters describing their areas of
+activity.
+
+* Menu:
+
+* User-modified:: Built-in variables that you change to control
+ `awk'.
+* Auto-set:: Built-in variables where `awk' gives
+ you information.
+* ARGC and ARGV:: Ways to use `ARGC' and `ARGV'.
+
+\1f
+File: gawk.info, Node: User-modified, Next: Auto-set, Up: Built-in Variables
+
+6.5.1 Built-in Variables That Control `awk'
+-------------------------------------------
+
+The following is an alphabetical list of variables that you can change
+to control how `awk' does certain things. The variables that are
+specific to `gawk' are marked with a pound sign (`#').
+
+`BINMODE #'
+ On non-POSIX systems, this variable specifies use of binary mode
+ for all I/O. Numeric values of one, two, or three specify that
+ input files, output files, or all files, respectively, should use
+ binary I/O. Alternatively, string values of `"r"' or `"w"'
+ specify that input files and output files, respectively, should
+ use binary I/O. A string value of `"rw"' or `"wr"' indicates that
+ all files should use binary I/O. Any other string value is
+ equivalent to `"rw"', but `gawk' generates a warning message.
+ `BINMODE' is described in more detail in *Note PC Using::.
+
+ This variable is a `gawk' extension. In other `awk'
+ implementations (except `mawk', *note Other Versions::), or if
+ `gawk' is in compatibility mode (*note Options::), it is not
+ special.
+
+`CONVFMT'
+ This string controls conversion of numbers to strings (*note
+ Conversion::). It works by being passed, in effect, as the first
+ argument to the `sprintf' function (*note String Functions::).
+ Its default value is `"%.6g"'. `CONVFMT' was introduced by the
+ POSIX standard.
+
+`FIELDWIDTHS #'
+ This is a space-separated list of columns that tells `gawk' how to
+ split input with fixed columnar boundaries. Assigning a value to
+ `FIELDWIDTHS' overrides the use of `FS' for field splitting.
+ *Note Constant Size::, for more information.
+
+ If `gawk' is in compatibility mode (*note Options::), then
+ `FIELDWIDTHS' has no special meaning, and field-splitting
+ operations occur based exclusively on the value of `FS'.
+
+`FS'
+ This is the input field separator (*note Field Separators::). The
+ value is a single-character string or a multi-character regular
+ expression that matches the separations between fields in an input
+ record. If the value is the null string (`""'), then each
+ character in the record becomes a separate field. (This behavior
+ is a `gawk' extension. POSIX `awk' does not specify the behavior
+ when `FS' is the null string.)
+
+ The default value is `" "', a string consisting of a single space.
+ As a special exception, this value means that any sequence of
+ spaces, tabs, and/or newlines is a single separator.(1) It also
+ causes spaces, tabs, and newlines at the beginning and end of a
+ record to be ignored.
+
+ You can set the value of `FS' on the command line using the `-F'
+ option:
+
+ awk -F, 'PROGRAM' INPUT-FILES
+
+ If `gawk' is using `FIELDWIDTHS' for field splitting, assigning a
+ value to `FS' causes `gawk' to return to the normal, `FS'-based
+ field splitting. An easy way to do this is to simply say `FS =
+ FS', perhaps with an explanatory comment.
+
+`IGNORECASE #'
+ If `IGNORECASE' is nonzero or non-null, then all string comparisons
+ and all regular expression matching are case independent. Thus,
+ regexp matching with `~' and `!~', as well as the `gensub',
+ `gsub', `index', `match', `split', and `sub' functions, record
+ termination with `RS', and field splitting with `FS', all ignore
+ case when doing their particular regexp operations. However, the
+ value of `IGNORECASE' does _not_ affect array subscripting and it
+ does not affect field splitting when using a single-character
+ field separator. *Note Case-sensitivity::.
+
+ If `gawk' is in compatibility mode (*note Options::), then
+ `IGNORECASE' has no special meaning. Thus, string and regexp
+ operations are always case-sensitive.
+
+`LINT #'
+ When this variable is true (nonzero or non-null), `gawk' behaves
+ as if the `--lint' command-line option is in effect. (*note
+ Options::). With a value of `"fatal"', lint warnings become fatal
+ errors. With a value of `"invalid"', only warnings about things
+ that are actually invalid are issued. (This is not fully
+ implemented yet.) Any other true value prints nonfatal warnings.
+ Assigning a false value to `LINT' turns off the lint warnings.
+
+ This variable is a `gawk' extension. It is not special in other
+ `awk' implementations. Unlike the other special variables,
+ changing `LINT' does affect the production of lint warnings, even
+ if `gawk' is in compatibility mode. Much as the `--lint' and
+ `--traditional' options independently control different aspects of
+ `gawk''s behavior, the control of lint warnings during program
+ execution is independent of the flavor of `awk' being executed.
+
+`OFMT'
+ This string controls conversion of numbers to strings (*note
+ Conversion::) for printing with the `print' statement. It works
+ by being passed as the first argument to the `sprintf' function
+ (*note String Functions::). Its default value is `"%.6g"'.
+ Earlier versions of `awk' also used `OFMT' to specify the format
+ for converting numbers to strings in general expressions; this is
+ now done by `CONVFMT'.
+
+`OFS'
+ This is the output field separator (*note Output Separators::).
+ It is output between the fields printed by a `print' statement.
+ Its default value is `" "', a string consisting of a single space.
+
+`ORS'
+ This is the output record separator. It is output at the end of
+ every `print' statement. Its default value is `"\n"', the newline
+ character. (*Note Output Separators::.)
+
+`RS'
+ This is `awk''s input record separator. Its default value is a
+ string containing a single newline character, which means that an
+ input record consists of a single line of text. It can also be
+ the null string, in which case records are separated by runs of
+ blank lines. If it is a regexp, records are separated by matches
+ of the regexp in the input text. (*Note Records::.)
+
+ The ability for `RS' to be a regular expression is a `gawk'
+ extension. In most other `awk' implementations, or if `gawk' is
+ in compatibility mode (*note Options::), just the first character
+ of `RS''s value is used.
+
+`SUBSEP'
+ This is the subscript separator. It has the default value of
+ `"\034"' and is used to separate the parts of the indices of a
+ multidimensional array. Thus, the expression `foo["A", "B"]'
+ really accesses `foo["A\034B"]' (*note Multi-dimensional::).
+
+`TEXTDOMAIN #'
+ This variable is used for internationalization of programs at the
+ `awk' level. It sets the default text domain for specially marked
+ string constants in the source text, as well as for the
+ `dcgettext', `dcngettext' and `bindtextdomain' functions (*note
+ Internationalization::). The default value of `TEXTDOMAIN' is
+ `"messages"'.
+
+ This variable is a `gawk' extension. In other `awk'
+ implementations, or if `gawk' is in compatibility mode (*note
+ Options::), it is not special.
+
+---------- Footnotes ----------
+
+(1) In POSIX `awk', newline does not count as whitespace.
+
+\1f
+File: gawk.info, Node: Auto-set, Next: ARGC and ARGV, Prev: User-modified, Up: Built-in Variables
+
+6.5.2 Built-in Variables That Convey Information
+------------------------------------------------
+
+The following is an alphabetical list of variables that `awk' sets
+automatically on certain occasions in order to provide information to
+your program. The variables that are specific to `gawk' are marked
+with a pound sign (`#').
+
+`ARGC, ARGV'
+ The command-line arguments available to `awk' programs are stored
+ in an array called `ARGV'. `ARGC' is the number of command-line
+ arguments present. *Note Other Arguments::. Unlike most `awk'
+ arrays, `ARGV' is indexed from 0 to `ARGC' - 1. In the following
+ example:
+
+ $ awk 'BEGIN {
+ > for (i = 0; i < ARGC; i++)
+ > print ARGV[i]
+ > }' inventory-shipped BBS-list
+ -| awk
+ -| inventory-shipped
+ -| BBS-list
+
+ `ARGV[0]' contains `"awk"', `ARGV[1]' contains
+ `"inventory-shipped"', and `ARGV[2]' contains `"BBS-list"'. The
+ value of `ARGC' is three, one more than the index of the last
+ element in `ARGV', because the elements are numbered from zero.
+
+ The names `ARGC' and `ARGV', as well as the convention of indexing
+ the array from 0 to `ARGC' - 1, are derived from the C language's
+ method of accessing command-line arguments.
+
+ The value of `ARGV[0]' can vary from system to system. Also, you
+ should note that the program text is _not_ included in `ARGV', nor
+ are any of `awk''s command-line options. *Note ARGC and ARGV::,
+ for information about how `awk' uses these variables.
+
+`ARGIND #'
+ The index in `ARGV' of the current file being processed. Every
+ time `gawk' opens a new data file for processing, it sets `ARGIND'
+ to the index in `ARGV' of the file name. When `gawk' is
+ processing the input files, `FILENAME == ARGV[ARGIND]' is always
+ true.
+
+ This variable is useful in file processing; it allows you to tell
+ how far along you are in the list of data files as well as to
+ distinguish between successive instances of the same file name on
+ the command line.
+
+ While you can change the value of `ARGIND' within your `awk'
+ program, `gawk' automatically sets it to a new value when the next
+ file is opened.
+
+ This variable is a `gawk' extension. In other `awk'
+ implementations, or if `gawk' is in compatibility mode (*note
+ Options::), it is not special.
+
+`ENVIRON'
+ An associative array that contains the values of the environment.
+ The array indices are the environment variable names; the elements
+ are the values of the particular environment variables. For
+ example, `ENVIRON["HOME"]' might be `/home/arnold'. Changing this
+ array does not affect the environment passed on to any programs
+ that `awk' may spawn via redirection or the `system' function.
+
+ Some operating systems may not have environment variables. On
+ such systems, the `ENVIRON' array is empty (except for
+ `ENVIRON["AWKPATH"]', *note AWKPATH Variable::).
+
+`ERRNO #'
+ If a system error occurs during a redirection for `getline',
+ during a read for `getline', or during a `close' operation, then
+ `ERRNO' contains a string describing the error.
+
+ `ERRNO' works similarly to the C variable `errno'. In particular
+ `gawk' _never_ clears it (sets it to zero or `""'). Thus, you
+ should only expect its value to be meaningful when an I/O
+ operation returns a failure value, such as `getline' returning -1.
+ You are, of course, free to clear it yourself before doing an I/O
+ operation.
+
+ This variable is a `gawk' extension. In other `awk'
+ implementations, or if `gawk' is in compatibility mode (*note
+ Options::), it is not special.
+
+`FILENAME'
+ The name of the file that `awk' is currently reading. When no
+ data files are listed on the command line, `awk' reads from the
+ standard input and `FILENAME' is set to `"-"'. `FILENAME' is
+ changed each time a new file is read (*note Reading Files::).
+ Inside a `BEGIN' rule, the value of `FILENAME' is `""', since
+ there are no input files being processed yet.(1) (d.c.) Note,
+ though, that using `getline' (*note Getline::) inside a `BEGIN'
+ rule can give `FILENAME' a value.
+
+`FNR'
+ The current record number in the current file. `FNR' is
+ incremented each time a new record is read (*note Getline::). It
+ is reinitialized to zero each time a new input file is started.
+
+`NF'
+ The number of fields in the current input record. `NF' is set
+ each time a new record is read, when a new field is created or
+ when `$0' changes (*note Fields::).
+
+ Unlike most of the variables described in this node, assigning a
+ value to `NF' has the potential to affect `awk''s internal
+ workings. In particular, assignments to `NF' can be used to
+ create or remove fields from the current record: *Note Changing
+ Fields::.
+
+`NR'
+ The number of input records `awk' has processed since the
+ beginning of the program's execution (*note Records::). `NR' is
+ incremented each time a new record is read.
+
+`PROCINFO #'
+ The elements of this array provide access to information about the
+ running `awk' program. The following elements (listed
+ alphabetically) are guaranteed to be available:
+
+ `PROCINFO["egid"]'
+ The value of the `getegid' system call.
+
+ `PROCINFO["euid"]'
+ The value of the `geteuid' system call.
+
+ `PROCINFO["FS"]'
+ This is `"FS"' if field splitting with `FS' is in effect, or
+ it is `"FIELDWIDTHS"' if field splitting with `FIELDWIDTHS'
+ is in effect.
+
+ `PROCINFO["gid"]'
+ The value of the `getgid' system call.
+
+ `PROCINFO["pgrpid"]'
+ The process group ID of the current process.
+
+ `PROCINFO["pid"]'
+ The process ID of the current process.
+
+ `PROCINFO["ppid"]'
+ The parent process ID of the current process.
+
+ `PROCINFO["uid"]'
+ The value of the `getuid' system call.
+
+ `PROCINFO["version"]'
+ The version of `gawk'. This is available from version 3.1.4
+ and later.
+
+ On some systems, there may be elements in the array, `"group1"'
+ through `"groupN"' for some N. N is the number of supplementary
+ groups that the process has. Use the `in' operator to test for
+ these elements (*note Reference to Elements::).
+
+ This array is a `gawk' extension. In other `awk' implementations,
+ or if `gawk' is in compatibility mode (*note Options::), it is not
+ special.
+
+`RLENGTH'
+ The length of the substring matched by the `match' function (*note
+ String Functions::). `RLENGTH' is set by invoking the `match'
+ function. Its value is the length of the matched string, or -1 if
+ no match is found.
+
+`RSTART'
+ The start-index in characters of the substring that is matched by
+ the `match' function (*note String Functions::). `RSTART' is set
+ by invoking the `match' function. Its value is the position of
+ the string where the matched substring starts, or zero if no match
+ was found.
+
+`RT #'
+ This is set each time a record is read. It contains the input text
+ that matched the text denoted by `RS', the record separator.
+
+ This variable is a `gawk' extension. In other `awk'
+ implementations, or if `gawk' is in compatibility mode (*note
+ Options::), it is not special.
+
+Advanced Notes: Changing `NR' and `FNR'
+---------------------------------------
+
+`awk' increments `NR' and `FNR' each time it reads a record, instead of
+setting them to the absolute value of the number of records read. This
+means that a program can change these variables and their new values
+are incremented for each record. (d.c.) This is demonstrated in the
+following example:
+
+ $ echo '1
+ > 2
+ > 3
+ > 4' | awk 'NR == 2 { NR = 17 }
+ > { print NR }'
+ -| 1
+ -| 17
+ -| 18
+ -| 19
+
+Before `FNR' was added to the `awk' language (*note V7/SVR3.1::), many
+`awk' programs used this feature to track the number of records in a
+file by resetting `NR' to zero when `FILENAME' changed.
+
+---------- Footnotes ----------
+
+(1) Some early implementations of Unix `awk' initialized `FILENAME' to
+`"-"', even if there were data files to be processed. This behavior was
+incorrect and should not be relied upon in your programs.
+
+\1f
+File: gawk.info, Node: ARGC and ARGV, Prev: Auto-set, Up: Built-in Variables
+
+6.5.4 Using `ARGC' and `ARGV'
+-----------------------------
+
+*Note Auto-set::, presented the following program describing the
+information contained in `ARGC' and `ARGV':
+
+ $ awk 'BEGIN {
+ > for (i = 0; i < ARGC; i++)
+ > print ARGV[i]
+ > }' inventory-shipped BBS-list
+ -| awk
+ -| inventory-shipped
+ -| BBS-list
+
+In this example, `ARGV[0]' contains `awk', `ARGV[1]' contains
+`inventory-shipped', and `ARGV[2]' contains `BBS-list'. Notice that
+the `awk' program is not entered in `ARGV'. The other special
+command-line options, with their arguments, are also not entered. This
+includes variable assignments done with the `-v' option (*note
+Options::). Normal variable assignments on the command line _are_
+treated as arguments and do show up in the `ARGV' array:
+
+ $ cat showargs.awk
+ -| 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 }
+ $ awk -v A=1 -f showargs.awk B=2 /dev/null
+ -| A=1, B=0
+ -| ARGV[0] = awk
+ -| ARGV[1] = B=2
+ -| ARGV[2] = /dev/null
+ -| A=1, B=2
+
+A program can alter `ARGC' and the elements of `ARGV'. Each time `awk'
+reaches the end of an input file, it uses the next element of `ARGV' as
+the name of the next input file. By storing a different string there,
+a program can change which files are read. Use `"-"' to represent the
+standard input. Storing additional elements and incrementing `ARGC'
+causes additional files to be read.
+
+If the value of `ARGC' is decreased, that eliminates input files from
+the end of the list. By recording the old value of `ARGC' elsewhere, a
+program can treat the eliminated arguments as something other than file
+names.
+
+To eliminate a file from the middle of the list, store the null string
+(`""') into `ARGV' in place of the file's name. As a special feature,
+`awk' ignores file names that have been replaced with the null string.
+Another option is to use the `delete' statement to remove elements from
+`ARGV' (*note Delete::).
+
+All of these actions are typically done in the `BEGIN' rule, before
+actual processing of the input begins. *Note Split Program::, and see
+*Note Tee Program::, for examples of each way of removing elements from
+`ARGV'. The following fragment processes `ARGV' in order to examine,
+and then remove, command-line options:
+
+ BEGIN {
+ for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] == "-v")
+ verbose = 1
+ else if (ARGV[i] == "-d")
+ debug = 1
+ else if (ARGV[i] ~ /^-?/) {
+ e = sprintf("%s: unrecognized option -- %c",
+ ARGV[0], substr(ARGV[i], 1, ,1))
+ print e > "/dev/stderr"
+ } else
+ break
+ delete ARGV[i]
+ }
+ }
+
+To actually get the options into the `awk' program, end the `awk'
+options with `--' and then supply the `awk' program's options, in the
+following manner:
+
+ awk -f myprog -- -v -d file1 file2 ...
+
+This is not necessary in `gawk'. Unless `--posix' has been specified,
+`gawk' silently puts any unrecognized options into `ARGV' for the `awk'
+program to deal with. As soon as it sees an unknown option, `gawk'
+stops looking for other options that it might otherwise recognize. The
+previous example with `gawk' would be:
+
+ gawk -f myprog -d -v file1 file2 ...
+
+Because `-d' is not a valid `gawk' option, it and the following `-v'
+are passed on to the `awk' program.
+
+\1f
+File: gawk.info, Node: Arrays, Next: Functions, Prev: Patterns and Actions, Up: Top
+
+7 Arrays in `awk'
+*****************
+
+An "array" is a table of values called "elements". The elements of an
+array are distinguished by their indices. "Indices" may be either
+numbers or strings.
+
+This major node describes how arrays work in `awk', how to use array
+elements, how to scan through every element in an array, and how to
+remove array elements. It also describes how `awk' simulates
+multidimensional arrays, as well as some of the less obvious points
+about array usage. The major node finishes with a discussion of
+`gawk''s facility for sorting an array based on its indices.
+
+`awk' maintains a single set of names that may be used for naming
+variables, arrays, and functions (*note User-defined::). Thus, you
+cannot have a variable and an array with the same name in the same
+`awk' program.
+
+* Menu:
+
+* Array Intro:: Introduction to Arrays
+* Reference to Elements:: How to examine one element of an array.
+* Assigning Elements:: How to change an element of an array.
+* Array Example:: Basic Example of an Array
+* Scanning an Array:: A variation of the `for' statement. It
+ loops through the indices of an array's
+ existing elements.
+* Delete:: The `delete' statement removes an element
+ from an array.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ `awk'.
+* Uninitialized Subscripts:: Using Uninitialized variables as subscripts.
+* Multi-dimensional:: Emulating multidimensional arrays in
+ `awk'.
+* Multi-scanning:: Scanning multidimensional arrays.
+* Array Sorting:: Sorting array values and indices.
+
+\1f
+File: gawk.info, Node: Array Intro, Next: Reference to Elements, Up: Arrays
+
+7.1 Introduction to Arrays
+==========================
+
+The `awk' language provides one-dimensional arrays for storing groups
+of related strings or numbers. Every `awk' array must have a name.
+Array names have the same syntax as variable names; any valid variable
+name would also be a valid array name. But one name cannot be used in
+both ways (as an array and as a variable) in the same `awk' program.
+
+Arrays in `awk' superficially resemble arrays in other programming
+languages, but there are fundamental differences. In `awk', it isn't
+necessary to specify the size of an array before starting to use it.
+Additionally, any number or string in `awk', not just consecutive
+integers, may be used as an array index.
+
+In most other languages, arrays must be "declared" before use,
+including a specification of how many elements or components they
+contain. In such languages, the declaration causes a contiguous block
+of memory to be allocated for that many elements. Usually, an index in
+the array must be a positive integer. For example, the index zero
+specifies the first element in the array, which is actually stored at
+the beginning of the block of memory. Index one specifies the second
+element, which is stored in memory right after the first element, and
+so on. It is impossible to add more elements to the array, because it
+has room only for as many elements as given in the declaration. (Some
+languages allow arbitrary starting and ending indices--e.g., `15 ..
+27'--but the size of the array is still fixed when the array is
+declared.)
+
+A contiguous array of four elements might look like the following
+example, conceptually, if the element values are 8, `"foo"', `""', and
+30:
+
+ +---------+---------+--------+---------+
+ | 8 | "foo" | "" | 30 | Value
+ +---------+---------+--------+---------+
+ 0 1 2 3 Index
+
+Only the values are stored; the indices are implicit from the order of
+the values. Here, 8 is the value at index zero, because 8 appears in the
+position with zero elements before it.
+
+Arrays in `awk' are different--they are "associative". This means that
+each array is a collection of pairs: an index and its corresponding
+array element value:
+
+ Element 3 Value 30
+ Element 1 Value "foo"
+ Element 0 Value 8
+ Element 2 Value ""
+
+The pairs are shown in jumbled order because their order is irrelevant.
+
+One advantage of associative arrays is that new pairs can be added at
+any time. For example, suppose a tenth element is added to the array
+whose value is `"number ten"'. The result is:
+
+ Element 10 Value "number ten"
+ Element 3 Value 30
+ Element 1 Value "foo"
+ Element 0 Value 8
+ Element 2 Value ""
+
+Now the array is "sparse", which just means some indices are missing.
+It has elements 0-3 and 10, but doesn't have elements 4, 5, 6, 7, 8, or
+9.
+
+Another consequence of associative arrays is that the indices don't
+have to be positive integers. Any number, or even a string, can be an
+index. For example, the following is an array that translates words
+from English to French:
+
+ Element "dog" Value "chien"
+ Element "cat" Value "chat"
+ Element "one" Value "un"
+ Element 1 Value "un"
+
+Here we decided to translate the number one in both spelled-out and
+numeric form--thus illustrating that a single array can have both
+numbers and strings as indices. In fact, array subscripts are always
+strings; this is discussed in more detail in *Note Numeric Array
+Subscripts::. Here, the number `1' isn't double-quoted, since `awk'
+automatically converts it to a string.
+
+The value of `IGNORECASE' has no effect upon array subscripting. The
+identical string value used to store an array element must be used to
+retrieve it. When `awk' creates an array (e.g., with the `split'
+built-in function), that array's indices are consecutive integers
+starting at one. (*Note String Functions::.)
+
+`awk''s arrays are efficient--the time to access an element is
+independent of the number of elements in the array.
+
+\1f
+File: gawk.info, Node: Reference to Elements, Next: Assigning Elements, Prev: Array Intro, Up: Arrays
+
+7.2 Referring to an Array Element
+=================================
+
+The principal way to use an array is to refer to one of its elements.
+An array reference is an expression as follows:
+
+ ARRAY[INDEX]
+
+Here, ARRAY is the name of an array. The expression INDEX is the index
+of the desired element of the array.
+
+The value of the array reference is the current value of that array
+element. For example, `foo[4.3]' is an expression for the element of
+array `foo' at index `4.3'.
+
+A reference to an array element that has no recorded value yields a
+value of `""', the null string. This includes elements that have not
+been assigned any value as well as elements that have been deleted
+(*note Delete::). Such a reference automatically creates that array
+element, with the null string as its value. (In some cases, this is
+unfortunate, because it might waste memory inside `awk'.)
+
+To determine whether an element exists in an array at a certain index,
+use the following expression:
+
+ INDEX in ARRAY
+
+This expression tests whether the particular index exists, without the
+side effect of creating that element if it is not present. The
+expression has the value one (true) if `ARRAY[INDEX]' exists and zero
+(false) if it does not exist. For example, this statement tests
+whether the array `frequencies' contains the index `2':
+
+ if (2 in frequencies)
+ print "Subscript 2 is present."
+
+Note that this is _not_ a test of whether the array `frequencies'
+contains an element whose _value_ is two. There is no way to do that
+except to scan all the elements. Also, this _does not_ create
+`frequencies[2]', while the following (incorrect) alternative does:
+
+ if (frequencies[2] != "")
+ print "Subscript 2 is present."
+
+\1f
+File: gawk.info, Node: Assigning Elements, Next: Array Example, Prev: Reference to Elements, Up: Arrays
+
+7.3 Assigning Array Elements
+============================
+
+Array elements can be assigned values just like `awk' variables:
+
+ ARRAY[SUBSCRIPT] = VALUE
+
+ARRAY is the name of an array. The expression SUBSCRIPT is the index
+of the element of the array that is assigned a value. The expression
+VALUE is the value to assign to that element of the array.
+
+\1f
+File: gawk.info, Node: Array Example, Next: Scanning an Array, Prev: Assigning Elements, Up: Arrays
+
+7.4 Basic Array Example
+=======================
+
+The following program takes a list of lines, each beginning with a line
+number, and prints them out in order of line number. The line numbers
+are not in order when they are first read--instead they are scrambled.
+This program sorts the lines by making an array using the line numbers
+as subscripts. The program then prints out the lines in sorted order
+of their numbers. It is a very simple program and gets confused upon
+encountering repeated numbers, gaps, or lines that don't begin with a
+number:
+
+ {
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
+ }
+
+ END {
+ for (x = 1; x <= max; x++)
+ print arr[x]
+ }
+
+The first rule keeps track of the largest line number seen so far; it
+also stores each line into the array `arr', at an index that is the
+line's number. The second rule runs after all the input has been read,
+to print out all the lines. When this program is run with the
+following input:
+
+ 5 I am the Five man
+ 2 Who are you? The new number two!
+ 4 . . . And four on the floor
+ 1 Who is number one?
+ 3 I three you.
+
+Its output is:
+
+ 1 Who is number one?
+ 2 Who are you? The new number two!
+ 3 I three you.
+ 4 . . . And four on the floor
+ 5 I am the Five man
+
+If a line number is repeated, the last line with a given number
+overrides the others. Gaps in the line numbers can be handled with an
+easy improvement to the program's `END' rule, as follows:
+
+ END {
+ for (x = 1; x <= max; x++)
+ if (x in arr)
+ print arr[x]
+ }
+
+\1f
+File: gawk.info, Node: Scanning an Array, Next: Delete, Prev: Array Example, Up: Arrays
+
+7.5 Scanning All Elements of an Array
+=====================================
+
+In programs that use arrays, it is often necessary to use a loop that
+executes once for each element of an array. In other languages, where
+arrays are contiguous and indices are limited to positive integers,
+this is easy: all the valid indices can be found by counting from the
+lowest index up to the highest. This technique won't do the job in
+`awk', because any number or string can be an array index. So `awk'
+has a special kind of `for' statement for scanning an array:
+
+ for (VAR in ARRAY)
+ BODY
+
+This loop executes BODY once for each index in ARRAY that the program
+has previously used, with the variable VAR set to that index.
+
+The following program uses this form of the `for' statement. The first
+rule scans the input records and notes which words appear (at least
+once) in the input, by storing a one into the array `used' with the
+word as index. The second rule scans the elements of `used' to find
+all the distinct words that appear in the input. It prints each word
+that is more than 10 characters long and also prints the number of such
+words. *Note String Functions::, for more information on the built-in
+function `length'.
+
+ # Record a 1 for each word that is used at least once
+ {
+ for (i = 1; i <= NF; i++)
+ used[$i] = 1
+ }
+
+ # Find number of distinct words more than 10 characters long
+ END {
+ for (x in used)
+ if (length(x) > 10) {
+ ++num_long_words
+ print x
+ }
+ print num_long_words, "words longer than 10 characters"
+ }
+
+*Note Word Sorting::, for a more detailed example of this type.
+
+The order in which elements of the array are accessed by this statement
+is determined by the internal arrangement of the array elements within
+`awk' and cannot be controlled or changed. This can lead to problems
+if new elements are added to ARRAY by statements in the loop body; it
+is not predictable whether the `for' loop will reach them. Similarly,
+changing VAR inside the loop may produce strange results. It is best
+to avoid such things.
+
+\1f
+File: gawk.info, Node: Delete, Next: Numeric Array Subscripts, Prev: Scanning an Array, Up: Arrays
+
+7.6 The `delete' Statement
+==========================
+
+To remove an individual element of an array, use the `delete' statement:
+
+ delete ARRAY[INDEX]
+
+Once an array element has been deleted, any value the element once had
+is no longer available. It is as if the element had never been referred
+to or had been given a value. The following is an example of deleting
+elements in an array:
+
+ for (i in frequencies)
+ delete frequencies[i]
+
+This example removes all the elements from the array `frequencies'.
+Once an element is deleted, a subsequent `for' statement to scan the
+array does not report that element and the `in' operator to check for
+the presence of that element returns zero (i.e., false):
+
+ delete foo[4]
+ if (4 in foo)
+ print "This will never be printed"
+
+It is important to note that deleting an element is _not_ the same as
+assigning it a null value (the empty string, `""'). For example:
+
+ foo[4] = ""
+ if (4 in foo)
+ print "This is printed, even though foo[4] is empty"
+
+It is not an error to delete an element that does not exist. If
+`--lint' is provided on the command line (*note Options::), `gawk'
+issues a warning message when an element that is not in the array is
+deleted.
+
+All the elements of an array may be deleted with a single statement by
+leaving off the subscript in the `delete' statement, as follows:
+
+ delete ARRAY
+
+This ability is a `gawk' extension; it is not available in
+compatibility mode (*note Options::).
+
+Using this version of the `delete' statement is about three times more
+efficient than the equivalent loop that deletes each element one at a
+time.
+
+The following statement provides a portable but nonobvious way to clear
+out an array:(1)
+
+ split("", array)
+
+The `split' function (*note String Functions::) clears out the target
+array first. This call asks it to split apart the null string. Because
+there is no data to split out, the function simply clears the array and
+then returns.
+
+*Caution:* Deleting an array does not change its type; you cannot
+delete an array and then use the array's name as a scalar (i.e., a
+regular variable). For example, the following does not work:
+
+ a[1] = 3; delete a; a = 3
+
+---------- Footnotes ----------
+
+(1) Thanks to Michael Brennan for pointing this out.
+
+\1f
+File: gawk.info, Node: Numeric Array Subscripts, Next: Uninitialized Subscripts, Prev: Delete, Up: Arrays
+
+7.7 Using Numbers to Subscript Arrays
+=====================================
+
+An important aspect about arrays to remember is that _array subscripts
+are always strings_. When a numeric value is used as a subscript, it
+is converted to a string value before being used for subscripting
+(*note Conversion::). This means that the value of the built-in
+variable `CONVFMT' can affect how your program accesses elements of an
+array. For example:
+
+ xyz = 12.153
+ data[xyz] = 1
+ CONVFMT = "%2.2f"
+ if (xyz in data)
+ printf "%s is in data\n", xyz
+ else
+ printf "%s is not in data\n", xyz
+
+This prints `12.15 is not in data'. The first statement gives `xyz' a
+numeric value. Assigning to `data[xyz]' subscripts `data' with the
+string value `"12.153"' (using the default conversion value of
+`CONVFMT', `"%.6g"'). Thus, the array element `data["12.153"]' is
+assigned the value one. The program then changes the value of
+`CONVFMT'. The test `(xyz in data)' generates a new string value from
+`xyz'--this time `"12.15"'--because the value of `CONVFMT' only allows
+two significant digits. This test fails, since `"12.15"' is a
+different string from `"12.153"'.
+
+According to the rules for conversions (*note Conversion::), integer
+values are always converted to strings as integers, no matter what the
+value of `CONVFMT' may happen to be. So the usual case of the
+following works:
+
+ for (i = 1; i <= maxsub; i++)
+ do something with array[i]
+
+The "integer values always convert to strings as integers" rule has an
+additional consequence for array indexing. Octal and hexadecimal
+constants (*note Nondecimal-numbers::) are converted internally into
+numbers, and their original form is forgotten. This means, for
+example, that `array[17]', `array[021]', and `array[0x11]' all refer to
+the same element!
+
+As with many things in `awk', the majority of the time things work as
+one would expect them to. But it is useful to have a precise knowledge
+of the actual rules which sometimes can have a subtle effect on your
+programs.
+
+\1f
+File: gawk.info, Node: Uninitialized Subscripts, Next: Multi-dimensional, Prev: Numeric Array Subscripts, Up: Arrays
+
+7.8 Using Uninitialized Variables as Subscripts
+===============================================
+
+Suppose it's necessary to write a program to print the input data in
+reverse order. A reasonable attempt to do so (with some test data)
+might look like this:
+
+ $ echo 'line 1
+ > line 2
+ > line 3' | awk '{ l[lines] = $0; ++lines }
+ > END {
+ > for (i = lines-1; i >= 0; --i)
+ > print l[i]
+ > }'
+ -| line 3
+ -| line 2
+
+Unfortunately, the very first line of input data did not come out in the
+output!
+
+At first glance, this program should have worked. The variable `lines'
+is uninitialized, and uninitialized variables have the numeric value
+zero. So, `awk' should have printed the value of `l[0]'.
+
+The issue here is that subscripts for `awk' arrays are _always_
+strings. Uninitialized variables, when used as strings, have the value
+`""', not zero. Thus, `line 1' ends up stored in `l[""]'. The
+following version of the program works correctly:
+
+ { l[lines++] = $0 }
+ END {
+ for (i = lines - 1; i >= 0; --i)
+ print l[i]
+ }
+
+Here, the `++' forces `lines' to be numeric, thus making the "old
+value" numeric zero. This is then converted to `"0"' as the array
+subscript.
+
+Even though it is somewhat unusual, the null string (`""') is a valid
+array subscript. (d.c.) `gawk' warns about the use of the null string
+as a subscript if `--lint' is provided on the command line (*note
+Options::).
+
+\1f
+File: gawk.info, Node: Multi-dimensional, Next: Multi-scanning, Prev: Uninitialized Subscripts, Up: Arrays
+
+7.9 Multidimensional Arrays
+===========================
+
+A multidimensional array is an array in which an element is identified
+by a sequence of indices instead of a single index. For example, a
+two-dimensional array requires two indices. The usual way (in most
+languages, including `awk') to refer to an element of a two-dimensional
+array named `grid' is with `grid[X,Y]'.
+
+Multidimensional arrays are supported in `awk' through concatenation of
+indices into one string. `awk' converts the indices into strings
+(*note Conversion::) and concatenates them together, with a separator
+between them. This creates a single string that describes the values
+of the separate indices. The combined string is used as a single index
+into an ordinary, one-dimensional array. The separator used is the
+value of the built-in variable `SUBSEP'.
+
+For example, suppose we evaluate the expression `foo[5,12] = "value"'
+when the value of `SUBSEP' is `"@"'. The numbers 5 and 12 are
+converted to strings and concatenated with an `@' between them,
+yielding `"5@12"'; thus, the array element `foo["5@12"]' is set to
+`"value"'.
+
+Once the element's value is stored, `awk' has no record of whether it
+was stored with a single index or a sequence of indices. The two
+expressions `foo[5,12]' and `foo[5 SUBSEP 12]' are always equivalent.
+
+The default value of `SUBSEP' is the string `"\034"', which contains a
+nonprinting character that is unlikely to appear in an `awk' program or
+in most input data. The usefulness of choosing an unlikely character
+comes from the fact that index values that contain a string matching
+`SUBSEP' can lead to combined strings that are ambiguous. Suppose that
+`SUBSEP' is `"@"'; then `foo["a@b", "c"]' and `foo["a", "b@c"]' are
+indistinguishable because both are actually stored as `foo["a@b@c"]'.
+
+To test whether a particular index sequence exists in a
+multidimensional array, use the same operator (`in') that is used for
+single dimensional arrays. Write the whole sequence of indices in
+parentheses, separated by commas, as the left operand:
+
+ (SUBSCRIPT1, SUBSCRIPT2, ...) in ARRAY
+
+The following example treats its input as a two-dimensional array of
+fields; it rotates this array 90 degrees clockwise and prints the
+result. It assumes that all lines have the same number of elements:
+
+ {
+ if (max_nf < NF)
+ max_nf = NF
+ max_nr = NR
+ for (x = 1; x <= NF; x++)
+ vector[x, NR] = $x
+ }
+
+ END {
+ for (x = 1; x <= max_nf; x++) {
+ for (y = max_nr; y >= 1; --y)
+ printf("%s ", vector[x, y])
+ printf("\n")
+ }
+ }
+
+When given the input:
+
+ 1 2 3 4 5 6
+ 2 3 4 5 6 1
+ 3 4 5 6 1 2
+ 4 5 6 1 2 3
+
+the program produces the following output:
+
+ 4 3 2 1
+ 5 4 3 2
+ 6 5 4 3
+ 1 6 5 4
+ 2 1 6 5
+ 3 2 1 6
+
+\1f
+File: gawk.info, Node: Multi-scanning, Next: Array Sorting, Prev: Multi-dimensional, Up: Arrays
+
+7.10 Scanning Multidimensional Arrays
+=====================================
+
+There is no special `for' statement for scanning a "multidimensional"
+array. There cannot be one, because, in truth, there are no
+multidimensional arrays or elements--there is only a multidimensional
+_way of accessing_ an array.
+
+However, if your program has an array that is always accessed as
+multidimensional, you can get the effect of scanning it by combining
+the scanning `for' statement (*note Scanning an Array::) with the
+built-in `split' function (*note String Functions::). It works in the
+following manner:
+
+ for (combined in array) {
+ split(combined, separate, SUBSEP)
+ ...
+ }
+
+This sets the variable `combined' to each concatenated combined index
+in the array, and splits it into the individual indices by breaking it
+apart where the value of `SUBSEP' appears. The individual indices then
+become the elements of the array `separate'.
+
+Thus, if a value is previously stored in `array[1, "foo"]'; then an
+element with index `"1\034foo"' exists in `array'. (Recall that the
+default value of `SUBSEP' is the character with code 034.) Sooner or
+later, the `for' statement finds that index and does an iteration with
+the variable `combined' set to `"1\034foo"'. Then the `split' function
+is called as follows:
+
+ split("1\034foo", separate, "\034")
+
+The result is to set `separate[1]' to `"1"' and `separate[2]' to
+`"foo"'. Presto! The original sequence of separate indices is
+recovered.
+
+\1f
+File: gawk.info, Node: Array Sorting, Prev: Multi-scanning, Up: Arrays
+
+7.11 Sorting Array Values and Indices with `gawk'
+=================================================
+
+The order in which an array is scanned with a `for (i in array)' loop
+is essentially arbitrary. In most `awk' implementations, sorting an
+array requires writing a `sort' function. While this can be
+educational for exploring different sorting algorithms, usually that's
+not the point of the program. `gawk' provides the built-in `asort' and
+`asorti' functions (*note String Functions::) for sorting arrays. For
+example:
+
+ POPULATE THE ARRAY data
+ n = asort(data)
+ for (i = 1; i <= n; i++)
+ DO SOMETHING WITH data[i]
+
+After the call to `asort', the array `data' is indexed from 1 to some
+number N, the total number of elements in `data'. (This count is
+`asort''s return value.) `data[1]' <= `data[2]' <= `data[3]', and so
+on. The comparison of array elements is done using `gawk''s usual
+comparison rules (*note Typing and Comparison::).
+
+An important side effect of calling `asort' is that _the array's
+original indices are irrevocably lost_. As this isn't always
+desirable, `asort' accepts a second argument:
+
+ POPULATE THE ARRAY source
+ n = asort(source, dest)
+ for (i = 1; i <= n; i++)
+ DO SOMETHING WITH dest[i]
+
+In this case, `gawk' copies the `source' array into the `dest' array
+and then sorts `dest', destroying its indices. However, the `source'
+array is not affected.
+
+Often, what's needed is to sort on the values of the _indices_ instead
+of the values of the elements. To do that, starting with `gawk' 3.1.2,
+use the `asorti' function. The interface is identical to that of
+`asort', except that the index values are used for sorting, and become
+the values of the result array:
+
+ { source[$0] = some_func($0) }
+
+ END {
+ n = asorti(source, dest)
+ for (i = 1; i <= n; i++) {
+ DO SOMETHING WITH dest[i] Work with sorted indices directly
+ ...
+ DO SOMETHING WITH source[dest[i]] Access original array via sorted indices
+ }
+ }
+
+If your version of `gawk' is 3.1.0 or 3.1.1, you don't have `asorti'.
+Instead, use a helper array to hold the sorted index values, and then
+access the original array's elements. It works in the following way:
+
+ POPULATE THE ARRAY data
+ # copy indices
+ j = 1
+ for (i in data) {
+ ind[j] = i # index value becomes element value
+ j++
+ }
+ n = asort(ind) # index values are now sorted
+ for (i = 1; i <= n; i++) {
+ DO SOMETHING WITH ind[i] Work with sorted indices directly
+ ...
+ DO SOMETHING WITH data[ind[i]] Access original array via sorted indices
+ }
+
+Sorting the array by replacing the indices provides maximal flexibility.
+To traverse the elements in decreasing order, use a loop that goes from
+N down to 1, either over the elements or over the indices.
+
+Copying array indices and elements isn't expensive in terms of memory.
+Internally, `gawk' maintains "reference counts" to data. For example,
+when `asort' copies the first array to the second one, there is only
+one copy of the original array elements' data, even though both arrays
+use the values. Similarly, when copying the indices from `data' to
+`ind', there is only one copy of the actual index strings.
+
+We said previously that comparisons are done using `gawk''s "usual
+comparison rules." Because `IGNORECASE' affects string comparisons,
+the value of `IGNORECASE' also affects sorting for both `asort' and
+`asorti'. Caveat Emptor.
+
+\1f
+File: gawk.info, Node: Functions, Next: Internationalization, Prev: Arrays, Up: Top
+
+8 Functions
+***********
+
+This major node describes `awk''s built-in functions, which fall into
+three categories: numeric, string, and I/O. `gawk' provides additional
+groups of functions to work with values that represent time, do bit
+manipulation, and internationalize and localize programs.
+
+Besides the built-in functions, `awk' has provisions for writing new
+functions that the rest of a program can use. The second half of this
+major node describes these "user-defined" functions.
+
+* Menu:
+
+* Built-in:: Summarizes the built-in functions.
+* User-defined:: Describes User-defined functions in detail.
+
+\1f
+File: gawk.info, Node: Built-in, Next: User-defined, Up: Functions
+
+8.1 Built-in Functions
+======================
+
+"Built-in" functions are always available for your `awk' program to
+call. This minor node defines all the built-in functions in `awk';
+some of these are mentioned in other sections but are summarized here
+for your convenience.
+
+* Menu:
+
+* Calling Built-in:: How to call built-in functions.
+* Numeric Functions:: Functions that work with numbers, including
+ `int', `sin' and `rand'.
+* String Functions:: Functions for string manipulation, such as
+ `split', `match' and `sprintf'.
+* I/O Functions:: Functions for files and shell commands.
+* Time Functions:: Functions for dealing with timestamps.
+* Bitwise Functions:: Functions for bitwise operations.
+* I18N Functions:: Functions for string translation.
+
+\1f
+File: gawk.info, Node: Calling Built-in, Next: Numeric Functions, Up: Built-in
+
+8.1.1 Calling Built-in Functions
+--------------------------------
+
+To call one of `awk''s built-in functions, write the name of the
+function followed by arguments in parentheses. For example, `atan2(y +
+z, 1)' is a call to the function `atan2' and has two arguments.
+
+Whitespace is ignored between the built-in function name and the open
+parenthesis, and it is good practice to avoid using whitespace there.
+User-defined functions do not permit whitespace in this way, and it is
+easier to avoid mistakes by following a simple convention that always
+works--no whitespace after a function name.
+
+Each built-in function accepts a certain number of arguments. In some
+cases, arguments can be omitted. The defaults for omitted arguments
+vary from function to function and are described under the individual
+functions. In some `awk' implementations, extra arguments given to
+built-in functions are ignored. However, in `gawk', it is a fatal
+error to give extra arguments to a built-in function.
+
+When a function is called, expressions that create the function's actual
+parameters are evaluated completely before the call is performed. For
+example, in the following code fragment:
+
+ i = 4
+ j = sqrt(i++)
+
+the variable `i' is incremented to the value five before `sqrt' is
+called with a value of four for its actual parameter. The order of
+evaluation of the expressions used for the function's parameters is
+undefined. Thus, avoid writing programs that assume that parameters
+are evaluated from left to right or from right to left. For example:
+
+ i = 5
+ j = atan2(i++, i *= 2)
+
+If the order of evaluation is left to right, then `i' first becomes 6,
+and then 12, and `atan2' is called with the two arguments 6 and 12.
+But if the order of evaluation is right to left, `i' first becomes 10,
+then 11, and `atan2' is called with the two arguments 11 and 10.
+
+\1f
+File: gawk.info, Node: Numeric Functions, Next: String Functions, Prev: Calling Built-in, Up: Built-in
+
+8.1.2 Numeric Functions
+-----------------------
+
+The following list describes all of the built-in functions that work
+with numbers. Optional parameters are enclosed in square
+brackets ([ ]):
+
+`int(X)'
+ This returns the nearest integer to X, located between X and zero
+ and truncated toward zero.
+
+ For example, `int(3)' is 3, `int(3.9)' is 3, `int(-3.9)' is -3,
+ and `int(-3)' is -3 as well.
+
+`sqrt(X)'
+ This returns the positive square root of X. `gawk' reports an
+ error if X is negative. Thus, `sqrt(4)' is 2.
+
+`exp(X)'
+ This returns the exponential of X (`e ^ X') or reports an error if
+ X is out of range. The range of values X can have depends on your
+ machine's floating-point representation.
+
+`log(X)'
+ This returns the natural logarithm of X, if X is positive;
+ otherwise, it reports an error.
+
+`sin(X)'
+ This returns the sine of X, with X in radians.
+
+`cos(X)'
+ This returns the cosine of X, with X in radians.
+
+`atan2(Y, X)'
+ This returns the arctangent of `Y / X' in radians.
+
+`rand()'
+ This returns a random number. The values of `rand' are uniformly
+ distributed between zero and one. The value could be zero but is
+ never one.(1)
+
+ Often random integers are needed instead. Following is a
+ user-defined function that can be used to obtain a random
+ non-negative integer less than N:
+
+ function randint(n) {
+ return int(n * rand())
+ }
+
+ The multiplication produces a random number greater than zero and
+ less than `n'. Using `int', this result is made into an integer
+ between zero and `n' - 1, inclusive.
+
+ The following example uses a similar function to produce random
+ integers between one and N. This program prints a new random
+ number for each input record:
+
+ # Function to roll a simulated die.
+ function roll(n) { return 1 + int(rand() * n) }
+
+ # Roll 3 six-sided dice and
+ # print total number of points.
+ {
+ printf("%d points\n",
+ roll(6)+roll(6)+roll(6))
+ }
+
+ *Caution:* In most `awk' implementations, including `gawk', `rand'
+ starts generating numbers from the same starting number, or
+ "seed", each time you run `awk'. Thus, a program generates the
+ same results each time you run it. The numbers are random within
+ one `awk' run but predictable from run to run. This is convenient
+ for debugging, but if you want a program to do different things
+ each time it is used, you must change the seed to a value that is
+ different in each run. To do this, use `srand'.
+
+`srand([X])'
+ The function `srand' sets the starting point, or seed, for
+ generating random numbers to the value X.
+
+ Each seed value leads to a particular sequence of random
+ numbers.(2) Thus, if the seed is set to the same value a second
+ time, the same sequence of random numbers is produced again.
+
+ Different `awk' implementations use different random-number
+ generators internally. Don't expect the same `awk' program to
+ produce the same series of random numbers when executed by
+ different versions of `awk'.
+
+ If the argument X is omitted, as in `srand()', then the current
+ date and time of day are used for a seed. This is the way to get
+ random numbers that are truly unpredictable.
+
+ The return value of `srand' is the previous seed. This makes it
+ easy to keep track of the seeds in case you need to consistently
+ reproduce sequences of random numbers.
+
+---------- Footnotes ----------
+
+(1) The C version of `rand' is known to produce fairly poor sequences
+of random numbers. However, nothing requires that an `awk'
+implementation use the C `rand' to implement the `awk' version of
+`rand'. In fact, `gawk' uses the BSD `random' function, which is
+considerably better than `rand', to produce random numbers.
+
+(2) Computer-generated random numbers really are not truly random.
+They are technically known as "pseudorandom." This means that while
+the numbers in a sequence appear to be random, you can in fact generate
+the same sequence of random numbers over and over again.
+
+\1f
+File: gawk.info, Node: String Functions, Next: I/O Functions, Prev: Numeric Functions, Up: Built-in
+
+8.1.3 String-Manipulation Functions
+-----------------------------------
+
+The functions in this minor node look at or change the text of one or
+more strings. Optional parameters are enclosed in square
+brackets ([ ]). Those functions that are specific to `gawk' are marked
+with a pound sign (`#'):
+
+* Menu:
+
+* Gory Details:: More than you want to know about `\' and
+ `&' with `sub', `gsub', and
+ `gensub'.
+
+`asort(SOURCE [, DEST]) #'
+ `asort' is a `gawk'-specific extension, returning the number of
+ elements in the array SOURCE. The contents of SOURCE are sorted
+ using `gawk''s normal rules for comparing values (in particular,
+ `IGNORECASE' affects the sorting) and the indices of the sorted
+ values of SOURCE are replaced with sequential integers starting
+ with one. If the optional array DEST is specified, then SOURCE is
+ duplicated into DEST. DEST is then sorted, leaving the indices of
+ SOURCE unchanged. For example, if the contents of `a' are as
+ follows:
+
+ a["last"] = "de"
+ a["first"] = "sac"
+ a["middle"] = "cul"
+
+ A call to `asort':
+
+ asort(a)
+
+ results in the following contents of `a':
+
+ a[1] = "cul"
+ a[2] = "de"
+ a[3] = "sac"
+
+ The `asort' function is described in more detail in *Note Array
+ Sorting::. `asort' is a `gawk' extension; it is not available in
+ compatibility mode (*note Options::).
+
+`asorti(SOURCE [, DEST]) #'
+ `asorti' is a `gawk'-specific extension, returning the number of
+ elements in the array SOURCE. It works similarly to `asort',
+ however, the _indices_ are sorted, instead of the values. As
+ array indices are always strings, the comparison performed is
+ always a string comparison. (Here too, `IGNORECASE' affects the
+ sorting.)
+
+ The `asorti' function is described in more detail in *Note Array
+ Sorting::. It was added in `gawk' 3.1.2. `asorti' is a `gawk'
+ extension; it is not available in compatibility mode (*note
+ Options::).
+
+`index(IN, FIND)'
+ This searches the string IN for the first occurrence of the string
+ FIND, and returns the position in characters where that occurrence
+ begins in the string IN. Consider the following example:
+
+ $ awk 'BEGIN { print index("peanut", "an") }'
+ -| 3
+
+ If FIND is not found, `index' returns zero. (Remember that string
+ indices in `awk' start at one.)
+
+`length([STRING])'
+ This returns the number of characters in STRING. If STRING is a
+ number, the length of the digit string representing that number is
+ returned. For example, `length("abcde")' is 5. By contrast,
+ `length(15 * 35)' works out to 3. In this example, 15 * 35 = 525,
+ and 525 is then converted to the string `"525"', which has three
+ characters.
+
+ If no argument is supplied, `length' returns the length of `$0'.
+
+ NOTE: In older versions of `awk', the `length' function could
+ be called without any parentheses. Doing so is marked as
+ "deprecated" in the POSIX standard. This means that while a
+ program can do this, it is a feature that can eventually be
+ removed from a future version of the standard. Therefore,
+ for programs to be maximally portable, always supply the
+ parentheses.
+
+ Beginning with `gawk' version 3.2, when supplied an array
+ argument, the `length' function returns the number of elements in
+ the array. This is less useful than it might seem at first, as the
+ array is not guaranteed to be indexed from one to the number of
+ elements in it. If `--lint' is provided on the command line
+ (*note Options::), `gawk' warns that passing an array argument is
+ not portable. If `--posix' is supplied, using an array argument
+ is a fatal error (*note Arrays::).
+
+`match(STRING, REGEXP [, ARRAY])'
+ The `match' function searches STRING for the longest, leftmost
+ substring matched by the regular expression, REGEXP. It returns
+ the character position, or "index", at which that substring begins
+ (one, if it starts at the beginning of STRING). If no match is
+ found, it returns zero.
+
+ The REGEXP argument may be either a regexp constant (`/.../') or a
+ string constant ("..."). In the latter case, the string is
+ treated as a regexp to be matched. *Note Computed Regexps::, for a
+ discussion of the difference between the two forms, and the
+ implications for writing your program correctly.
+
+ The order of the first two arguments is backwards from most other
+ string functions that work with regular expressions, such as `sub'
+ and `gsub'. It might help to remember that for `match', the order
+ is the same as for the `~' operator: `STRING ~ REGEXP'.
+
+ The `match' function sets the built-in variable `RSTART' to the
+ index. It also sets the built-in variable `RLENGTH' to the length
+ in characters of the matched substring. If no match is found,
+ `RSTART' is set to zero, and `RLENGTH' to -1.
+
+ For example:
+
+ {
+ if ($1 == "FIND")
+ regex = $2
+ else {
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at",
+ where, "in", $0
+ }
+ }
+
+ This program looks for lines that match the regular expression
+ stored in the variable `regex'. This regular expression can be
+ changed. If the first word on a line is `FIND', `regex' is
+ changed to be the second word on that line. Therefore, if given:
+
+ FIND ru+n
+ My program runs
+ but not very quickly
+ FIND Melvin
+ JF+KM
+ This line is property of Reality Engineering Co.
+ Melvin was here.
+
+ `awk' prints:
+
+ Match of ru+n found at 12 in My program runs
+ Match of Melvin found at 1 in Melvin was here.
+
+ If ARRAY is present, it is cleared, and then the 0th element of
+ ARRAY is set to the entire portion of STRING matched by REGEXP.
+ If REGEXP contains parentheses, the integer-indexed elements of
+ ARRAY are set to contain the portion of STRING matching the
+ corresponding parenthesized subexpression. For example:
+
+ $ echo foooobazbarrrrr |
+ > gawk '{ match($0, /(fo+).+(bar*)/, arr)
+ > print arr[1], arr[2] }'
+ -| foooo barrrrr
+
+ In addition, beginning with `gawk' 3.1.2, multidimensional
+ subscripts are available providing the start index and length of
+ each matched subexpression:
+
+ $ echo foooobazbarrrrr |
+ > gawk '{ match($0, /(fo+).+(bar*)/, arr)
+ > print arr[1], arr[2]
+ > print arr[1, "start"], arr[1, "length"]
+ > print arr[2, "start"], arr[2, "length"]
+ > }'
+ -| foooo barrrrr
+ -| 1 5
+ -| 9 7
+
+ There may not be subscripts for the start and index for every
+ parenthesized subexpressions, since they may not all have matched
+ text; thus they should be tested for with the `in' operator (*note
+ Reference to Elements::).
+
+ The ARRAY argument to `match' is a `gawk' extension. In
+ compatibility mode (*note Options::), using a third argument is a
+ fatal error.
+
+`split(STRING, ARRAY [, FIELDSEP])'
+ This function divides STRING into pieces separated by FIELDSEP and
+ stores the pieces in ARRAY. The first piece is stored in
+ `ARRAY[1]', the second piece in `ARRAY[2]', and so forth. The
+ string value of the third argument, FIELDSEP, is a regexp
+ describing where to split STRING (much as `FS' can be a regexp
+ describing where to split input records). If FIELDSEP is omitted,
+ the value of `FS' is used. `split' returns the number of elements
+ created.
+
+ The `split' function splits strings into pieces in a manner
+ similar to the way input lines are split into fields. For example:
+
+ split("cul-de-sac", a, "-")
+
+ splits the string `cul-de-sac' into three fields using `-' as the
+ separator. It sets the contents of the array `a' as follows:
+
+ a[1] = "cul"
+ a[2] = "de"
+ a[3] = "sac"
+
+ The value returned by this call to `split' is three.
+
+ As with input field-splitting, when the value of FIELDSEP is
+ `" "', leading and trailing whitespace is ignored, and the elements
+ are separated by runs of whitespace. Also as with input
+ field-splitting, if FIELDSEP is the null string, each individual
+ character in the string is split into its own array element.
+ (This is a `gawk'-specific extension.)
+
+ Note, however, that `RS' has no effect on the way `split' works.
+ Even though `RS = ""' causes newline to also be an input field
+ separator, this does not affect how `split' splits strings.
+
+ Modern implementations of `awk', including `gawk', allow the third
+ argument to be a regexp constant (`/abc/') as well as a string.
+ (d.c.) The POSIX standard allows this as well. *Note Computed
+ Regexps::, for a discussion of the difference between using a
+ string constant or a regexp constant, and the implications for
+ writing your program correctly.
+
+ Before splitting the string, `split' deletes any previously
+ existing elements in the array ARRAY.
+
+ If STRING is null, the array has no elements. (So this is a
+ portable way to delete an entire array with one statement. *Note
+ Delete::.)
+
+ If STRING does not match FIELDSEP at all (but is not null), ARRAY
+ has one element only. The value of that element is the original
+ STRING.
+
+`sprintf(FORMAT, EXPRESSION1, ...)'
+ This returns (without printing) the string that `printf' would
+ have printed out with the same arguments (*note Printf::). For
+ example:
+
+ pival = sprintf("pi = %.2f (approx.)", 22/7)
+
+ assigns the string `"pi = 3.14 (approx.)"' to the variable `pival'.
+
+`strtonum(STR) #'
+ Examines STR and returns its numeric value. If STR begins with a
+ leading `0', `strtonum' assumes that STR is an octal number. If
+ STR begins with a leading `0x' or `0X', `strtonum' assumes that
+ STR is a hexadecimal number. For example:
+
+ $ echo 0x11 |
+ > gawk '{ printf "%d\n", strtonum($1) }'
+ -| 17
+
+ Using the `strtonum' function is _not_ the same as adding zero to
+ a string value; the automatic coercion of strings to numbers works
+ only for decimal data, not for octal or hexadecimal.(1)
+
+ Note also that `strtonum' uses the current locale's decimal point
+ for recognizing numbers.
+
+ `strtonum' is a `gawk' extension; it is not available in
+ compatibility mode (*note Options::).
+
+`sub(REGEXP, REPLACEMENT [, TARGET])'
+ The `sub' function alters the value of TARGET. It searches this
+ value, which is treated as a string, for the leftmost, longest
+ substring matched by the regular expression REGEXP. Then the
+ entire string is changed by replacing the matched text with
+ REPLACEMENT. The modified string becomes the new value of TARGET.
+
+ The REGEXP argument may be either a regexp constant (`/.../') or a
+ string constant ("..."). In the latter case, the string is
+ treated as a regexp to be matched. *Note Computed Regexps::, for a
+ discussion of the difference between the two forms, and the
+ implications for writing your program correctly.
+
+ This function is peculiar because TARGET is not simply used to
+ compute a value, and not just any expression will do--it must be a
+ variable, field, or array element so that `sub' can store a
+ modified value there. If this argument is omitted, then the
+ default is to use and alter `$0'.(2) For example:
+
+ str = "water, water, everywhere"
+ sub(/at/, "ith", str)
+
+ sets `str' to `"wither, water, everywhere"', by replacing the
+ leftmost longest occurrence of `at' with `ith'.
+
+ The `sub' function returns the number of substitutions made (either
+ one or zero).
+
+ If the special character `&' appears in REPLACEMENT, it stands for
+ the precise substring that was matched by REGEXP. (If the regexp
+ can match more than one string, then this precise substring may
+ vary.) For example:
+
+ { sub(/candidate/, "& and his wife"); print }
+
+ changes the first occurrence of `candidate' to `candidate and his
+ wife' on each input line. Here is another example:
+
+ $ awk 'BEGIN {
+ > str = "daabaaa"
+ > sub(/a+/, "C&C", str)
+ > print str
+ > }'
+ -| dCaaCbaaa
+
+ This shows how `&' can represent a nonconstant string and also
+ illustrates the "leftmost, longest" rule in regexp matching (*note
+ Leftmost Longest::).
+
+ The effect of this special character (`&') can be turned off by
+ putting a backslash before it in the string. As usual, to insert
+ one backslash in the string, you must write two backslashes.
+ Therefore, write `\\&' in a string constant to include a literal
+ `&' in the replacement. For example, the following shows how to
+ replace the first `|' on each line with an `&':
+
+ { sub(/\|/, "\\&"); print }
+
+ As mentioned, the third argument to `sub' must be a variable,
+ field or array reference. Some versions of `awk' allow the third
+ argument to be an expression that is not an lvalue. In such a
+ case, `sub' still searches for the pattern and returns zero or
+ one, but the result of the substitution (if any) is thrown away
+ because there is no place to put it. Such versions of `awk'
+ accept expressions such as the following:
+
+ sub(/USA/, "United States", "the USA and Canada")
+
+ For historical compatibility, `gawk' accepts erroneous code, such
+ as in the previous example. However, using any other nonchangeable
+ object as the third parameter causes a fatal error and your program
+ will not run.
+
+ Finally, if the REGEXP is not a regexp constant, it is converted
+ into a string, and then the value of that string is treated as the
+ regexp to match.
+
+`gsub(REGEXP, REPLACEMENT [, TARGET])'
+ This is similar to the `sub' function, except `gsub' replaces
+ _all_ of the longest, leftmost, _nonoverlapping_ matching
+ substrings it can find. The `g' in `gsub' stands for "global,"
+ which means replace everywhere. For example:
+
+ { gsub(/Britain/, "United Kingdom"); print }
+
+ replaces all occurrences of the string `Britain' with `United
+ Kingdom' for all input records.
+
+ The `gsub' function returns the number of substitutions made. If
+ the variable to search and alter (TARGET) is omitted, then the
+ entire input record (`$0') is used. As in `sub', the characters
+ `&' and `\' are special, and the third argument must be assignable.
+
+`gensub(REGEXP, REPLACEMENT, HOW [, TARGET]) #'
+ `gensub' is a general substitution function. Like `sub' and
+ `gsub', it searches the target string TARGET for matches of the
+ regular expression REGEXP. Unlike `sub' and `gsub', the modified
+ string is returned as the result of the function and the original
+ target string is _not_ changed. If HOW is a string beginning with
+ `g' or `G', then it replaces all matches of REGEXP with
+ REPLACEMENT. Otherwise, HOW is treated as a number that indicates
+ which match of REGEXP to replace. If no TARGET is supplied, `$0'
+ is used.
+
+ `gensub' provides an additional feature that is not available in
+ `sub' or `gsub': the ability to specify components of a regexp in
+ the replacement text. This is done by using parentheses in the
+ regexp to mark the components and then specifying `\N' in the
+ replacement text, where N is a digit from 1 to 9. For example:
+
+ $ gawk '
+ > BEGIN {
+ > a = "abc def"
+ > b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)
+ > print b
+ > }'
+ -| def abc
+
+ As with `sub', you must type two backslashes in order to get one
+ into the string. In the replacement text, the sequence `\0'
+ represents the entire matched text, as does the character `&'.
+
+ The following example shows how you can use the third argument to
+ control which match of the regexp should be changed:
+
+ $ echo a b c a b c |
+ > gawk '{ print gensub(/a/, "AA", 2) }'
+ -| a b c AA b c
+
+ In this case, `$0' is used as the default target string. `gensub'
+ returns the new string as its result, which is passed directly to
+ `print' for printing.
+
+ If the HOW argument is a string that does not begin with `g' or
+ `G', or if it is a number that is less than or equal to zero, only
+ one substitution is performed. If HOW is zero, `gawk' issues a
+ warning message.
+
+ If REGEXP does not match TARGET, `gensub''s return value is the
+ original unchanged value of TARGET.
+
+ `gensub' is a `gawk' extension; it is not available in
+ compatibility mode (*note Options::).
+
+`substr(STRING, START [, LENGTH])'
+ This returns a LENGTH-character-long substring of STRING, starting
+ at character number START. The first character of a string is
+ character number one.(3) For example, `substr("washington", 5, 3)'
+ returns `"ing"'.
+
+ If LENGTH is not present, this function returns the whole suffix of
+ STRING that begins at character number START. For example,
+ `substr("washington", 5)' returns `"ington"'. The whole suffix is
+ also returned if LENGTH is greater than the number of characters
+ remaining in the string, counting from character START.
+
+ If START is less than one, `substr' treats it as if it was one.
+ (POSIX doesn't specify what to do in this case: Unix `awk' acts
+ this way, and therefore `gawk' does too.) If START is greater
+ than the number of characters in the string, `substr' returns the
+ null string. Similarly, if LENGTH is present but less than or
+ equal to zero, the null string is returned.
+
+ The string returned by `substr' _cannot_ be assigned. Thus, it is
+ a mistake to attempt to change a portion of a string, as shown in
+ the following example:
+
+ string = "abcdef"
+ # try to get "abCDEf", won't work
+ substr(string, 3, 3) = "CDE"
+
+ It is also a mistake to use `substr' as the third argument of
+ `sub' or `gsub':
+
+ gsub(/xyz/, "pdq", substr($0, 5, 20)) # WRONG
+
+ (Some commercial versions of `awk' do in fact let you use `substr'
+ this way, but doing so is not portable.)
+
+ If you need to replace bits and pieces of a string, combine
+ `substr' with string concatenation, in the following manner:
+
+ string = "abcdef"
+ ...
+ string = substr(string, 1, 2) "CDE" substr(string, 6)
+
+`tolower(STRING)'
+ This returns a copy of STRING, with each uppercase character in
+ the string replaced with its corresponding lowercase character.
+ Nonalphabetic characters are left unchanged. For example,
+ `tolower("MiXeD cAsE 123")' returns `"mixed case 123"'.
+
+`toupper(STRING)'
+ This returns a copy of STRING, with each lowercase character in
+ the string replaced with its corresponding uppercase character.
+ Nonalphabetic characters are left unchanged. For example,
+ `toupper("MiXeD cAsE 123")' returns `"MIXED CASE 123"'.
+
+---------- Footnotes ----------
+
+(1) Unless you use the `--non-decimal-data' option, which isn't
+recommended. *Note Nondecimal Data::, for more information.
+
+(2) Note that this means that the record will first be regenerated
+using the value of `OFS' if any fields have been changed, and that the
+fields will be updated after the substituion, even if the operation is
+a "no-op" such as `sub(/^/, "")'.
+
+(3) This is different from C and C++, in which the first character is
+number zero.
+
+\1f
+File: gawk.info, Node: Gory Details, Up: String Functions
+
+8.1.3.1 More About `\' and `&' with `sub', `gsub', and `gensub'
+...............................................................
+
+When using `sub', `gsub', or `gensub', and trying to get literal
+backslashes and ampersands into the replacement text, you need to
+remember that there are several levels of "escape processing" going on.
+
+First, there is the "lexical" level, which is when `awk' reads your
+program and builds an internal copy of it that can be executed. Then
+there is the runtime level, which is when `awk' actually scans the
+replacement string to determine what to generate.
+
+At both levels, `awk' looks for a defined set of characters that can
+come after a backslash. At the lexical level, it looks for the escape
+sequences listed in *Note Escape Sequences::. Thus, for every `\' that
+`awk' processes at the runtime level, type two backslashes at the
+lexical level. When a character that is not valid for an escape
+sequence follows the `\', Unix `awk' and `gawk' both simply remove the
+initial `\' and put the next character into the string. Thus, for
+example, `"a\qb"' is treated as `"aqb"'.
+
+At the runtime level, the various functions handle sequences of `\' and
+`&' differently. The situation is (sadly) somewhat complex.
+Historically, the `sub' and `gsub' functions treated the two character
+sequence `\&' specially; this sequence was replaced in the generated
+text with a single `&'. Any other `\' within the REPLACEMENT string
+that did not precede an `&' was passed through unchanged. This is
+illustrated in *Note table-sub-escapes::.
+
+ You type `sub' sees `sub' generates
+ ------- --------- --------------
+ `\&' `&' the matched text
+ `\\&' `\&' a literal `&'
+ `\\\&' `\&' a literal `&'
+ `\\\\&' `\\&' a literal `\&'
+ `\\\\\&' `\\&' a literal `\&'
+ `\\\\\\&' `\\\&' a literal `\\&'
+ `\\q' `\q' a literal `\q'
+
+Table 8.1: Historical Escape Sequence Processing for sub and gsub
+
+This table shows both the lexical-level processing, where an odd number
+of backslashes becomes an even number at the runtime level, as well as
+the runtime processing done by `sub'. (For the sake of simplicity, the
+rest of the following tables only show the case of even numbers of
+backslashes entered at the lexical level.)
+
+ The problem with the historical approach is that there is no way to
+get a literal `\' followed by the matched text.
+
+ The 1992 POSIX standard attempted to fix this problem. That standard
+says that `sub' and `gsub' look for either a `\' or an `&' after the
+`\'. If either one follows a `\', that character is output literally.
+The interpretation of `\' and `&' then becomes as shown in *Note
+table-sub-posix-92::.
+
+ You type `sub' sees `sub' generates
+ ------- --------- --------------
+ `&' `&' the matched text
+ `\\&' `\&' a literal `&'
+ `\\\\&' `\\&' a literal `\', then the matched text
+ `\\\\\\&' `\\\&' a literal `\&'
+
+Table 8.2: 1992 POSIX Rules for sub and gsub Escape Sequence Processing
+
+This appears to solve the problem. Unfortunately, the phrasing of the
+standard is unusual. It says, in effect, that `\' turns off the special
+meaning of any following character, but for anything other than `\' and
+`&', such special meaning is undefined. This wording leads to two
+problems:
+
+ * Backslashes must now be doubled in the REPLACEMENT string, breaking
+ historical `awk' programs.
+
+ * To make sure that an `awk' program is portable, _every_ character
+ in the REPLACEMENT string must be preceded with a backslash.(1)
+
+ Because of the problems just listed, in 1996, the `gawk' maintainer
+submitted proposed text for a revised standard that reverts to rules
+that correspond more closely to the original existing practice. The
+proposed rules have special cases that make it possible to produce a
+`\' preceding the matched text. This is shown in *Note
+table-sub-proposed::.
+
+ You type `sub' sees `sub' generates
+ ------- --------- --------------
+ `\\\\\\&' `\\\&' a literal `\&'
+ `\\\\&' `\\&' a literal `\', followed by the matched text
+ `\\&' `\&' a literal `&'
+ `\\q' `\q' a literal `\q'
+ `\\\\' `\\' `\\'
+
+Table 8.3: Propsosed rules for sub and backslash
+
+ In a nutshell, at the runtime level, there are now three special
+sequences of characters (`\\\&', `\\&' and `\&') whereas historically
+there was only one. However, as in the historical case, any `\' that
+is not part of one of these three sequences is not special and appears
+in the output literally.
+
+ `gawk' 3.0 and 3.1 follow these proposed POSIX rules for `sub' and
+`gsub'. The POSIX standard took much longer to be revised than was
+expected in 1996. The 2001 standard does not follow the above rules.
+Instead, the rules there are somewhat simpler. The results are similar
+except for one case.
+
+ The 2001 POSIX rules state that `\&' in the replacement string
+produces a literal `&', `\\' produces a literal `\', and `\' followed
+by anything else is not special; the `\' is placed straight into the
+output. These rules are presented in *Note table-posix-2001-sub::.
+
+ You type `sub' sees `sub' generates
+ ------- --------- --------------
+ `\\\\\\&' `\\\&' a literal `\&'
+ `\\\\&' `\\&' a literal `\', followed by the matched text
+ `\\&' `\&' a literal `&'
+ `\\q' `\q' a literal `\q'
+ `\\\\' `\\' `\'
+
+Table 8.4: POSIX 2001 rules for sub
+
+ The only case where the difference is noticeable is the last one:
+`\\\\' is seen as `\\' and produces `\' instead of `\\'.
+
+ Starting with version 3.1.4, `gawk' follows the POSIX rules when
+`--posix' is specified (*note Options::). Otherwise, it continues to
+follow the 1996 proposed rules, since, as of this writing, that has
+been its behavior for over seven years.
+
+ NOTE: At the next major release, `gawk' will switch to using the
+ POSIX 2001 rules by default.
+
+ The rules for `gensub' are considerably simpler. At the runtime
+level, whenever `gawk' sees a `\', if the following character is a
+digit, then the text that matched the corresponding parenthesized
+subexpression is placed in the generated output. Otherwise, no matter
+what character follows the `\', it appears in the generated text and
+the `\' does not, as shown in *Note table-gensub-escapes::.
+
+ You type `gensub' sees `gensub' generates
+ ------- ------------ -----------------
+ `&' `&' the matched text
+ `\\&' `\&' a literal `&'
+ `\\\\' `\\' a literal `\'
+ `\\\\&' `\\&' a literal `\', then the matched text
+ `\\\\\\&' `\\\&' a literal `\&'
+ `\\q' `\q' a literal `q'
+
+Table 8.5: Escape Sequence Processing for gensub
+
+ Because of the complexity of the lexical and runtime level processing
+and the special cases for `sub' and `gsub', we recommend the use of
+`gawk' and `gensub' when you have to do substitutions.
+
+Advanced Notes: Matching the Null String
+----------------------------------------
+
+In `awk', the `*' operator can match the null string. This is
+particularly important for the `sub', `gsub', and `gensub' functions.
+For example:
+
+ $ echo abc | awk '{ gsub(/m*/, "X"); print }'
+ -| XaXbXcX
+
+Although this makes a certain amount of sense, it can be surprising.
+
+---------- Footnotes ----------
+
+(1) This consequence was certainly unintended.
+
+\1f
+File: gawk.info, Node: I/O Functions, Next: Time Functions, Prev: String Functions, Up: Built-in
+
+8.1.5 Input/Output Functions
+----------------------------
+
+The following functions relate to input/output (I/O). Optional
+parameters are enclosed in square brackets ([ ]):
+
+`close(FILENAME [, HOW])'
+ Close the file FILENAME for input or output. Alternatively, the
+ argument may be a shell command that was used for creating a
+ coprocess, or for redirecting to or from a pipe; then the
+ coprocess or pipe is closed. *Note Close Files And Pipes::, for
+ more information.
+
+ When closing a coprocess, it is occasionally useful to first close
+ one end of the two-way pipe and then to close the other. This is
+ done by providing a second argument to `close'. This second
+ argument should be one of the two string values `"to"' or `"from"',
+ indicating which end of the pipe to close. Case in the string does
+ not matter. *Note Two-way I/O::, which discusses this feature in
+ more detail and gives an example.
+
+`fflush([FILENAME])'
+ Flush any buffered output associated with FILENAME, which is
+ either a file opened for writing or a shell command for
+ redirecting output to a pipe or coprocess.
+
+ Many utility programs "buffer" their output; i.e., they save
+ information to write to a disk file or terminal in memory until
+ there is enough for it to be worthwhile to send the data to the
+ output device. This is often more efficient than writing every
+ little bit of information as soon as it is ready. However,
+ sometimes it is necessary to force a program to "flush" its
+ buffers; that is, write the information to its destination, even
+ if a buffer is not full. This is the purpose of the `fflush'
+ function--`gawk' also buffers its output and the `fflush' function
+ forces `gawk' to flush its buffers.
+
+ `fflush' was added to the Bell Laboratories research version of
+ `awk' in 1994; it is not part of the POSIX standard and is not
+ available if `--posix' has been specified on the command line
+ (*note Options::).
+
+ `gawk' extends the `fflush' function in two ways. The first is to
+ allow no argument at all. In this case, the buffer for the
+ standard output is flushed. The second is to allow the null string
+ (`""') as the argument. In this case, the buffers for _all_ open
+ output files and pipes are flushed.
+
+ `fflush' returns zero if the buffer is successfully flushed;
+ otherwise, it returns -1. In the case where all buffers are
+ flushed, the return value is zero only if all buffers were flushed
+ successfully. Otherwise, it is -1, and `gawk' warns about the
+ problem FILENAME.
+
+ `gawk' also issues a warning message if you attempt to flush a
+ file or pipe that was opened for reading (such as with `getline'),
+ or if FILENAME is not an open file, pipe, or coprocess. In such a
+ case, `fflush' returns -1, as well.
+
+`system(COMMAND)'
+ Executes operating-system commands and then returns to the `awk'
+ program. The `system' function executes the command given by the
+ string COMMAND. It returns the status returned by the command
+ that was executed as its value.
+
+ For example, if the following fragment of code is put in your `awk'
+ program:
+
+ END {
+ system("date | mail -s 'awk run done' root")
+ }
+
+ the system administrator is sent mail when the `awk' program
+ finishes processing input and begins its end-of-input processing.
+
+ Note that redirecting `print' or `printf' into a pipe is often
+ enough to accomplish your task. If you need to run many commands,
+ it is more efficient to simply print them down a pipeline to the
+ shell:
+
+ while (MORE STUFF TO DO)
+ print COMMAND | "/bin/sh"
+ close("/bin/sh")
+
+ However, if your `awk' program is interactive, `system' is useful
+ for cranking up large self-contained programs, such as a shell or
+ an editor. Some operating systems cannot implement the `system'
+ function. `system' causes a fatal error if it is not supported.
+
+Advanced Notes: Interactive Versus Noninteractive Buffering
+-----------------------------------------------------------
+
+As a side point, buffering issues can be even more confusing, depending
+upon whether your program is "interactive", i.e., communicating with a
+user sitting at a keyboard.(1)
+
+Interactive programs generally "line buffer" their output; i.e., they
+write out every line. Noninteractive programs wait until they have a
+full buffer, which may be many lines of output. Here is an example of
+the difference:
+
+ $ awk '{ print $1 + $2 }'
+ 1 1
+ -| 2
+ 2 3
+ -| 5
+ Ctrl-d
+
+Each line of output is printed immediately. Compare that behavior with
+this example:
+
+ $ awk '{ print $1 + $2 }' | cat
+ 1 1
+ 2 3
+ Ctrl-d
+ -| 2
+ -| 5
+
+Here, no output is printed until after the `Ctrl-d' is typed, because
+it is all buffered and sent down the pipe to `cat' in one shot.
+
+Advanced Notes: Controlling Output Buffering with `system'
+----------------------------------------------------------
+
+The `fflush' function provides explicit control over output buffering
+for individual files and pipes. However, its use is not portable to
+many other `awk' implementations. An alternative method to flush output
+buffers is to call `system' with a null string as its argument:
+
+ system("") # flush output
+
+`gawk' treats this use of the `system' function as a special case and
+is smart enough not to run a shell (or other command interpreter) with
+the empty command. Therefore, with `gawk', this idiom is not only
+useful, it is also efficient. While this method should work with other
+`awk' implementations, it does not necessarily avoid starting an
+unnecessary shell. (Other implementations may only flush the buffer
+associated with the standard output and not necessarily all buffered
+output.)
+
+If you think about what a programmer expects, it makes sense that
+`system' should flush any pending output. The following program:
+
+ BEGIN {
+ print "first print"
+ system("echo system echo")
+ print "second print"
+ }
+
+must print:
+
+ first print
+ system echo
+ second print
+
+and not:
+
+ system echo
+ first print
+ second print
+
+If `awk' did not flush its buffers before calling `system', you would
+see the latter (undesirable) output.
+
+---------- Footnotes ----------
+
+(1) A program is interactive if the standard output is connected to a
+terminal device.
+
+\1f
+File: gawk.info, Node: Time Functions, Next: Bitwise Functions, Prev: I/O Functions, Up: Built-in
+
+8.1.8 Using `gawk''s Timestamp Functions
+----------------------------------------
+
+`awk' programs are commonly used to process log files containing
+timestamp information, indicating when a particular log record was
+written. Many programs log their timestamp in the form returned by the
+`time' system call, which is the number of seconds since a particular
+epoch. On POSIX-compliant systems, it is the number of seconds since
+1970-01-01 00:00:00 UTC, not counting leap seconds.(1) All known
+POSIX-compliant systems support timestamps from 0 through 2^31 - 1,
+which is sufficient to represent times through 2038-01-19 03:14:07 UTC.
+Many systems support a wider range of timestamps, including negative
+timestamps that represent times before the epoch.
+
+In order to make it easier to process such log files and to produce
+useful reports, `gawk' provides the following functions for working
+with timestamps. They are `gawk' extensions; they are not specified in
+the POSIX standard, nor are they in any other known version of `awk'.(2)
+Optional parameters are enclosed in square brackets ([ ]):
+
+`systime()'
+ This function returns the current time as the number of seconds
+ since the system epoch. On POSIX systems, this is the number of
+ seconds since 1970-01-01 00:00:00 UTC, not counting leap seconds.
+ It may be a different number on other systems.
+
+`mktime(DATESPEC)'
+ This function turns DATESPEC into a timestamp in the same form as
+ is returned by `systime'. It is similar to the function of the
+ same name in ISO C. The argument, DATESPEC, is a string of the
+ form `"YYYY MM DD HH MM SS [DST]"'. The string consists of six or
+ seven numbers representing, respectively, the full year including
+ century, the month from 1 to 12, the day of the month from 1 to
+ 31, the hour of the day from 0 to 23, the minute from 0 to 59, the
+ second from 0 to 60,(3) and an optional daylight-savings flag.
+
+ The values of these numbers need not be within the ranges
+ specified; for example, an hour of -1 means 1 hour before midnight.
+ The origin-zero Gregorian calendar is assumed, with year 0
+ preceding year 1 and year -1 preceding year 0. The time is
+ assumed to be in the local timezone. If the daylight-savings flag
+ is positive, the time is assumed to be daylight savings time; if
+ zero, the time is assumed to be standard time; and if negative
+ (the default), `mktime' attempts to determine whether daylight
+ savings time is in effect for the specified time.
+
+ If DATESPEC does not contain enough elements or if the resulting
+ time is out of range, `mktime' returns -1.
+
+`strftime([FORMAT [, TIMESTAMP]])'
+ This function returns a string. It is similar to the function of
+ the same name in ISO C. The time specified by TIMESTAMP is used to
+ produce a string, based on the contents of the FORMAT string. The
+ TIMESTAMP is in the same format as the value returned by the
+ `systime' function. If no TIMESTAMP argument is supplied, `gawk'
+ uses the current time of day as the timestamp. If no FORMAT
+ argument is supplied, `strftime' uses `"%a %b %d %H:%M:%S %Z %Y"'.
+ This format string produces output that is (almost) equivalent to
+ that of the `date' utility. (Versions of `gawk' prior to 3.0
+ require the FORMAT argument.)
+
+The `systime' function allows you to compare a timestamp from a log
+file with the current time of day. In particular, it is easy to
+determine how long ago a particular record was logged. It also allows
+you to produce log records using the "seconds since the epoch" format.
+
+The `mktime' function allows you to convert a textual representation of
+a date and time into a timestamp. This makes it easy to do
+before/after comparisons of dates and times, particularly when dealing
+with date and time data coming from an external source, such as a log
+file.
+
+The `strftime' function allows you to easily turn a timestamp into
+human-readable information. It is similar in nature to the `sprintf'
+function (*note String Functions::), in that it copies nonformat
+specification characters verbatim to the returned string, while
+substituting date and time values for format specifications in the
+FORMAT string.
+
+`strftime' is guaranteed by the 1999 ISO C standard(4) to support the
+following date format specifications:
+
+`%a'
+ The locale's abbreviated weekday name.
+
+`%A'
+ The locale's full weekday name.
+
+`%b'
+ The locale's abbreviated month name.
+
+`%B'
+ The locale's full month name.
+
+`%c'
+ The locale's "appropriate" date and time representation. (This is
+ `%A %B %d %T %Y' in the `"C"' locale.)
+
+`%C'
+ The century. This is the year divided by 100 and truncated to the
+ next lower integer.
+
+`%d'
+ The day of the month as a decimal number (01-31).
+
+`%D'
+ Equivalent to specifying `%m/%d/%y'.
+
+`%e'
+ The day of the month, padded with a space if it is only one digit.
+
+`%F'
+ Equivalent to specifying `%Y-%m-%d'. This is the ISO 8601 date
+ format.
+
+`%g'
+ The year modulo 100 of the ISO week number, as a decimal number
+ (00-99). For example, January 1, 1993 is in week 53 of 1992.
+ Thus, the year of its ISO week number is 1992, even though its
+ year is 1993. Similarly, December 31, 1973 is in week 1 of 1974.
+ Thus, the year of its ISO week number is 1974, even though its
+ year is 1973.
+
+`%G'
+ The full year of the ISO week number, as a decimal number.
+
+`%h'
+ Equivalent to `%b'.
+
+`%H'
+ The hour (24-hour clock) as a decimal number (00-23).
+
+`%I'
+ The hour (12-hour clock) as a decimal number (01-12).
+
+`%j'
+ The day of the year as a decimal number (001-366).
+
+`%m'
+ The month as a decimal number (01-12).
+
+`%M'
+ The minute as a decimal number (00-59).
+
+`%n'
+ A newline character (ASCII LF).
+
+`%p'
+ The locale's equivalent of the AM/PM designations associated with
+ a 12-hour clock.
+
+`%r'
+ The locale's 12-hour clock time. (This is `%I:%M:%S %p' in the
+ `"C"' locale.)
+
+`%R'
+ Equivalent to specifying `%H:%M'.
+
+`%S'
+ The second as a decimal number (00-60).
+
+`%t'
+ A TAB character.
+
+`%T'
+ Equivalent to specifying `%H:%M:%S'.
+
+`%u'
+ The weekday as a decimal number (1-7). Monday is day one.
+
+`%U'
+ The week number of the year (the first Sunday as the first day of
+ week one) as a decimal number (00-53).
+
+`%V'
+ The week number of the year (the first Monday as the first day of
+ week one) as a decimal number (01-53). The method for determining
+ the week number is as specified by ISO 8601. (To wit: if the week
+ containing January 1 has four or more days in the new year, then
+ it is week one; otherwise it is week 53 of the previous year and
+ the next week is week one.)
+
+`%w'
+ The weekday as a decimal number (0-6). Sunday is day zero.
+
+`%W'
+ The week number of the year (the first Monday as the first day of
+ week one) as a decimal number (00-53).
+
+`%x'
+ The locale's "appropriate" date representation. (This is `%A %B
+ %d %Y' in the `"C"' locale.)
+
+`%X'
+ The locale's "appropriate" time representation. (This is `%T' in
+ the `"C"' locale.)
+
+`%y'
+ The year modulo 100 as a decimal number (00-99).
+
+`%Y'
+ The full year as a decimal number (e.g., 1995).
+
+`%z'
+ The timezone offset in a +HHMM format (e.g., the format necessary
+ to produce RFC 822/RFC 1036 date headers).
+
+`%Z'
+ The time zone name or abbreviation; no characters if no time zone
+ is determinable.
+
+`%Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH'
+`%OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy'
+ "Alternate representations" for the specifications that use only
+ the second letter (`%c', `%C', and so on).(5) (These facilitate
+ compliance with the POSIX `date' utility.)
+
+`%%'
+ A literal `%'.
+
+If a conversion specifier is not one of the above, the behavior is
+undefined.(6)
+
+Informally, a "locale" is the geographic place in which a program is
+meant to run. For example, a common way to abbreviate the date
+September 4, 1991 in the United States is "9/4/91." In many countries
+in Europe, however, it is abbreviated "4.9.91." Thus, the `%x'
+specification in a `"US"' locale might produce `9/4/91', while in a
+`"EUROPE"' locale, it might produce `4.9.91'. The ISO C standard
+defines a default `"C"' locale, which is an environment that is typical
+of what most C programmers are used to.
+
+A public-domain C version of `strftime' is supplied with `gawk' for
+systems that are not yet fully standards-compliant. It supports all of
+the just listed format specifications. If that version is used to
+compile `gawk' (*note Installation::), then the following additional
+format specifications are available:
+
+`%k'
+ The hour (24-hour clock) as a decimal number (0-23). Single-digit
+ numbers are padded with a space.
+
+`%l'
+ The hour (12-hour clock) as a decimal number (1-12). Single-digit
+ numbers are padded with a space.
+
+`%N'
+ The "Emperor/Era" name. Equivalent to `%C'.
+
+`%o'
+ The "Emperor/Era" year. Equivalent to `%y'.
+
+`%s'
+ The time as a decimal timestamp in seconds since the epoch.
+
+`%v'
+ The date in VMS format (e.g., `20-JUN-1991').
+
+Additionally, the alternate representations are recognized but their
+normal representations are used.
+
+This example is an `awk' implementation of the POSIX `date' utility.
+Normally, the `date' utility prints the current date and time of day in
+a well-known format. However, if you provide an argument to it that
+begins with a `+', `date' copies nonformat specifier characters to the
+standard output and interprets the current time according to the format
+specifiers in the string. For example:
+
+ $ date '+Today is %A, %B %d, %Y.'
+ -| Today is Thursday, September 14, 2000.
+
+Here is the `gawk' version of the `date' utility. It has a shell
+"wrapper" to handle the `-u' option, which requires that `date' run as
+if the time zone is set to UTC:
+
+ #! /bin/sh
+ #
+ # date --- approximate the P1003.2 'date' command
+
+ case $1 in
+ -u) TZ=UTC0 # use UTC
+ export TZ
+ shift ;;
+ esac
+
+ gawk 'BEGIN {
+ format = "%a %b %d %H:%M:%S %Z %Y"
+ exitval = 0
+
+ if (ARGC > 2)
+ exitval = 1
+ else if (ARGC == 2) {
+ format = ARGV[1]
+ if (format ~ /^\+/)
+ format = substr(format, 2) # remove leading +
+ }
+ print strftime(format)
+ exit exitval
+ }' "$@"
+
+---------- Footnotes ----------
+
+(1) *Note Glossary::, especially the entries "Epoch" and "UTC."
+
+(2) The GNU `date' utility can also do many of the things described
+here. Its use may be preferable for simple time-related operations in
+shell scripts.
+
+(3) Occasionally there are minutes in a year with a leap second, which
+is why the seconds can go up to 60.
+
+(4) As this is a recent standard, not every system's `strftime'
+necessarily supports all of the conversions listed here.
+
+(5) If you don't understand any of this, don't worry about it; these
+facilities are meant to make it easier to "internationalize" programs.
+Other internationalization features are described in *Note
+Internationalization::.
+
+(6) This is because ISO C leaves the behavior of the C version of
+`strftime' undefined and `gawk' uses the system's version of `strftime'
+if it's there. Typically, the conversion specifier either does not
+appear in the returned string or appears literally.
+
+\1f
+File: gawk.info, Node: Bitwise Functions, Next: I18N Functions, Prev: Time Functions, Up: Built-in
+
+8.1.9 Bit-Manipulation Functions of `gawk'
+------------------------------------------
+
+ I can explain it for you, but I can't understand it for you.
+ Anonymous
+
+Many languages provide the ability to perform "bitwise" operations on
+two integer numbers. In other words, the operation is performed on
+each successive pair of bits in the operands. Three common operations
+are bitwise AND, OR, and XOR. The operations are described in *Note
+table-bitwise-ops::.
+
+ Bit Operator
+ | AND | OR | XOR
+ |--+--+--+--+--+--
+ Operands | 0 | 1 | 0 | 1 | 0 | 1
+ ---------+--+--+--+--+--+--
+ 0 | 0 0 | 0 1 | 0 1
+ 1 | 0 1 | 1 1 | 1 0
+
+Table 8.6: Bitwise Operations
+
+ As you can see, the result of an AND operation is 1 only when _both_
+bits are 1. The result of an OR operation is 1 if _either_ bit is 1.
+The result of an XOR operation is 1 if either bit is 1, but not both.
+The next operation is the "complement"; the complement of 1 is 0 and
+the complement of 0 is 1. Thus, this operation "flips" all the bits of
+a given value.
+
+ Finally, two other common operations are to shift the bits left or
+right. For example, if you have a bit string `10111001' and you shift
+it right by three bits, you end up with `00010111'.(1) If you start over
+again with `10111001' and shift it left by three bits, you end up with
+`11001000'. `gawk' provides built-in functions that implement the
+bitwise operations just described. They are:
+
+`and(V1, V2)' Returns the bitwise AND of the values provided by V1
+ and V2.
+`or(V1, V2)' Returns the bitwise OR of the values provided by V1
+ and V2.
+`xor(V1, V2)' Returns the bitwise XOR of the values provided by V1
+ and V2.
+`compl(VAL)' Returns the bitwise complement of VAL.
+`lshift(VAL, COUNT)' Returns the value of VAL, shifted left by COUNT bits.
+`rshift(VAL, COUNT)' Returns the value of VAL, shifted right by COUNT bits.
+
+ For all of these functions, first the double-precision
+floating-point value is converted to the widest C unsigned integer
+type, then the bitwise operation is performed. If the result cannot be
+represented exactly as a C `double', leading nonzero bits are removed
+one by one until it can be represented exactly. The result is then
+converted back into a C `double'. (If you don't understand this
+paragraph, don't worry about it.)
+
+ Here is a user-defined function (*note User-defined::) that
+illustrates the use of these functions:
+
+ # 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
+ }
+
+ 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)
+ }
+
+This program produces the following output when run:
+
+ $ gawk -f testbits.awk
+ -| 123 = 01111011
+ -| 0123 = 01010011
+ -| 0x99 = 10011001
+ -| compl(0x99) = 0xffffff66 = 11111111111111111111111101100110
+ -| lshift(0x99, 2) = 0x264 = 0000001001100100
+ -| rshift(0x99, 2) = 0x26 = 00100110
+
+The `bits2str' function turns a binary number into a string. The
+number `1' represents a binary value where the rightmost bit is set to
+1. Using this mask, the function repeatedly checks the rightmost bit.
+ANDing the mask with the value indicates whether the rightmost bit is 1
+or not. If so, a `"1"' is concatenated onto the front of the string.
+Otherwise, a `"0"' is added. The value is then shifted right by one
+bit and the loop continues until there are no more 1 bits.
+
+If the initial value is zero it returns a simple `"0"'. Otherwise, at
+the end, it pads the value with zeros to represent multiples of 8-bit
+quantities. This is typical in modern computers.
+
+The main code in the `BEGIN' rule shows the difference between the
+decimal and octal values for the same numbers (*note
+Nondecimal-numbers::), and then demonstrates the results of the
+`compl', `lshift', and `rshift' functions.
+
+---------- Footnotes ----------
+
+(1) This example shows that 0's come in on the left side. For `gawk',
+this is always true, but in some languages, it's possible to have the
+left side fill with 1's. Caveat emptor.
+
+\1f
+File: gawk.info, Node: I18N Functions, Prev: Bitwise Functions, Up: Built-in
+
+8.1.10 Using `gawk''s String-Translation Functions
+--------------------------------------------------
+
+`gawk' provides facilities for internationalizing `awk' programs.
+These include the functions described in the following list. The
+descriptions here are purposely brief. *Note Internationalization::,
+for the full story. Optional parameters are enclosed in square
+brackets ([ ]):
+
+`dcgettext(STRING [, DOMAIN [, CATEGORY]])'
+ This function returns the translation of STRING in text domain
+ DOMAIN for locale category CATEGORY. The default value for DOMAIN
+ is the current value of `TEXTDOMAIN'. The default value for
+ CATEGORY is `"LC_MESSAGES"'.
+
+`dcngettext(STRING1, STRING2, NUMBER [, DOMAIN [, CATEGORY]])'
+ This function returns the plural form used for NUMBER of the
+ translation of STRING1 and STRING2 in text domain DOMAIN for
+ locale category CATEGORY. STRING1 is the English singular variant
+ of a message, and STRING2 the English plural variant of the same
+ message. The default value for DOMAIN is the current value of
+ `TEXTDOMAIN'. The default value for CATEGORY is `"LC_MESSAGES"'.
+
+`bindtextdomain(DIRECTORY [, DOMAIN])'
+ This function allows you to specify the directory in which `gawk'
+ will look for message translation files, in case they will not or
+ cannot be placed in the "standard" locations (e.g., during
+ testing). It returns the directory in which DOMAIN is "bound."
+
+ The default DOMAIN is the value of `TEXTDOMAIN'. If DIRECTORY is
+ the null string (`""'), then `bindtextdomain' returns the current
+ binding for the given DOMAIN.
+
+\1f
+File: gawk.info, Node: User-defined, Prev: Built-in, Up: Functions
+
+8.2 User-Defined Functions
+==========================
+
+Complicated `awk' programs can often be simplified by defining your own
+functions. User-defined functions can be called just like built-in
+ones (*note Function Calls::), but it is up to you to define them,
+i.e., to tell `awk' what they should do.
+
+* Menu:
+
+* Definition Syntax:: How to write definitions and what they mean.
+* Function Example:: An example function definition and what it
+ does.
+* Function Caveats:: Things to watch out for.
+* Return Statement:: Specifying the value a function returns.
+* Dynamic Typing:: How variable types can change at runtime.
+
+\1f
+File: gawk.info, Node: Definition Syntax, Next: Function Example, Up: User-defined
+
+8.2.1 Function Definition Syntax
+--------------------------------
+
+Definitions of functions can appear anywhere between the rules of an
+`awk' program. Thus, the general form of an `awk' program is extended
+to include sequences of rules _and_ user-defined function definitions.
+There is no need to put the definition of a function before all uses of
+the function. This is because `awk' reads the entire program before
+starting to execute any of it.
+
+The definition of a function named NAME looks like this:
+
+ function NAME(PARAMETER-LIST)
+ {
+ BODY-OF-FUNCTION
+ }
+
+NAME is the name of the function to define. A valid function name is
+like a valid variable name: a sequence of letters, digits, and
+underscores that doesn't start with a digit. Within a single `awk'
+program, any particular name can only be used as a variable, array, or
+function.
+
+PARAMETER-LIST is a list of the function's arguments and local variable
+names, separated by commas. When the function is called, the argument
+names are used to hold the argument values given in the call. The
+local variables are initialized to the empty string. A function cannot
+have two parameters with the same name, nor may it have a parameter
+with the same name as the function itself.
+
+The BODY-OF-FUNCTION consists of `awk' statements. It is the most
+important part of the definition, because it says what the function
+should actually _do_. The argument names exist to give the body a way
+to talk about the arguments; local variables exist to give the body
+places to keep temporary values.
+
+Argument names are not distinguished syntactically from local variable
+names. Instead, the number of arguments supplied when the function is
+called determines how many argument variables there are. Thus, if three
+argument values are given, the first three names in PARAMETER-LIST are
+arguments and the rest are local variables.
+
+It follows that if the number of arguments is not the same in all calls
+to the function, some of the names in PARAMETER-LIST may be arguments
+on some occasions and local variables on others. Another way to think
+of this is that omitted arguments default to the null string.
+
+Usually when you write a function, you know how many names you intend to
+use for arguments and how many you intend to use as local variables.
+It is conventional to place some extra space between the arguments and
+the local variables, in order to document how your function is supposed
+to be used.
+
+During execution of the function body, the arguments and local variable
+values hide, or "shadow", any variables of the same names used in the
+rest of the program. The shadowed variables are not accessible in the
+function definition, because there is no way to name them while their
+names have been taken away for the local variables. All other variables
+used in the `awk' program can be referenced or set normally in the
+function's body.
+
+The arguments and local variables last only as long as the function body
+is executing. Once the body finishes, you can once again access the
+variables that were shadowed while the function was running.
+
+The function body can contain expressions that call functions. They
+can even call this function, either directly or by way of another
+function. When this happens, we say the function is "recursive". The
+act of a function calling itself is called "recursion".
+
+In many `awk' implementations, including `gawk', the keyword `function'
+may be abbreviated `func'. However, POSIX only specifies the use of
+the keyword `function'. This actually has some practical implications.
+If `gawk' is in POSIX-compatibility mode (*note Options::), then the
+following statement does _not_ define a function:
+
+ func foo() { a = sqrt($1) ; print a }
+
+Instead it defines a rule that, for each record, concatenates the value
+of the variable `func' with the return value of the function `foo'. If
+the resulting string is non-null, the action is executed. This is
+probably not what is desired. (`awk' accepts this input as
+syntactically valid, because functions may be used before they are
+defined in `awk' programs.)
+
+To ensure that your `awk' programs are portable, always use the keyword
+`function' when defining a function.
+
+\1f
+File: gawk.info, Node: Function Example, Next: Function Caveats, Prev: Definition Syntax, Up: User-defined
+
+8.2.2 Function Definition Examples
+----------------------------------
+
+Here is an example of a user-defined function, called `myprint', that
+takes a number and prints it in a specific format:
+
+ function myprint(num)
+ {
+ printf "%6.3g\n", num
+ }
+
+To illustrate, here is an `awk' rule that uses our `myprint' function:
+
+ $3 > 0 { myprint($3) }
+
+This program prints, in our special format, all the third fields that
+contain a positive number in our input. Therefore, when given the
+following:
+
+ 1.2 3.4 5.6 7.8
+ 9.10 11.12 -13.14 15.16
+ 17.18 19.20 21.22 23.24
+
+this program, using our function to format the results, prints:
+
+ 5.6
+ 21.2
+
+This function deletes all the elements in an array:
+
+ function delarray(a, i)
+ {
+ for (i in a)
+ delete a[i]
+ }
+
+When working with arrays, it is often necessary to delete all the
+elements in an array and start over with a new list of elements (*note
+Delete::). Instead of having to repeat this loop everywhere that you
+need to clear out an array, your program can just call `delarray'.
+(This guarantees portability. The use of `delete ARRAY' to delete the
+contents of an entire array is a nonstandard extension.)
+
+The following is an example of a recursive function. It takes a string
+as an input parameter and returns the string in backwards order.
+Recursive functions must always have a test that stops the recursion.
+In this case, the recursion terminates when the starting position is
+zero, i.e., when there are no more characters left in the string.
+
+ function rev(str, start)
+ {
+ if (start == 0)
+ return ""
+
+ return (substr(str, start, 1) rev(str, start - 1))
+ }
+
+If this function is in a file named `rev.awk', it can be tested this
+way:
+
+ $ echo "Don't Panic!" |
+ > gawk --source '{ print rev($0, length($0)) }' -f rev.awk
+ -| !cinaP t'noD
+
+The C `ctime' function takes a timestamp and returns it in a string,
+formatted in a well-known fashion. The following example uses the
+built-in `strftime' function (*note Time Functions::) to create an
+`awk' version of `ctime':
+
+ # ctime.awk
+ #
+ # awk version of C ctime(3) function
+
+ function ctime(ts, format)
+ {
+ format = "%a %b %d %H:%M:%S %Z %Y"
+ if (ts == 0)
+ ts = systime() # use current time as default
+ return strftime(format, ts)
+ }
+
+\1f
+File: gawk.info, Node: Function Caveats, Next: Return Statement, Prev: Function Example, Up: User-defined
+
+8.2.3 Calling User-Defined Functions
+------------------------------------
+
+"Calling a function" means causing the function to run and do its job.
+A function call is an expression and its value is the value returned by
+the function.
+
+A function call consists of the function name followed by the arguments
+in parentheses. `awk' expressions are what you write in the call for
+the arguments. Each time the call is executed, these expressions are
+evaluated, and the values are the actual arguments. For example, here
+is a call to `foo' with three arguments (the first being a string
+concatenation):
+
+ foo(x y, "lose", 4 * z)
+
+*Caution:* Whitespace characters (spaces and tabs) are not allowed
+between the function name and the open-parenthesis of the argument list.
+If you write whitespace by mistake, `awk' might think that you mean to
+concatenate a variable with an expression in parentheses. However, it
+notices that you used a function name and not a variable name, and
+reports an error.
+
+When a function is called, it is given a _copy_ of the values of its
+arguments. This is known as "call by value". The caller may use a
+variable as the expression for the argument, but the called function
+does not know this--it only knows what value the argument had. For
+example, if you write the following code:
+
+ foo = "bar"
+ z = myfunc(foo)
+
+then you should not think of the argument to `myfunc' as being "the
+variable `foo'." Instead, think of the argument as the string value
+`"bar"'. If the function `myfunc' alters the values of its local
+variables, this has no effect on any other variables. Thus, if `myfunc'
+does this:
+
+ function myfunc(str)
+ {
+ print str
+ str = "zzz"
+ print str
+ }
+
+to change its first argument variable `str', it does _not_ change the
+value of `foo' in the caller. The role of `foo' in calling `myfunc'
+ended when its value (`"bar"') was computed. If `str' also exists
+outside of `myfunc', the function body cannot alter this outer value,
+because it is shadowed during the execution of `myfunc' and cannot be
+seen or changed from there.
+
+However, when arrays are the parameters to functions, they are _not_
+copied. Instead, the array itself is made available for direct
+manipulation by the function. This is usually called "call by
+reference". Changes made to an array parameter inside the body of a
+function _are_ visible outside that function.
+
+ NOTE: Changing an array parameter inside a function can be very
+ dangerous if you do not watch what you are doing. For example:
+
+ function changeit(array, ind, nvalue)
+ {
+ array[ind] = nvalue
+ }
+
+ BEGIN {
+ a[1] = 1; a[2] = 2; a[3] = 3
+ changeit(a, 2, "two")
+ printf "a[1] = %s, a[2] = %s, a[3] = %s\n",
+ a[1], a[2], a[3]
+ }
+
+ prints `a[1] = 1, a[2] = two, a[3] = 3', because `changeit' stores
+ `"two"' in the second element of `a'.
+
+Some `awk' implementations allow you to call a function that has not
+been defined. They only report a problem at runtime when the program
+actually tries to call the function. For example:
+
+ BEGIN {
+ if (0)
+ foo()
+ else
+ bar()
+ }
+ function bar() { ... }
+ # note that `foo' is not defined
+
+Because the `if' statement will never be true, it is not really a
+problem that `foo' has not been defined. Usually, though, it is a
+problem if a program calls an undefined function.
+
+If `--lint' is specified (*note Options::), `gawk' reports calls to
+undefined functions.
+
+Some `awk' implementations generate a runtime error if you use the
+`next' statement (*note Next Statement::) inside a user-defined
+function. `gawk' does not have this limitation.
+
+\1f
+File: gawk.info, Node: Return Statement, Next: Dynamic Typing, Prev: Function Caveats, Up: User-defined
+
+8.2.4 The `return' Statement
+----------------------------
+
+The body of a user-defined function can contain a `return' statement.
+This statement returns control to the calling part of the `awk'
+program. It can also be used to return a value for use in the rest of
+the `awk' program. It looks like this:
+
+ return [EXPRESSION]
+
+The EXPRESSION part is optional. If it is omitted, then the returned
+value is undefined, and therefore, unpredictable.
+
+A `return' statement with no value expression is assumed at the end of
+every function definition. So if control reaches the end of the
+function body, then the function returns an unpredictable value. `awk'
+does _not_ warn you if you use the return value of such a function.
+
+Sometimes, you want to write a function for what it does, not for what
+it returns. Such a function corresponds to a `void' function in C or
+to a `procedure' in Pascal. Thus, it may be appropriate to not return
+any value; simply bear in mind that if you use the return value of such
+a function, you do so at your own risk.
+
+The following is an example of a user-defined function that returns a
+value for the largest number among the elements of an array:
+
+ function maxelt(vec, i, ret)
+ {
+ for (i in vec) {
+ if (ret == "" || vec[i] > ret)
+ ret = vec[i]
+ }
+ return ret
+ }
+
+You call `maxelt' with one argument, which is an array name. The local
+variables `i' and `ret' are not intended to be arguments; while there
+is nothing to stop you from passing more than one argument to `maxelt',
+the results would be strange. The extra space before `i' in the
+function parameter list indicates that `i' and `ret' are not supposed
+to be arguments. You should follow this convention when defining
+functions.
+
+The following program uses the `maxelt' function. It loads an array,
+calls `maxelt', and then reports the maximum number in that array:
+
+ function maxelt(vec, i, ret)
+ {
+ for (i in vec) {
+ if (ret == "" || vec[i] > ret)
+ ret = vec[i]
+ }
+ return ret
+ }
+
+ # Load all fields of each record into nums.
+ {
+ for(i = 1; i <= NF; i++)
+ nums[NR, i] = $i
+ }
+
+ END {
+ print maxelt(nums)
+ }
+
+Given the following input:
+
+ 1 5 23 8 16
+ 44 3 5 2 8 26
+ 256 291 1396 2962 100
+ -6 467 998 1101
+ 99385 11 0 225
+
+the program reports (predictably) that `99385' is the largest number in
+the array.
+
+\1f
+File: gawk.info, Node: Dynamic Typing, Prev: Return Statement, Up: User-defined
+
+8.2.5 Functions and Their Effects on Variable Typing
+----------------------------------------------------
+
+`awk' is a very fluid language. It is possible that `awk' can't tell
+if an identifier represents a regular variable or an array until
+runtime. Here is an annotated sample program:
+
+ function foo(a)
+ {
+ a[1] = 1 # parameter is an array
+ }
+
+ BEGIN {
+ b = 1
+ foo(b) # invalid: fatal type mismatch
+
+ foo(x) # x uninitialized, becomes an array dynamically
+ x = 1 # now not allowed, runtime error
+ }
+
+Usually, such things aren't a big issue, but it's worth being aware of
+them.
+
+\1f
+File: gawk.info, Node: Internationalization, Next: Advanced Features, Prev: Functions, Up: Top
+
+9 Internationalization with `gawk'
+**********************************
+
+Once upon a time, computer makers wrote software that worked only in
+English. Eventually, hardware and software vendors noticed that if
+their systems worked in the native languages of non-English-speaking
+countries, they were able to sell more systems. As a result,
+internationalization and localization of programs and software systems
+became a common practice.
+
+Until recently, the ability to provide internationalization was largely
+restricted to programs written in C and C++. This major node describes
+the underlying library `gawk' uses for internationalization, as well as
+how `gawk' makes internationalization features available at the `awk'
+program level. Having internationalization available at the `awk' level
+gives software developers additional flexibility--they are no longer
+required to write in C when internationalization is a requirement.
+
+* Menu:
+
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU `gettext' works.
+* Programmer i18n:: Features for the programmer.
+* Translator i18n:: Features for the translator.
+* I18N Example:: A simple i18n example.
+* Gawk I18N:: `gawk' is also internationalized.
+
+\1f
+File: gawk.info, Node: I18N and L10N, Next: Explaining gettext, Up: Internationalization
+
+9.1 Internationalization and Localization
+=========================================
+
+"Internationalization" means writing (or modifying) a program once, in
+such a way that it can use multiple languages without requiring further
+source-code changes. "Localization" means providing the data necessary
+for an internationalized program to work in a particular language.
+Most typically, these terms refer to features such as the language used
+for printing error messages, the language used to read responses, and
+information related to how numerical and monetary values are printed
+and read.
+
+\1f
+File: gawk.info, Node: Explaining gettext, Next: Programmer i18n, Prev: I18N and L10N, Up: Internationalization
+
+9.2 GNU `gettext'
+=================
+
+The facilities in GNU `gettext' focus on messages; strings printed by a
+program, either directly or via formatting with `printf' or
+`sprintf'.(1)
+
+When using GNU `gettext', each application has its own "text domain".
+This is a unique name, such as `kpilot' or `gawk', that identifies the
+application. A complete application may have multiple
+components--programs written in C or C++, as well as scripts written in
+`sh' or `awk'. All of the components use the same text domain.
+
+To make the discussion concrete, assume we're writing an application
+named `guide'. Internationalization consists of the following steps,
+in this order:
+
+ 1. The programmer goes through the source for all of `guide''s
+ components and marks each string that is a candidate for
+ translation. For example, `"`-F': option required"' is a good
+ candidate for translation. A table with strings of option names
+ is not (e.g., `gawk''s `--profile' option should remain the same,
+ no matter what the local language).
+
+ 2. The programmer indicates the application's text domain (`"guide"')
+ to the `gettext' library, by calling the `textdomain' function.
+
+ 3. Messages from the application are extracted from the source code
+ and collected into a portable object file (`guide.po'), which
+ lists the strings and their translations. The translations are
+ initially empty. The original (usually English) messages serve as
+ the key for lookup of the translations.
+
+ 4. For each language with a translator, `guide.po' is copied and
+ translations are created and shipped with the application.
+
+ 5. Each language's `.po' file is converted into a binary message
+ object (`.mo') file. A message object file contains the original
+ messages and their translations in a binary format that allows
+ fast lookup of translations at runtime.
+
+ 6. When `guide' is built and installed, the binary translation files
+ are installed in a standard place.
+
+ 7. For testing and development, it is possible to tell `gettext' to
+ use `.mo' files in a different directory than the standard one by
+ using the `bindtextdomain' function.
+
+ 8. At runtime, `guide' looks up each string via a call to `gettext'.
+ The returned string is the translated string if available, or the
+ original string if not.
+
+ 9. If necessary, it is possible to access messages from a different
+ text domain than the one belonging to the application, without
+ having to switch the application's default text domain back and
+ forth.
+
+In C (or C++), the string marking and dynamic translation lookup are
+accomplished by wrapping each string in a call to `gettext':
+
+ printf(gettext("Don't Panic!\n"));
+
+The tools that extract messages from source code pull out all strings
+enclosed in calls to `gettext'.
+
+The GNU `gettext' developers, recognizing that typing `gettext' over
+and over again is both painful and ugly to look at, use the macro `_'
+(an underscore) to make things easier:
+
+ /* In the standard header file: */
+ #define _(str) gettext(str)
+
+ /* In the program text: */
+ printf(_("Don't Panic!\n"));
+
+This reduces the typing overhead to just three extra characters per
+string and is considerably easier to read as well. There are locale
+"categories" for different types of locale-related information. The
+defined locale categories that `gettext' knows about are:
+
+`LC_MESSAGES'
+ Text messages. This is the default category for `gettext'
+ operations, but it is possible to supply a different one
+ explicitly, if necessary. (It is almost never necessary to supply
+ a different category.)
+
+`LC_COLLATE'
+ Text-collation information; i.e., how different characters and/or
+ groups of characters sort in a given language.
+
+`LC_CTYPE'
+ Character-type information (alphabetic, digit, upper- or
+ lowercase, and so on). This information is accessed via the POSIX
+ character classes in regular expressions, such as `/[[:alnum:]]/'
+ (*note Regexp Operators::).
+
+`LC_MONETARY'
+ Monetary information, such as the currency symbol, and whether the
+ symbol goes before or after a number.
+
+`LC_NUMERIC'
+ Numeric information, such as which characters to use for the
+ decimal point and the thousands separator.(2)
+
+`LC_RESPONSE'
+ Response information, such as how "yes" and "no" appear in the
+ local language, and possibly other information as well.
+
+`LC_TIME'
+ Time- and date-related information, such as 12- or 24-hour clock,
+ month printed before or after day in a date, local month
+ abbreviations, and so on.
+
+`LC_ALL'
+ All of the above. (Not too useful in the context of `gettext'.)
+
+---------- Footnotes ----------
+
+(1) For some operating systems, the `gawk' port doesn't support GNU
+`gettext'. This applies most notably to the PC operating systems. As
+such, these features are not available if you are using one of those
+operating systems. Sorry.
+
+(2) Americans use a comma every three decimal places and a period for
+the decimal point, while many Europeans do exactly the opposite:
+`1,234.56' versus `1.234,56'.
+
+\1f
+File: gawk.info, Node: Programmer i18n, Next: Translator i18n, Prev: Explaining gettext, Up: Internationalization
+
+9.3 Internationalizing `awk' Programs
+=====================================
+
+`gawk' provides the following variables and functions for
+internationalization:
+
+`TEXTDOMAIN'
+ This variable indicates the application's text domain. For
+ compatibility with GNU `gettext', the default value is
+ `"messages"'.
+
+`_"your message here"'
+ String constants marked with a leading underscore are candidates
+ for translation at runtime. String constants without a leading
+ underscore are not translated.
+
+`dcgettext(STRING [, DOMAIN [, CATEGORY]])'
+ This built-in function returns the translation of STRING in text
+ domain DOMAIN for locale category CATEGORY. The default value for
+ DOMAIN is the current value of `TEXTDOMAIN'. The default value
+ for CATEGORY is `"LC_MESSAGES"'.
+
+ If you supply a value for CATEGORY, it must be a string equal to
+ one of the known locale categories described in *Note Explaining
+ gettext::. You must also supply a text domain. Use `TEXTDOMAIN'
+ if you want to use the current domain.
+
+ *Caution:* The order of arguments to the `awk' version of the
+ `dcgettext' function is purposely different from the order for the
+ C version. The `awk' version's order was chosen to be simple and
+ to allow for reasonable `awk'-style default arguments.
+
+`dcngettext(STRING1, STRING2, NUMBER [, DOMAIN [, CATEGORY]])'
+ This built-in function returns the plural form used for NUMBER of
+ the translation of STRING1 and STRING2 in text domain DOMAIN for
+ locale category CATEGORY. STRING1 is the English singular variant
+ of a message, and STRING2 the English plural variant of the same
+ message. The default value for DOMAIN is the current value of
+ `TEXTDOMAIN'. The default value for CATEGORY is `"LC_MESSAGES"'.
+
+ The same remarks as for the `dcgettext' function apply.
+
+`bindtextdomain(DIRECTORY [, DOMAIN])'
+ This built-in function allows you to specify the directory in which
+ `gettext' looks for `.mo' files, in case they will not or cannot
+ be placed in the standard locations (e.g., during testing). It
+ returns the directory in which DOMAIN is "bound."
+
+ The default DOMAIN is the value of `TEXTDOMAIN'. If DIRECTORY is
+ the null string (`""'), then `bindtextdomain' returns the current
+ binding for the given DOMAIN.
+
+To use these facilities in your `awk' program, follow the steps
+outlined in *Note Explaining gettext::, like so:
+
+ 1. Set the variable `TEXTDOMAIN' to the text domain of your program.
+ This is best done in a `BEGIN' rule (*note BEGIN/END::), or it can
+ also be done via the `-v' command-line option (*note Options::):
+
+ BEGIN {
+ TEXTDOMAIN = "guide"
+ ...
+ }
+
+ 2. Mark all translatable strings with a leading underscore (`_')
+ character. It _must_ be adjacent to the opening quote of the
+ string. For example:
+
+ print _"hello, world"
+ x = _"you goofed"
+ printf(_"Number of users is %d\n", nusers)
+
+ 3. If you are creating strings dynamically, you can still translate
+ them, using the `dcgettext' built-in function:
+
+ message = nusers " users logged in"
+ message = dcgettext(message, "adminprog")
+ print message
+
+ Here, the call to `dcgettext' supplies a different text domain
+ (`"adminprog"') in which to find the message, but it uses the
+ default `"LC_MESSAGES"' category.
+
+ 4. During development, you might want to put the `.mo' file in a
+ private directory for testing. This is done with the
+ `bindtextdomain' built-in function:
+
+ BEGIN {
+ TEXTDOMAIN = "guide" # our text domain
+ if (Testing) {
+ # where to find our files
+ bindtextdomain("testdir")
+ # joe is in charge of adminprog
+ bindtextdomain("../joe/testdir", "adminprog")
+ }
+ ...
+ }
+
+
+*Note I18N Example::, for an example program showing the steps to create
+and use translations from `awk'.
+
+\1f
+File: gawk.info, Node: Translator i18n, Next: I18N Example, Prev: Programmer i18n, Up: Internationalization
+
+9.4 Translating `awk' Programs
+==============================
+
+Once a program's translatable strings have been marked, they must be
+extracted to create the initial `.po' file. As part of translation, it
+is often helpful to rearrange the order in which arguments to `printf'
+are output.
+
+`gawk''s `--gen-po' command-line option extracts the messages and is
+discussed next. After that, `printf''s ability to rearrange the order
+for `printf' arguments at runtime is covered.
+
+* Menu:
+
+* String Extraction:: Extracting marked strings.
+* Printf Ordering:: Rearranging `printf' arguments.
+* I18N Portability:: `awk'-level portability issues.
+
+\1f
+File: gawk.info, Node: String Extraction, Next: Printf Ordering, Up: Translator i18n
+
+9.4.1 Extracting Marked Strings
+-------------------------------
+
+Once your `awk' program is working, and all the strings have been
+marked and you've set (and perhaps bound) the text domain, it is time
+to produce translations. First, use the `--gen-po' command-line option
+to create the initial `.po' file:
+
+ $ gawk --gen-po -f guide.awk > guide.po
+
+When run with `--gen-po', `gawk' does not execute your program.
+Instead, it parses it as usual and prints all marked strings to
+standard output in the format of a GNU `gettext' Portable Object file.
+Also included in the output are any constant strings that appear as the
+first argument to `dcgettext' or as the first and second argument to
+`dcngettext'.(1) *Note I18N Example::, for the full list of steps to go
+through to create and test translations for `guide'.
+
+---------- Footnotes ----------
+
+(1) Starting with `gettext' version 0.11.5, the `xgettext' utility that
+comes with GNU `gettext' can handle `.awk' files.
+
+\1f
+File: gawk.info, Node: Printf Ordering, Next: I18N Portability, Prev: String Extraction, Up: Translator i18n
+
+9.4.2 Rearranging `printf' Arguments
+------------------------------------
+
+Format strings for `printf' and `sprintf' (*note Printf::) present a
+special problem for translation. Consider the following:(1)
+
+ printf(_"String `%s' has %d characters\n",
+ string, length(string)))
+
+A possible German translation for this might be:
+
+ "%d Zeichen lang ist die Zeichenkette `%s'\n"
+
+The problem should be obvious: the order of the format specifications
+is different from the original! Even though `gettext' can return the
+translated string at runtime, it cannot change the argument order in
+the call to `printf'.
+
+To solve this problem, `printf' format specificiers may have an
+additional optional element, which we call a "positional specifier".
+For example:
+
+ "%2$d Zeichen lang ist die Zeichenkette `%1$s'\n"
+
+Here, the positional specifier consists of an integer count, which
+indicates which argument to use, and a `$'. Counts are one-based, and
+the format string itself is _not_ included. Thus, in the following
+example, `string' is the first argument and `length(string)' is the
+second:
+
+ $ gawk 'BEGIN {
+ > string = "Dont Panic"
+ > printf _"%2$d characters live in \"%1$s\"\n",
+ > string, length(string)
+ > }'
+ -| 10 characters live in "Dont Panic"
+
+If present, positional specifiers come first in the format
+specification, before the flags, the field width, and/or the precision.
+
+Positional specifiers can be used with the dynamic field width and
+precision capability:
+
+ $ gawk 'BEGIN {
+ > printf("%*.*s\n", 10, 20, "hello")
+ > printf("%3$*2$.*1$s\n", 20, 10, "hello")
+ > }'
+ -| hello
+ -| hello
+
+ NOTE: When using `*' with a positional specifier, the `*' comes
+ first, then the integer position, and then the `$'. This is
+ somewhat counterintutive.
+
+`gawk' does not allow you to mix regular format specifiers and those
+with positional specifiers in the same string:
+
+ $ gawk 'BEGIN { printf _"%d %3$s\n", 1, 2, "hi" }'
+ error--> gawk: cmd. line:1: fatal: must use `count$' on all formats or none
+
+ NOTE: There are some pathological cases that `gawk' may fail to
+ diagnose. In such cases, the output may not be what you expect.
+ It's still a bad idea to try mixing them, even if `gawk' doesn't
+ detect it.
+
+Although positional specifiers can be used directly in `awk' programs,
+their primary purpose is to help in producing correct translations of
+format strings into languages different from the one in which the
+program is first written.
+
+---------- Footnotes ----------
+
+(1) This example is borrowed from the GNU `gettext' manual.
+
+\1f
+File: gawk.info, Node: I18N Portability, Prev: Printf Ordering, Up: Translator i18n
+
+9.4.3 `awk' Portability Issues
+------------------------------
+
+`gawk''s internationalization features were purposely chosen to have as
+little impact as possible on the portability of `awk' programs that use
+them to other versions of `awk'. Consider this program:
+
+ BEGIN {
+ TEXTDOMAIN = "guide"
+ if (Test_Guide) # set with -v
+ bindtextdomain("/test/guide/messages")
+ print _"don't panic!"
+ }
+
+As written, it won't work on other versions of `awk'. However, it is
+actually almost portable, requiring very little change:
+
+ * Assignments to `TEXTDOMAIN' won't have any effect, since
+ `TEXTDOMAIN' is not special in other `awk' implementations.
+
+ * Non-GNU versions of `awk' treat marked strings as the
+ concatenation of a variable named `_' with the string following
+ it.(1) Typically, the variable `_' has the null string (`""') as
+ its value, leaving the original string constant as the result.
+
+ * By defining "dummy" functions to replace `dcgettext', `dcngettext'
+ and `bindtextdomain', the `awk' program can be made to run, but
+ all the messages are output in the original language. For example:
+
+ 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)
+ }
+
+ * The use of positional specifications in `printf' or `sprintf' is
+ _not_ portable. To support `gettext' at the C level, many
+ systems' C versions of `sprintf' do support positional specifiers.
+ But it works only if enough arguments are supplied in the
+ function call. Many versions of `awk' pass `printf' formats and
+ arguments unchanged to the underlying C library version of
+ `sprintf', but only one format and argument at a time. What
+ happens if a positional specification is used is anybody's guess.
+ However, since the positional specifications are primarily for use
+ in _translated_ format strings, and since non-GNU `awk's never
+ retrieve the translated string, this should not be a problem in
+ practice.
+
+---------- Footnotes ----------
+
+(1) This is good fodder for an "Obfuscated `awk'" contest.
+
+\1f
+File: gawk.info, Node: I18N Example, Next: Gawk I18N, Prev: Translator i18n, Up: Internationalization
+
+9.5 A Simple Internationalization Example
+=========================================
+
+Now let's look at a step-by-step example of how to internationalize and
+localize a simple `awk' program, using `guide.awk' as our original
+source:
+
+ BEGIN {
+ TEXTDOMAIN = "guide"
+ bindtextdomain(".") # for testing
+ print _"Don't Panic"
+ print _"The Answer Is", 42
+ print "Pardon me, Zaphod who?"
+ }
+
+Run `gawk --gen-po' to create the `.po' file:
+
+ $ gawk --gen-po -f guide.awk > guide.po
+
+This produces:
+
+ #: guide.awk:4
+ msgid "Don't Panic"
+ msgstr ""
+
+ #: guide.awk:5
+ msgid "The Answer Is"
+ msgstr ""
+
+This original portable object file is saved and reused for each language
+into which the application is translated. The `msgid' is the original
+string and the `msgstr' is the translation.
+
+ NOTE: Strings not marked with a leading underscore do not appear
+ in the `guide.po' file.
+
+Next, the messages must be translated. Here is a translation to a
+hypothetical dialect of English, called "Mellow":(1)
+
+ $ cp guide.po guide-mellow.po
+ ADD TRANSLATIONS TO guide-mellow.po ...
+
+Following are the translations:
+
+ #: guide.awk:4
+ msgid "Don't Panic"
+ msgstr "Hey man, relax!"
+
+ #: guide.awk:5
+ msgid "The Answer Is"
+ msgstr "Like, the scoop is"
+
+The next step is to make the directory to hold the binary message object
+file and then to create the `guide.mo' file. The directory layout
+shown here is standard for GNU `gettext' on GNU/Linux systems. Other
+versions of `gettext' may use a different layout:
+
+ $ mkdir en_US en_US/LC_MESSAGES
+
+The `msgfmt' utility does the conversion from human-readable `.po' file
+to machine-readable `.mo' file. By default, `msgfmt' creates a file
+named `messages'. This file must be renamed and placed in the proper
+directory so that `gawk' can find it:
+
+ $ msgfmt guide-mellow.po
+ $ mv messages en_US/LC_MESSAGES/guide.mo
+
+Finally, we run the program to test it:
+
+ $ gawk -f guide.awk
+ -| Hey man, relax!
+ -| Like, the scoop is 42
+ -| Pardon me, Zaphod who?
+
+If the three replacement functions for `dcgettext', `dcngettext' and
+`bindtextdomain' (*note I18N Portability::) are in a file named
+`libintl.awk', then we can run `guide.awk' unchanged as follows:
+
+ $ gawk --posix -f guide.awk -f libintl.awk
+ -| Don't Panic
+ -| The Answer Is 42
+ -| Pardon me, Zaphod who?
+
+---------- Footnotes ----------
+
+(1) Perhaps it would be better if it were called "Hippy." Ah, well.
+
+\1f
+File: gawk.info, Node: Gawk I18N, Prev: I18N Example, Up: Internationalization
+
+9.6 `gawk' Can Speak Your Language
+==================================
+
+As of version 3.1, `gawk' itself has been internationalized using the
+GNU `gettext' package. (GNU `gettext' is described in complete detail
+in *Note Top::.) As of this writing, the latest version of GNU
+`gettext' is version 0.11.5
+(ftp://ftp.gnu.org/gnu/gettext/gettext-0.11.5.tar.gz).
+
+If a translation of `gawk''s messages exists, then `gawk' produces
+usage messages, warnings, and fatal errors in the local language.
+
+\1f
+File: gawk.info, Node: Advanced Features, Next: Invoking Gawk, Prev: Internationalization, Up: Top
+
+10 Advanced Features of `gawk'
+******************************
+
+ Write documentation as if whoever reads it is a violent psychopath
+ who knows where you live.
+ Steve English, as quoted by Peter Langston
+
+This major node discusses advanced features in `gawk'. It's a bit of a
+"grab bag" of items that are otherwise unrelated to each other. First,
+a command-line option allows `gawk' to recognize nondecimal numbers in
+input data, not just in `awk' programs. Next, two-way I/O, discussed
+briefly in earlier parts of this Info file, is described in full
+detail, along with the basics of TCP/IP networking and BSD portal
+files. Finally, `gawk' can "profile" an `awk' program, making it
+possible to tune it for performance.
+
+*Note Dynamic Extensions::, discusses the ability to dynamically add
+new built-in functions to `gawk'. As this feature is still immature
+and likely to change, its description is relegated to an appendix.
+
+* Menu:
+
+* Nondecimal Data:: Allowing nondecimal input data.
+* Two-way I/O:: Two-way communications with another process.
+* TCP/IP Networking:: Using `gawk' for network programming.
+* Portal Files:: Using `gawk' with BSD portals.
+* Profiling:: Profiling your `awk' programs.
+
+\1f
+File: gawk.info, Node: Nondecimal Data, Next: Two-way I/O, Up: Advanced Features
+
+10.1 Allowing Nondecimal Input Data
+===================================
+
+If you run `gawk' with the `--non-decimal-data' option, you can have
+nondecimal constants in your input data:
+
+ $ echo 0123 123 0x123 |
+ > gawk --non-decimal-data '{ printf "%d, %d, %d\n",
+ > $1, $2, $3 }'
+ -| 83, 123, 291
+
+For this feature to work, write your program so that `gawk' treats your
+data as numeric:
+
+ $ echo 0123 123 0x123 | gawk '{ print $1, $2, $3 }'
+ -| 0123 123 0x123
+
+The `print' statement treats its expressions as strings. Although the
+fields can act as numbers when necessary, they are still strings, so
+`print' does not try to treat them numerically. You may need to add
+zero to a field to force it to be treated as a number. For example:
+
+ $ echo 0123 123 0x123 | gawk --non-decimal-data '
+ > { print $1, $2, $3
+ > print $1 + 0, $2 + 0, $3 + 0 }'
+ -| 0123 123 0x123
+ -| 83 123 291
+
+Because it is common to have decimal data with leading zeros, and
+because using it could lead to surprising results, the default is to
+leave this facility disabled. If you want it, you must explicitly
+request it.
+
+*Caution:* _Use of this option is not recommended._ It can break old
+programs very badly. Instead, use the `strtonum' function to convert
+your data (*note Nondecimal-numbers::). This makes your programs
+easier to write and easier to read, and leads to less surprising
+results.
+
+\1f
+File: gawk.info, Node: Two-way I/O, Next: TCP/IP Networking, Prev: Nondecimal Data, Up: Advanced Features
+
+10.2 Two-Way Communications with Another Process
+================================================
+
+ 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
+ Message-ID: <5s53rm$eca@news.whidbey.com>
+
+ 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
+
+It is often useful to be able to send data to a separate program for
+processing and then read the result. This can always be done with
+temporary files:
+
+ # write the data for processing
+ tempfile = ("mydata." PROCINFO["pid"])
+ while (NOT DONE WITH DATA)
+ print DATA | ("subprogram > " tempfile)
+ close("subprogram > " tempfile)
+
+ # read the results, remove tempfile when done
+ while ((getline newdata < tempfile) > 0)
+ PROCESS newdata APPROPRIATELY
+ close(tempfile)
+ system("rm " tempfile)
+
+This works, but not elegantly. Among other things, it requires that
+the program be run in a directory that cannot be shared among users;
+for example, `/tmp' will not do, as another user might happen to be
+using a temporary file with the same name.
+
+Starting with version 3.1 of `gawk', it is possible to open a _two-way_
+pipe to another process. The second process is termed a "coprocess",
+since it runs in parallel with `gawk'. The two-way connection is
+created using the new `|&' operator (borrowed from the Korn shell,
+`ksh'):(1)
+
+ do {
+ print DATA |& "subprogram"
+ "subprogram" |& getline results
+ } while (DATA LEFT TO PROCESS)
+ close("subprogram")
+
+The first time an I/O operation is executed using the `|&' operator,
+`gawk' creates a two-way pipeline to a child process that runs the
+other program. Output created with `print' or `printf' is written to
+the program's standard input, and output from the program's standard
+output can be read by the `gawk' program using `getline'. As is the
+case with processes started by `|', the subprogram can be any program,
+or pipeline of programs, that can be started by the shell.
+
+There are some cautionary items to be aware of:
+
+ * As the code inside `gawk' currently stands, the coprocess's
+ standard error goes to the same place that the parent `gawk''s
+ standard error goes. It is not possible to read the child's
+ standard error separately.
+
+ * I/O buffering may be a problem. `gawk' automatically flushes all
+ output down the pipe to the child process. However, if the
+ coprocess does not flush its output, `gawk' may hang when doing a
+ `getline' in order to read the coprocess's results. This could
+ lead to a situation known as "deadlock", where each process is
+ waiting for the other one to do something.
+
+It is possible to close just one end of the two-way pipe to a
+coprocess, by supplying a second argument to the `close' function of
+either `"to"' or `"from"' (*note Close Files And Pipes::). These
+strings tell `gawk' to close the end of the pipe that sends data to the
+process or the end that reads from it, respectively.
+
+This is particularly necessary in order to use the system `sort'
+utility as part of a coprocess; `sort' must read _all_ of its input
+data before it can produce any output. The `sort' program does not
+receive an end-of-file indication until `gawk' closes the write end of
+the pipe.
+
+When you have finished writing data to the `sort' utility, you can
+close the `"to"' end of the pipe, and then start reading sorted data
+via `getline'. For example:
+
+ BEGIN {
+ command = "LC_ALL=C sort"
+ n = split("abcdefghijklmnopqrstuvwxyz", a, "")
+
+ for (i = n; i > 0; i--)
+ print a[i] |& command
+ close(command, "to")
+
+ while ((command |& getline line) > 0)
+ print "got", line
+ close(command)
+ }
+
+This program writes the letters of the alphabet in reverse order, one
+per line, down the two-way pipe to `sort'. It then closes the write
+end of the pipe, so that `sort' receives an end-of-file indication.
+This causes `sort' to sort the data and write the sorted data back to
+the `gawk' program. Once all of the data has been read, `gawk'
+terminates the coprocess and exits.
+
+As a side note, the assignment `LC_ALL=C' in the `sort' command ensures
+traditional Unix (ASCII) sorting from `sort'.
+
+Beginning with `gawk' 3.1.2, you may use Pseudo-ttys (ptys) for two-way
+communication instead of pipes, if your system supports them. This is
+done on a per-command basis, by setting a special element in the
+`PROCINFO' array (*note Auto-set::), like so:
+
+ command = "sort -nr" # command, saved in variable for convenience
+ PROCINFO[command, "pty"] = 1 # update PROCINFO
+ print ... |& command # start two-way pipe
+ ...
+
+Using ptys avoids the buffer deadlock issues described earlier, at some
+loss in performance. If your system does not have ptys, or if all the
+system's ptys are in use, `gawk' automatically falls back to using
+regular pipes.
+
+---------- Footnotes ----------
+
+(1) This is very different from the same operator in the C shell, `csh'.
+
+\1f
+File: gawk.info, Node: TCP/IP Networking, Next: Portal Files, Prev: Two-way I/O, Up: Advanced Features
+
+10.3 Using `gawk' for Network Programming
+=========================================
+
+ `EMISTERED': A host is a host from coast to coast,
+ and no-one can talk to host that's close,
+ unless the host that isn't close
+ is busy hung or dead.
+
+In addition to being able to open a two-way pipeline to a coprocess on
+the same system (*note Two-way I/O::), it is possible to make a two-way
+connection to another process on another system across an IP networking
+connection.
+
+You can think of this as just a _very long_ two-way pipeline to a
+coprocess. The way `gawk' decides that you want to use TCP/IP
+networking is by recognizing special file names that begin with
+`/inet/'.
+
+The full syntax of the special file name is
+`/inet/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT'. The components
+are:
+
+PROTOCOL
+ The protocol to use over IP. This must be either `tcp', `udp', or
+ `raw', for a TCP, UDP, or raw IP connection, respectively. The
+ use of TCP is recommended for most applications.
+
+ *Caution:* The use of raw sockets is not currently supported in
+ version 3.1 of `gawk'.
+
+LOCAL-PORT
+ The local TCP or UDP port number to use. Use a port number of `0'
+ when you want the system to pick a port. This is what you should do
+ when writing a TCP or UDP client. You may also use a well-known
+ service name, such as `smtp' or `http', in which case `gawk'
+ attempts to determine the predefined port number using the C
+ `getservbyname' function.
+
+REMOTE-HOST
+ The IP address or fully-qualified domain name of the Internet host
+ to which you want to connect.
+
+REMOTE-PORT
+ The TCP or UDP port number to use on the given REMOTE-HOST.
+ Again, use `0' if you don't care, or else a well-known service
+ name.
+
+Consider the following very simple example:
+
+ BEGIN {
+ Service = "/inet/tcp/0/localhost/daytime"
+ Service |& getline
+ print $0
+ close(Service)
+ }
+
+This program reads the current date and time from the local system's
+TCP `daytime' server. It then prints the results and closes the
+connection.
+
+Because this topic is extensive, the use of `gawk' for TCP/IP
+programming is documented separately. *Note Top::, for a much more
+complete introduction and discussion, as well as extensive examples.
+
+\1f
+File: gawk.info, Node: Portal Files, Next: Profiling, Prev: TCP/IP Networking, Up: Advanced Features
+
+10.4 Using `gawk' with BSD Portals
+==================================
+
+Similar to the `/inet' special files, if `gawk' is configured with the
+`--enable-portals' option (*note Quick Installation::), then `gawk'
+treats files whose pathnames begin with `/p' as 4.4 BSD-style portals.
+
+When used with the `|&' operator, `gawk' opens the file for two-way
+communications. The operating system's portal mechanism then manages
+creating the process associated with the portal and the corresponding
+communications with the portal's process.
+
+\1f
+File: gawk.info, Node: Profiling, Prev: Portal Files, Up: Advanced Features
+
+10.5 Profiling Your `awk' Programs
+==================================
+
+Beginning with version 3.1 of `gawk', you may produce execution traces
+of your `awk' programs. This is done with a specially compiled version
+of `gawk', called `pgawk' ("profiling `gawk'").
+
+`pgawk' is identical in every way to `gawk', except that when it has
+finished running, it creates a profile of your program in a file named
+`awkprof.out'. Because it is profiling, it also executes up to 45%
+slower than `gawk' normally does.
+
+As shown in the following example, the `--profile' option can be used
+to change the name of the file where `pgawk' will write the profile:
+
+ $ pgawk --profile=myprog.prof -f myprog.awk data1 data2
+
+In the above example, `pgawk' places the profile in `myprog.prof'
+instead of in `awkprof.out'.
+
+Regular `gawk' also accepts this option. When called with just
+`--profile', `gawk' "pretty prints" the program into `awkprof.out',
+without any execution counts. You may supply an option to `--profile'
+to change the file name. Here is a sample session showing a simple
+`awk' program, its input data, and the results from running `pgawk'.
+First, the `awk' program:
+
+ BEGIN { print "First BEGIN rule" }
+
+ END { print "First END rule" }
+
+ /foo/ {
+ print "matched /foo/, gosh"
+ for (i = 1; i <= 3; i++)
+ sing()
+ }
+
+ {
+ if (/foo/)
+ print "if is true"
+ else
+ print "else is true"
+ }
+
+ BEGIN { print "Second BEGIN rule" }
+
+ END { print "Second END rule" }
+
+ function sing( dummy)
+ {
+ print "I gotta be me!"
+ }
+
+Following is the input data:
+
+ foo
+ bar
+ baz
+ foo
+ junk
+
+Here is the `awkprof.out' that results from running `pgawk' on this
+program and data (this example also illustrates that `awk' programmers
+sometimes have to work late):
+
+ # gawk profile, created Sun Aug 13 00:00:15 2000
+
+ # BEGIN block(s)
+
+ BEGIN {
+ 1 print "First BEGIN rule"
+ 1 print "Second BEGIN rule"
+ }
+
+ # Rule(s)
+
+ 5 /foo/ { # 2
+ 2 print "matched /foo/, gosh"
+ 6 for (i = 1; i <= 3; i++) {
+ 6 sing()
+ }
+ }
+
+ 5 {
+ 5 if (/foo/) { # 2
+ 2 print "if is true"
+ 3 } else {
+ 3 print "else is true"
+ }
+ }
+
+ # END block(s)
+
+ END {
+ 1 print "First END rule"
+ 1 print "Second END rule"
+ }
+
+ # Functions, listed alphabetically
+
+ 6 function sing(dummy)
+ {
+ 6 print "I gotta be me!"
+ }
+
+This example illustrates many of the basic rules for profiling output.
+The rules are as follows:
+
+ * The program is printed in the order `BEGIN' rule, pattern/action
+ rules, `END' rule and functions, listed alphabetically. Multiple
+ `BEGIN' and `END' rules are merged together.
+
+ * Pattern-action rules have two counts. The first count, to the
+ left of the rule, shows how many times the rule's pattern was
+ _tested_. The second count, to the right of the rule's opening
+ left brace in a comment, shows how many times the rule's action
+ was _executed_. The difference between the two indicates how many
+ times the rule's pattern evaluated to false.
+
+ * Similarly, the count for an `if'-`else' statement shows how many
+ times the condition was tested. To the right of the opening left
+ brace for the `if''s body is a count showing how many times the
+ condition was true. The count for the `else' indicates how many
+ times the test failed.
+
+ * The count for a loop header (such as `for' or `while') shows how
+ many times the loop test was executed. (Because of this, you
+ can't just look at the count on the first statement in a rule to
+ determine how many times the rule was executed. If the first
+ statement is a loop, the count is misleading.)
+
+ * For user-defined functions, the count next to the `function'
+ keyword indicates how many times the function was called. The
+ counts next to the statements in the body show how many times
+ those statements were executed.
+
+ * The layout uses "K&R" style with tabs. Braces are used
+ everywhere, even when the body of an `if', `else', or loop is only
+ a single statement.
+
+ * Parentheses are used only where needed, as indicated by the
+ structure of the program and the precedence rules. For example,
+ `(3 + 5) * 4' means add three plus five, then multiply the total
+ by four. However, `3 + 5 * 4' has no parentheses, and means `3 +
+ (5 * 4)'.
+
+ * All string concatenations are parenthesized too. (This could be
+ made a bit smarter.)
+
+ * Parentheses are used around the arguments to `print' and `printf'
+ only when the `print' or `printf' statement is followed by a
+ redirection. Similarly, if the target of a redirection isn't a
+ scalar, it gets parenthesized.
+
+ * `pgawk' supplies leading comments in front of the `BEGIN' and
+ `END' rules, the pattern/action rules, and the functions.
+
+
+The profiled version of your program may not look exactly like what you
+typed when you wrote it. This is because `pgawk' creates the profiled
+version by "pretty printing" its internal representation of the
+program. The advantage to this is that `pgawk' can produce a standard
+representation. The disadvantage is that all source-code comments are
+lost, as are the distinctions among multiple `BEGIN' and `END' rules.
+Also, things such as:
+
+ /foo/
+
+come out as:
+
+ /foo/ {
+ print $0
+ }
+
+which is correct, but possibly surprising.
+
+Besides creating profiles when a program has completed, `pgawk' can
+produce a profile while it is running. This is useful if your `awk'
+program goes into an infinite loop and you want to see what has been
+executed. To use this feature, run `pgawk' in the background:
+
+ $ pgawk -f myprog &
+ [1] 13992
+
+The shell prints a job number and process ID number; in this case,
+13992. Use the `kill' command to send the `USR1' signal to `pgawk':
+
+ $ kill -USR1 13992
+
+As usual, the profiled version of the program is written to
+`awkprof.out', or to a different file if you use the `--profile' option.
+
+Along with the regular profile, as shown earlier, the profile includes
+a trace of any active functions:
+
+ # Function Call Stack:
+
+ # 3. baz
+ # 2. bar
+ # 1. foo
+ # -- main --
+
+You may send `pgawk' the `USR1' signal as many times as you like. Each
+time, the profile and function call trace are appended to the output
+profile file.
+
+If you use the `HUP' signal instead of the `USR1' signal, `pgawk'
+produces the profile and the function call trace and then exits.
+
+When `pgawk' runs on MS-DOS or MS-Windows, it uses the `INT' and `QUIT'
+signals for producing the profile and, in the case of the `INT' signal,
+`pgawk' exits. This is because these systems don't support the `kill'
+command, so the only signals you can deliver to a program are those
+generated by the keyboard. The `INT' signal is generated by the
+`Ctrl-<C>' or `Ctrl-<BREAK>' key, while the `QUIT' signal is generated
+by the `Ctrl-<\>' key.
+
+\1f
+File: gawk.info, Node: Invoking Gawk, Next: Library Functions, Prev: Advanced Features, Up: Top
+
+11 Running `awk' and `gawk'
+***************************
+
+This major node covers how to run awk, both POSIX-standard and
+`gawk'-specific command-line options, and what `awk' and `gawk' do with
+non-option arguments. It then proceeds to cover how `gawk' searches
+for source files, obsolete options and/or features, and known bugs in
+`gawk'. This major node rounds out the discussion of `awk' as a
+program and as a language.
+
+While a number of the options and features described here were
+discussed in passing earlier in the book, this major node provides the
+full details.
+
+* Menu:
+
+* Command Line:: How to run `awk'.
+* Options:: Command-line options and their meanings.
+* Other Arguments:: Input file names and variable assignments.
+* AWKPATH Variable:: Searching directories for `awk'
+ programs.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Known Bugs:: Known Bugs in `gawk'.
+
+\1f
+File: gawk.info, Node: Command Line, Next: Options, Up: Invoking Gawk
+
+11.1 Invoking `awk'
+===================
+
+There are two ways to run `awk'--with an explicit program or with one
+or more program files. Here are templates for both of them; items
+enclosed in [...] in these templates are optional:
+
+ awk [OPTIONS] -f progfile [`--'] FILE ...
+ awk [OPTIONS] [`--'] 'PROGRAM' FILE ...
+
+Besides traditional one-letter POSIX-style options, `gawk' also
+supports GNU long options.
+
+It is possible to invoke `awk' with an empty program:
+
+ awk '' datafile1 datafile2
+
+Doing so makes little sense, though; `awk' exits silently when given an
+empty program. (d.c.) If `--lint' has been specified on the command
+line, `gawk' issues a warning that the program is empty.
+
+\1f
+File: gawk.info, Node: Options, Next: Other Arguments, Prev: Command Line, Up: Invoking Gawk
+
+11.2 Command-Line Options
+=========================
+
+Options begin with a dash and consist of a single character. GNU-style
+long options consist of two dashes and a keyword. The keyword can be
+abbreviated, as long as the abbreviation allows the option to be
+uniquely identified. If the option takes an argument, then the keyword
+is either immediately followed by an equals sign (`=') and the
+argument's value, or the keyword and the argument's value are separated
+by whitespace. If a particular option with a value is given more than
+once, it is the last value that counts.
+
+Each long option for `gawk' has a corresponding POSIX-style option.
+The long and short options are interchangeable in all contexts. The
+options and their meanings are as follows:
+
+`-F FS'
+`--field-separator FS'
+ Sets the `FS' variable to FS (*note Field Separators::).
+
+`-f SOURCE-FILE'
+`--file SOURCE-FILE'
+ Indicates that the `awk' program is to be found in SOURCE-FILE
+ instead of in the first non-option argument.
+
+`-v VAR=VAL'
+`--assign VAR=VAL'
+ Sets the variable VAR to the value VAL _before_ execution of the
+ program begins. Such variable values are available inside the
+ `BEGIN' rule (*note Other Arguments::).
+
+ The `-v' option can only set one variable, but it can be used more
+ than once, setting another variable each time, like this: `awk
+ -v foo=1 -v bar=2 ...'.
+
+ *Caution:* Using `-v' to set the values of the built-in variables
+ may lead to surprising results. `awk' will reset the values of
+ those variables as it needs to, possibly ignoring any predefined
+ value you may have given.
+
+`-mf N'
+`-mr N'
+ Sets various memory limits to the value N. The `f' flag sets the
+ maximum number of fields and the `r' flag sets the maximum record
+ size. These two flags and the `-m' option are from the Bell
+ Laboratories research version of Unix `awk'. They are provided
+ for compatibility but otherwise ignored by `gawk', since `gawk'
+ has no predefined limits. (The Bell Laboratories `awk' no longer
+ needs these options; it continues to accept them to avoid breaking
+ old programs.)
+
+`-W GAWK-OPT'
+ Following the POSIX standard, implementation-specific options are
+ supplied as arguments to the `-W' option. These options also have
+ corresponding GNU-style long options. Note that the long options
+ may be abbreviated, as long as the abbreviations remain unique.
+ The full list of `gawk'-specific options is provided next.
+
+`--'
+ Signals the end of the command-line options. The following
+ arguments are not treated as options even if they begin with `-'.
+ This interpretation of `--' follows the POSIX argument parsing
+ conventions.
+
+ This is useful if you have file names that start with `-', or in
+ shell scripts, if you have file names that will be specified by
+ the user that could start with `-'.
+
+The previous list described options mandated by the POSIX standard, as
+well as options available in the Bell Laboratories version of `awk'.
+The following list describes `gawk'-specific options:
+
+`-W compat'
+`-W traditional'
+`--compat'
+`--traditional'
+ Specifies "compatibility mode", in which the GNU extensions to the
+ `awk' language are disabled, so that `gawk' behaves just like the
+ Bell Laboratories research version of Unix `awk'. `--traditional'
+ is the preferred form of this option. *Note POSIX/GNU::, which
+ summarizes the extensions. Also see *Note Compatibility Mode::.
+
+`-W copyright'
+`--copyright'
+ Print the short version of the General Public License and then
+ exit.
+
+`-W copyleft'
+`--copyleft'
+ Just like `--copyright'. This option may disappear in a future
+ version of `gawk'.
+
+`-W dump-variables[=FILE]'
+`--dump-variables[=FILE]'
+ Prints a sorted list of global variables, their types, and final
+ values to FILE. If no FILE is provided, `gawk' prints this list
+ to the file named `awkvars.out' in the current directory.
+
+ Having a list of all global variables is a good way to look for
+ typographical errors in your programs. You would also use this
+ option if you have a large program with a lot of functions, and
+ you want to be sure that your functions don't inadvertently use
+ global variables that you meant to be local. (This is a
+ particularly easy mistake to make with simple variable names like
+ `i', `j', etc.)
+
+`-W exec FILE'
+`--exec FILE'
+ Similar to `-f', reads `awk' program text from FILE. There are
+ two differences. The fist is that this option also terminates
+ option processing; anything else on the command line is passed on
+ directly to the `awk' program. The second is that command line
+ variable assignments of the form `VAR=VALUE' are disallowed.
+
+ This option is particularly necessary for World Wide Web CGI
+ applications that pass arguments through the URL; using this
+ option prevents a malicious (or other) user from passing in
+ options, assignments, or `awk' source code (via `--source') to the
+ CGI application. This option should be used with `#!' scripts
+ (*note Executable Scripts::), like so:
+
+ #! /usr/local/bin/gawk --exec
+
+ AWK PROGRAM HERE ...
+
+`-W gen-po'
+`--gen-po'
+ Analyzes the source program and generates a GNU `gettext' Portable
+ Object file on standard output for all string constants that have
+ been marked for translation. *Note Internationalization::, for
+ information about this option.
+
+`-W help'
+`-W usage'
+`--help'
+`--usage'
+ Prints a "usage" message summarizing the short and long style
+ options that `gawk' accepts and then exit.
+
+`-W lint[=fatal]'
+`--lint[=fatal]'
+ Warns about constructs that are dubious or nonportable to other
+ `awk' implementations. Some warnings are issued when `gawk' first
+ reads your program. Others are issued at runtime, as your program
+ executes. With an optional argument of `fatal', lint warnings
+ become fatal errors. This may be drastic, but its use will
+ certainly encourage the development of cleaner `awk' programs.
+ With an optional argument of `invalid', only warnings about things
+ that are actually invalid are issued. (This is not fully
+ implemented yet.)
+
+`-W lint-old'
+`--lint-old'
+ Warns about constructs that are not available in the original
+ version of `awk' from Version 7 Unix (*note V7/SVR3.1::).
+
+`-W non-decimal-data'
+`--non-decimal-data'
+ Enable automatic interpretation of octal and hexadecimal values in
+ input data (*note Nondecimal Data::).
+
+ *Caution:* This option can severely break old programs. Use with
+ care.
+
+`-W posix'
+`--posix'
+ Operates in strict POSIX mode. This disables all `gawk'
+ extensions (just like `--traditional') and adds the following
+ additional restrictions:
+
+ * `\x' escape sequences are not recognized (*note Escape
+ Sequences::).
+
+ * Newlines do not act as whitespace to separate fields when
+ `FS' is equal to a single space (*note Fields::).
+
+ * Newlines are not allowed after `?' or `:' (*note Conditional
+ Exp::).
+
+ * The synonym `func' for the keyword `function' is not
+ recognized (*note Definition Syntax::).
+
+ * The `**' and `**=' operators cannot be used in place of `^'
+ and `^=' (*note Arithmetic Ops::, and also *note Assignment
+ Ops::).
+
+ * Specifying `-Ft' on the command-line does not set the value
+ of `FS' to be a single TAB character (*note Field
+ Separators::).
+
+ * The `fflush' built-in function is not supported (*note I/O
+ Functions::).
+
+ If you supply both `--traditional' and `--posix' on the command
+ line, `--posix' takes precedence. `gawk' also issues a warning if
+ both options are supplied.
+
+`-W profile[=FILE]'
+`--profile[=FILE]'
+ Enable profiling of `awk' programs (*note Profiling::). By
+ default, profiles are created in a file named `awkprof.out'. The
+ optional FILE argument allows you to specify a different file name
+ for the profile file.
+
+ When run with `gawk', the profile is just a "pretty printed"
+ version of the program. When run with `pgawk', the profile
+ contains execution counts for each statement in the program in the
+ left margin, and function call counts for each function.
+
+`-W re-interval'
+`--re-interval'
+ Allows interval expressions (*note Regexp Operators::) in regexps.
+ Because interval expressions were traditionally not available in
+ `awk', `gawk' does not provide them by default. This prevents old
+ `awk' programs from breaking.
+
+`-W source PROGRAM-TEXT'
+`--source PROGRAM-TEXT'
+ Allows you to mix source code in files with source code that you
+ enter on the command line. Program source code is taken from the
+ PROGRAM-TEXT. This is particularly useful when you have library
+ functions that you want to use from your command-line programs
+ (*note AWKPATH Variable::).
+
+`-W version'
+`--version'
+ Prints version information for this particular copy of `gawk'.
+ This allows you to determine if your copy of `gawk' is up to date
+ with respect to whatever the Free Software Foundation is currently
+ distributing. It is also useful for bug reports (*note Bugs::).
+
+As long as program text has been supplied, any other options are
+flagged as invalid with a warning message but are otherwise ignored.
+
+In compatibility mode, as a special case, if the value of FS supplied
+to the `-F' option is `t', then `FS' is set to the TAB character
+(`"\t"'). This is true only for `--traditional' and not for `--posix'
+(*note Field Separators::).
+
+The `-f' option may be used more than once on the command line. If it
+is, `awk' reads its program source from all of the named files, as if
+they had been concatenated together into one big file. This is useful
+for creating libraries of `awk' functions. These functions can be
+written once and then retrieved from a standard place, instead of
+having to be included into each individual program. (As mentioned in
+*Note Definition Syntax::, function names must be unique.)
+
+Library functions can still be used, even if the program is entered at
+the terminal, by specifying `-f /dev/tty'. After typing your program,
+type `Ctrl-d' (the end-of-file character) to terminate it. (You may
+also use `-f -' to read program source from the standard input but then
+you will not be able to also use the standard input as a source of
+data.)
+
+Because it is clumsy using the standard `awk' mechanisms to mix source
+file and command-line `awk' programs, `gawk' provides the `--source'
+option. This does not require you to pre-empt the standard input for
+your source code; it allows you to easily mix command-line and library
+source code (*note AWKPATH Variable::).
+
+If no `-f' or `--source' option is specified, then `gawk' uses the
+first non-option command-line argument as the text of the program
+source code.
+
+If the environment variable `POSIXLY_CORRECT' exists, then `gawk'
+behaves in strict POSIX mode, exactly as if you had supplied the
+`--posix' command-line option. Many GNU programs look for this
+environment variable to turn on strict POSIX mode. If `--lint' is
+supplied on the command line and `gawk' turns on POSIX mode because of
+`POSIXLY_CORRECT', then it issues a warning message indicating that
+POSIX mode is in effect. You would typically set this variable in your
+shell's startup file. For a Bourne-compatible shell (such as `bash'),
+you would add these lines to the `.profile' file in your home directory:
+
+ POSIXLY_CORRECT=true
+ export POSIXLY_CORRECT
+
+For a `csh'-compatible shell,(1) you would add this line to the
+`.login' file in your home directory:
+
+ setenv POSIXLY_CORRECT true
+
+Having `POSIXLY_CORRECT' set is not recommended for daily use, but it
+is good for testing the portability of your programs to other
+environments.
+
+---------- Footnotes ----------
+
+(1) Not recommended.
+
+\1f
+File: gawk.info, Node: Other Arguments, Next: AWKPATH Variable, Prev: Options, Up: Invoking Gawk
+
+11.3 Other Command-Line Arguments
+=================================
+
+Any additional arguments on the command line are normally treated as
+input files to be processed in the order specified. However, an
+argument that has the form `VAR=VALUE', assigns the value VALUE to the
+variable VAR--it does not specify a file at all. (This was discussed
+earlier in *Note Assignment Options::.)
+
+All these arguments are made available to your `awk' program in the
+`ARGV' array (*note Built-in Variables::). Command-line options and
+the program text (if present) are omitted from `ARGV'. All other
+arguments, including variable assignments, are included. As each
+element of `ARGV' is processed, `gawk' sets the variable `ARGIND' to
+the index in `ARGV' of the current element.
+
+The distinction between file name arguments and variable-assignment
+arguments is made when `awk' is about to open the next input file. At
+that point in execution, it checks the file name to see whether it is
+really a variable assignment; if so, `awk' sets the variable instead of
+reading a file.
+
+Therefore, the variables actually receive the given values after all
+previously specified files have been read. In particular, the values of
+variables assigned in this fashion are _not_ available inside a `BEGIN'
+rule (*note BEGIN/END::), because such rules are run before `awk'
+begins scanning the argument list.
+
+The variable values given on the command line are processed for escape
+sequences (*note Escape Sequences::). (d.c.)
+
+In some earlier implementations of `awk', when a variable assignment
+occurred before any file names, the assignment would happen _before_
+the `BEGIN' rule was executed. `awk''s behavior was thus inconsistent;
+some command-line assignments were available inside the `BEGIN' rule,
+while others were not. Unfortunately, some applications came to depend
+upon this "feature." When `awk' was changed to be more consistent, the
+`-v' option was added to accommodate applications that depended upon
+the old behavior.
+
+The variable assignment feature is most useful for assigning to
+variables such as `RS', `OFS', and `ORS', which control input and
+output formats before scanning the data files. It is also useful for
+controlling state if multiple passes are needed over a data file. For
+example:
+
+ awk 'pass == 1 { PASS 1 STUFF }
+ pass == 2 { PASS 2 STUFF }' pass=1 mydata pass=2 mydata
+
+Given the variable assignment feature, the `-F' option for setting the
+value of `FS' is not strictly necessary. It remains for historical
+compatibility.
+
+\1f
+File: gawk.info, Node: AWKPATH Variable, Next: Obsolete, Prev: Other Arguments, Up: Invoking Gawk
+
+11.4 The `AWKPATH' Environment Variable
+=======================================
+
+The previous minor node described how `awk' program files can be named
+on the command-line with the `-f' option. In most `awk'
+implementations, you must supply a precise path name for each program
+file, unless the file is in the current directory. But in `gawk', if
+the file name supplied to the `-f' option does not contain a `/', then
+`gawk' searches a list of directories (called the "search path"), one
+by one, looking for a file with the specified name.
+
+The search path is a string consisting of directory names separated by
+colons. `gawk' gets its search path from the `AWKPATH' environment
+variable. If that variable does not exist, `gawk' uses a default path,
+`.:/usr/local/share/awk'.(1) (Programs written for use by system
+administrators should use an `AWKPATH' variable that does not include
+the current directory, `.'.)
+
+The search path feature is particularly useful for building libraries
+of useful `awk' functions. The library files can be placed in a
+standard directory in the default path and then specified on the
+command line with a short file name. Otherwise, the full file name
+would have to be typed for each file.
+
+By using both the `--source' and `-f' options, your command-line `awk'
+programs can use facilities in `awk' library files (*note Library
+Functions::). Path searching is not done if `gawk' is in compatibility
+mode. This is true for both `--traditional' and `--posix'. *Note
+Options::.
+
+ NOTE: If you want files in the current directory to be found, you
+ must include the current directory in the path, either by including
+ `.' explicitly in the path or by writing a null entry in the path.
+ (A null entry is indicated by starting or ending the path with a
+ colon or by placing two colons next to each other (`::').) If the
+ current directory is not included in the path, then files cannot be
+ found in the current directory. This path search mechanism is
+ identical to the shell's.
+
+Starting with version 3.0, if `AWKPATH' is not defined in the
+environment, `gawk' places its default search path into
+`ENVIRON["AWKPATH"]'. This makes it easy to determine the actual search
+path that `gawk' will use from within an `awk' program.
+
+While you can change `ENVIRON["AWKPATH"]' within your `awk' program,
+this has no effect on the running program's behavior. This makes
+sense: the `AWKPATH' environment variable is used to find the program
+source files. Once your program is running, all the files have been
+found, and `gawk' no longer needs to use `AWKPATH'.
+
+---------- Footnotes ----------
+
+(1) Your version of `gawk' may use a different directory; it will
+depend upon how `gawk' was built and installed. The actual directory is
+the value of `$(datadir)' generated when `gawk' was configured. You
+probably don't need to worry about this, though.
+
+\1f
+File: gawk.info, Node: Obsolete, Next: Undocumented, Prev: AWKPATH Variable, Up: Invoking Gawk
+
+11.5 Obsolete Options and/or Features
+=====================================
+
+This minor node describes features and/or command-line options from
+previous releases of `gawk' that are either not available in the
+current version or that are still supported but deprecated (meaning that
+they will _not_ be in the next release).
+
+For version 3.1 of `gawk', there are no deprecated command-line options
+from the previous version of `gawk'. The use of `next file' (two
+words) for `nextfile' was deprecated in `gawk' 3.0 but still worked.
+Starting with version 3.1, the two-word usage is no longer accepted.
+
+The process-related special files described in *Note Special Process::,
+work as described, but are now considered deprecated. `gawk' prints a
+warning message every time they are used. (Use `PROCINFO' instead; see
+*Note Auto-set::.) They will be removed from the next release of
+`gawk'.
+
+\1f
+File: gawk.info, Node: Undocumented, Next: Known Bugs, Prev: Obsolete, Up: Invoking Gawk
+
+11.6 Undocumented Options and Features
+======================================
+
+ Use the Source, Luke!
+ Obi-Wan
+
+This minor node intentionally left blank.
+
+\1f
+File: gawk.info, Node: Known Bugs, Prev: Undocumented, Up: Invoking Gawk
+
+11.7 Known Bugs in `gawk'
+=========================
+
+ * The `-F' option for changing the value of `FS' (*note Options::)
+ is not necessary given the command-line variable assignment
+ feature; it remains only for backward compatibility.
+
+ * Syntactically invalid single-character programs tend to overflow
+ the parse stack, generating a rather unhelpful message. Such
+ programs are surprisingly difficult to diagnose in the completely
+ general case, and the effort to do so really is not worth it.
+
+\1f
+File: gawk.info, Node: Library Functions, Next: Sample Programs, Prev: Invoking Gawk, Up: Top
+
+12 A Library of `awk' Functions
+*******************************
+
+*Note User-defined::, describes how to write your own `awk' functions.
+Writing functions is important, because it allows you to encapsulate
+algorithms and program tasks in a single place. It simplifies
+programming, making program development more manageable, and making
+programs more readable.
+
+One valuable way to learn a new programming language is to _read_
+programs in that language. To that end, this major node and *Note
+Sample Programs::, provide a good-sized body of code for you to read,
+and hopefully, to learn from.
+
+This major node presents a library of useful `awk' functions. Many of
+the sample programs presented later in this Info file use these
+functions. The functions are presented here in a progression from
+simple to complex.
+
+*Note Extract Program::, presents a program that you can use to extract
+the source code for these example library functions and programs from
+the Texinfo source for this Info file. (This has already been done as
+part of the `gawk' distribution.)
+
+If you have written one or more useful, general-purpose `awk' functions
+and would like to contribute them to the author's collection of `awk'
+programs, see *Note How To Contribute::, for more information.
+
+The programs in this major node and in *Note Sample Programs::, freely
+use features that are `gawk'-specific. Rewriting these programs for
+different implementations of awk is pretty straightforward.
+
+Diagnostic error messages are sent to `/dev/stderr'. Use `| "cat
+1>&2"' instead of `> "/dev/stderr"' if your system does not have a
+`/dev/stderr', or if you cannot use `gawk'.
+
+A number of programs use `nextfile' (*note Nextfile Statement::) to
+skip any remaining input in the input file. *Note Nextfile Function::,
+shows you how to write a function that does the same thing.
+
+Finally, some of the programs choose to ignore upper- and lowercase
+distinctions in their input. They do so by assigning one to
+`IGNORECASE'. You can achieve almost the same effect(1) by adding the
+following rule to the beginning of the program:
+
+ # ignore case
+ { $0 = tolower($0) }
+
+Also, verify that all regexp and string constants used in comparisons
+use only lowercase letters.
+
+* Menu:
+
+* Library Names:: How to best name private global variables in
+ library functions.
+* General Functions:: Functions that are of general use.
+* Data File Management:: Functions for managing command-line data
+ files.
+* Getopt Function:: A function for processing command-line
+ arguments.
+* Passwd Functions:: Functions for getting user information.
+* Group Functions:: Functions for getting group information.
+
+---------- Footnotes ----------
+
+(1) The effects are not identical. Output of the transformed record
+will be in all lowercase, while `IGNORECASE' preserves the original
+contents of the input record.
+
+\1f
+File: gawk.info, Node: Library Names, Next: General Functions, Up: Library Functions
+
+12.1 Naming Library Function Global Variables
+=============================================
+
+Due to the way the `awk' language evolved, variables are either
+"global" (usable by the entire program) or "local" (usable just by a
+specific function). There is no intermediate state analogous to
+`static' variables in C.
+
+Library functions often need to have global variables that they can use
+to preserve state information between calls to the function--for
+example, `getopt''s variable `_opti' (*note Getopt Function::). Such
+variables are called "private", since the only functions that need to
+use them are the ones in the library.
+
+When writing a library function, you should try to choose names for your
+private variables that will not conflict with any variables used by
+either another library function or a user's main program. For example,
+a name like `i' or `j' is not a good choice, because user programs
+often use variable names like these for their own purposes.
+
+The example programs shown in this major node all start the names of
+their private variables with an underscore (`_'). Users generally
+don't use leading underscores in their variable names, so this
+convention immediately decreases the chances that the variable name
+will be accidentally shared with the user's program.
+
+In addition, several of the library functions use a prefix that helps
+indicate what function or set of functions use the variables--for
+example, `_pw_byname' in the user database routines (*note Passwd
+Functions::). This convention is recommended, since it even further
+decreases the chance of inadvertent conflict among variable names.
+Note that this convention is used equally well for variable names and
+for private function names as well.(1)
+
+As a final note on variable naming, if a function makes global variables
+available for use by a main program, it is a good convention to start
+that variable's name with a capital letter--for example, `getopt''s
+`Opterr' and `Optind' variables (*note Getopt Function::). The leading
+capital letter indicates that it is global, while the fact that the
+variable name is not all capital letters indicates that the variable is
+not one of `awk''s built-in variables, such as `FS'.
+
+It is also important that _all_ variables in library functions that do
+not need to save state are, in fact, declared local.(2) If this is not
+done, the variable could accidentally be used in the user's program,
+leading to bugs that are very difficult to track down:
+
+ function lib_func(x, y, l1, l2)
+ {
+ ...
+ USE VARIABLE some_var # some_var should be local
+ ... # but is not by oversight
+ }
+
+A different convention, common in the Tcl community, is to use a single
+associative array to hold the values needed by the library function(s),
+or "package." This significantly decreases the number of actual global
+names in use. For example, the functions described in *Note Passwd
+Functions::, might have used array elements `PW_data["inited"]',
+`PW_data["total"]', `PW_data["count"]', and `PW_data["awklib"]',
+instead of `_pw_inited', `_pw_awklib', `_pw_total', and `_pw_count'.
+
+The conventions presented in this minor node are exactly that:
+conventions. You are not required to write your programs this way--we
+merely recommend that you do so.
+
+---------- Footnotes ----------
+
+(1) While all the library routines could have been rewritten to use
+this convention, this was not done, in order to show how my own `awk'
+programming style has evolved and to provide some basis for this
+discussion.
+
+(2) `gawk''s `--dump-variables' command-line option is useful for
+verifying this.
+
+\1f
+File: gawk.info, Node: General Functions, Next: Data File Management, Prev: Library Names, Up: Library Functions
+
+12.2 General Programming
+========================
+
+This minor node presents a number of functions that are of general
+programming use.
+
+* Menu:
+
+* Nextfile Function:: Two implementations of a `nextfile'
+ function.
+* Strtonum Function:: A replacement for the built-in `strtonum'
+ function.
+* Assert Function:: A function for assertions in `awk'
+ programs.
+* Round Function:: A function for rounding if `sprintf' does
+ not do it correctly.
+* Cliff Random Function:: The Cliff Random Number Generator.
+* Ordinal Functions:: Functions for using characters as numbers and
+ vice versa.
+* Join Function:: A function to join an array into a string.
+* Gettimeofday Function:: A function to get formatted times.
+
+\1f
+File: gawk.info, Node: Nextfile Function, Next: Strtonum Function, Up: General Functions
+
+12.2.1 Implementing `nextfile' as a Function
+--------------------------------------------
+
+The `nextfile' statement, presented in *Note Nextfile Statement::, is a
+`gawk'-specific extension--it is not available in most other
+implementations of `awk'. This minor node shows two versions of a
+`nextfile' function that you can use to simulate `gawk''s `nextfile'
+statement if you cannot use `gawk'.
+
+A first attempt at writing a `nextfile' function is as follows:
+
+ # nextfile --- skip remaining records in current file
+ # this should be read in before the "main" awk program
+
+ function nextfile() { _abandon_ = FILENAME; next }
+ _abandon_ == FILENAME { next }
+
+Because it supplies a rule that must be executed first, this file should
+be included before the main program. This rule compares the current
+data file's name (which is always in the `FILENAME' variable) to a
+private variable named `_abandon_'. If the file name matches, then the
+action part of the rule executes a `next' statement to go on to the
+next record. (The use of `_' in the variable name is a convention. It
+is discussed more fully in *Note Library Names::.)
+
+The use of the `next' statement effectively creates a loop that reads
+all the records from the current data file. The end of the file is
+eventually reached and a new data file is opened, changing the value of
+`FILENAME'. Once this happens, the comparison of `_abandon_' to
+`FILENAME' fails, and execution continues with the first rule of the
+"real" program.
+
+The `nextfile' function itself simply sets the value of `_abandon_' and
+then executes a `next' statement to start the loop.
+
+This initial version has a subtle problem. If the same data file is
+listed _twice_ on the commandline, one right after the other or even
+with just a variable assignment between them, this code skips right
+through the file a second time, even though it should stop when it gets
+to the end of the first occurrence. A second version of `nextfile'
+that remedies this problem is shown here:
+
+ # nextfile --- skip remaining records in current file
+ # correctly handle successive occurrences of the same file
+ # this should be read in before the "main" awk program
+
+ function nextfile() { _abandon_ = FILENAME; next }
+
+ _abandon_ == FILENAME {
+ if (FNR == 1)
+ _abandon_ = ""
+ else
+ next
+ }
+
+The `nextfile' function has not changed. It makes `_abandon_' equal to
+the current file name and then executes a `next' statement. The `next'
+statement reads the next record and increments `FNR' so that `FNR' is
+guaranteed to have a value of at least two. However, if `nextfile' is
+called for the last record in the file, then `awk' closes the current
+data file and moves on to the next one. Upon doing so, `FILENAME' is
+set to the name of the new file and `FNR' is reset to one. If this
+next file is the same as the previous one, `_abandon_' is still equal
+to `FILENAME'. However, `FNR' is equal to one, telling us that this is
+a new occurrence of the file and not the one we were reading when the
+`nextfile' function was executed. In that case, `_abandon_' is reset
+to the empty string, so that further executions of this rule fail
+(until the next time that `nextfile' is called).
+
+If `FNR' is not one, then we are still in the original data file and
+the program executes a `next' statement to skip through it.
+
+An important question to ask at this point is: given that the
+functionality of `nextfile' can be provided with a library file, why is
+it built into `gawk'? Adding features for little reason leads to
+larger, slower programs that are harder to maintain. The answer is
+that building `nextfile' into `gawk' provides significant gains in
+efficiency. If the `nextfile' function is executed at the beginning of
+a large data file, `awk' still has to scan the entire file, splitting
+it up into records, just to skip over it. The built-in `nextfile' can
+simply close the file immediately and proceed to the next one, which
+saves a lot of time. This is particularly important in `awk', because
+`awk' programs are generally I/O-bound (i.e., they spend most of their
+time doing input and output, instead of performing computations).
+
+\1f
+File: gawk.info, Node: Strtonum Function, Next: Assert Function, Prev: Nextfile Function, Up: General Functions
+
+12.2.2 Converting Strings To Numbers
+------------------------------------
+
+The `strtonum' function (*note String Functions::) is a `gawk'
+extension. The following function provides an implementation for other
+versions of `awk':
+
+ # strtonum --- convert string to number
+ function mystrtonum(str, ret, chars, n, i, k, c)
+ {
+ if (str ~ /^0[0-7]*$/) {
+ # octal
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ if ((k = index("01234567", c)) > 0)
+ k-- # adjust for 1-basing in awk
+
+ ret = ret * 8 + k
+ }
+ } else if (str ~ /^0[xX][0-9a-fA-f]+/) {
+ # hexadecimal
+ str = substr(str, 3) # lop off leading 0x
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ c = tolower(c)
+ if ((k = index("0123456789", c)) > 0)
+ k-- # adjust for 1-basing in awk
+ else if ((k = index("abcdef", c)) > 0)
+ k += 9
+
+ ret = ret * 16 + k
+ }
+ } else if (str ~ /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) {
+ # decimal number, possibly floating point
+ ret = str + 0
+ } else
+ ret = "NOT-A-NUMBER"
+
+ return ret
+ }
+
+ # BEGIN { # gawk test harness
+ # 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[7] = "1.32E2"
+ #
+ # for (i = 1; i in a; i++)
+ # print a[i], strtonum(a[i]), mystrtonum(a[i])
+ # }
+
+The function first looks for C-style octal numbers (base 8). If the
+input string matches a regular expression describing octal numbers,
+then `mystrtonum' loops through each character in the string. It sets
+`k' to the index in `"01234567"' of the current octal digit. Since the
+return value is one-based, the `k--' adjusts `k' so it can be used in
+computing the return value.
+
+Similar logic applies to the code that checks for and converts a
+hexadecimal value, which starts with `0x' or `0X'. The use of
+`tolower' simplifies the computation for finding the correct numeric
+value for each hexadecimal digit.
+
+Finally, if the string matches the (rather complicated) regex for a
+regular decimal integer or floating-point numer, the computation `ret =
+str + 0' lets `awk' convert the value to a number.
+
+A commented-out test program is included, so that the function can be
+tested with `gawk' and the results compared to the built-in `strtonum'
+function.
+
+\1f
+File: gawk.info, Node: Assert Function, Next: Round Function, Prev: Strtonum Function, Up: General Functions
+
+12.2.3 Assertions
+-----------------
+
+When writing large programs, it is often useful to know that a
+condition or set of conditions is true. Before proceeding with a
+particular computation, you make a statement about what you believe to
+be the case. Such a statement is known as an "assertion". The C
+language provides an `<assert.h>' header file and corresponding
+`assert' macro that the programmer can use to make assertions. If an
+assertion fails, the `assert' macro arranges to print a diagnostic
+message describing the condition that should have been true but was
+not, and then it kills the program. In C, using `assert' looks this:
+
+ #include <assert.h>
+
+ int myfunc(int a, double b)
+ {
+ assert(a <= 5 && b >= 17.1);
+ ...
+ }
+
+If the assertion fails, the program prints a message similar to this:
+
+ prog.c:5: assertion failed: a <= 5 && b >= 17.1
+
+The C language makes it possible to turn the condition into a string
+for use in printing the diagnostic message. This is not possible in
+`awk', so this `assert' function also requires a string version of the
+condition that is being tested. Following is the function:
+
+ # assert --- assert that a condition is true. Otherwise exit.
+ function assert(condition, string)
+ {
+ if (! condition) {
+ printf("%s:%d: assertion failed: %s\n",
+ FILENAME, FNR, string) > "/dev/stderr"
+ _assert_exit = 1
+ exit 1
+ }
+ }
+
+ END {
+ if (_assert_exit)
+ exit 1
+ }
+
+The `assert' function tests the `condition' parameter. If it is false,
+it prints a message to standard error, using the `string' parameter to
+describe the failed condition. It then sets the variable
+`_assert_exit' to one and executes the `exit' statement. The `exit'
+statement jumps to the `END' rule. If the `END' rules finds
+`_assert_exit' to be true, it exits immediately.
+
+The purpose of the test in the `END' rule is to keep any other `END'
+rules from running. When an assertion fails, the program should exit
+immediately. If no assertions fail, then `_assert_exit' is still false
+when the `END' rule is run normally, and the rest of the program's
+`END' rules execute. For all of this to work correctly, `assert.awk'
+must be the first source file read by `awk'. The function can be used
+in a program in the following way:
+
+ function myfunc(a, b)
+ {
+ assert(a <= 5 && b >= 17.1, "a <= 5 && b >= 17.1")
+ ...
+ }
+
+If the assertion fails, you see a message similar to the following:
+
+ mydata:1357: assertion failed: a <= 5 && b >= 17.1
+
+There is a small problem with this version of `assert'. An `END' rule
+is automatically added to the program calling `assert'. Normally, if a
+program consists of just a `BEGIN' rule, the input files and/or
+standard input are not read. However, now that the program has an `END'
+rule, `awk' attempts to read the input data files or standard input
+(*note Using BEGIN/END::), most likely causing the program to hang as
+it waits for input.
+
+There is a simple workaround to this: make sure the `BEGIN' rule always
+ends with an `exit' statement.
+
+\1f
+File: gawk.info, Node: Round Function, Next: Cliff Random Function, Prev: Assert Function, Up: General Functions
+
+12.2.4 Rounding Numbers
+-----------------------
+
+The way `printf' and `sprintf' (*note Printf::) perform rounding often
+depends upon the system's C `sprintf' subroutine. On many machines,
+`sprintf' rounding is "unbiased," which means it doesn't always round a
+trailing `.5' up, contrary to naive expectations. In unbiased
+rounding, `.5' rounds to even, rather than always up, so 1.5 rounds to
+2 but 4.5 rounds to 4. This means that if you are using a format that
+does rounding (e.g., `"%.0f"'), you should check what your system does.
+The following function does traditional rounding; it might be useful
+if your awk's `printf' does unbiased rounding:
+
+ # round.awk --- do normal rounding
+ function round(x, ival, aval, fraction)
+ {
+ ival = int(x) # integer part, int() truncates
+
+ # see if fractional part
+ if (ival == x) # no fraction
+ return x
+
+ if (x < 0) {
+ aval = -x # absolute value
+ ival = int(aval)
+ fraction = aval - ival
+ if (fraction >= .5)
+ return int(x) - 1 # -2.5 --> -3
+ else
+ return int(x) # -2.3 --> -2
+ } else {
+ fraction = x - ival
+ if (fraction >= .5)
+ return ival + 1
+ else
+ return ival
+ }
+ }
+
+ # test harness
+ { print $0, round($0) }
+
+\1f
+File: gawk.info, Node: Cliff Random Function, Next: Ordinal Functions, Prev: Round Function, Up: General Functions
+
+12.2.5 The Cliff Random Number Generator
+----------------------------------------
+
+The Cliff random number generator(1) is a very simple random number
+generator that "passes the noise sphere test for randomness by showing
+no structure." It is easily programmed, in less than 10 lines of `awk'
+code:
+
+ # cliff_rand.awk --- generate Cliff random numbers
+ BEGIN { _cliff_seed = 0.1 }
+
+ function cliff_rand()
+ {
+ _cliff_seed = (100 * log(_cliff_seed)) % 1
+ if (_cliff_seed < 0)
+ _cliff_seed = - _cliff_seed
+ return _cliff_seed
+ }
+
+This algorithm requires an initial "seed" of 0.1. Each new value uses
+the current seed as input for the calculation. If the built-in `rand'
+function (*note Numeric Functions::) isn't random enough, you might try
+using this function instead.
+
+---------- Footnotes ----------
+
+(1) `http://mathworld.wolfram.com/CliffRandomNumberGenerator.hmtl'
+
+\1f
+File: gawk.info, Node: Ordinal Functions, Next: Join Function, Prev: Cliff Random Function, Up: General Functions
+
+12.2.6 Translating Between Characters and Numbers
+-------------------------------------------------
+
+One commercial implementation of `awk' supplies a built-in function,
+`ord', which takes a character and returns the numeric value for that
+character in the machine's character set. If the string passed to
+`ord' has more than one character, only the first one is used.
+
+The inverse of this function is `chr' (from the function of the same
+name in Pascal), which takes a number and returns the corresponding
+character. Both functions are written very nicely in `awk'; there is
+no real reason to build them into the `awk' interpreter:
+
+ # ord.awk --- do ord and chr
+
+ # Global identifiers:
+ # _ord_: numerical values indexed by characters
+ # _ord_init: function to initialize _ord_
+ BEGIN { _ord_init() }
+
+ function _ord_init( low, high, i, t)
+ {
+ low = sprintf("%c", 7) # BEL is ascii 7
+ if (low == "\a") { # regular ascii
+ low = 0
+ high = 127
+ } else if (sprintf("%c", 128 + 7) == "\a") {
+ # ascii, mark parity
+ low = 128
+ high = 255
+ } else { # ebcdic(!)
+ low = 0
+ high = 255
+ }
+
+ for (i = low; i <= high; i++) {
+ t = sprintf("%c", i)
+ _ord_[t] = i
+ }
+ }
+
+Some explanation of the numbers used by `chr' is worthwhile. The most
+prominent character set in use today is ASCII. Although an 8-bit byte
+can hold 256 distinct values (from 0 to 255), ASCII only defines
+characters that use the values from 0 to 127.(1) In the now distant
+past, at least one minicomputer manufacturer used ASCII, but with mark
+parity, meaning that the leftmost bit in the byte is always 1. This
+means that on those systems, characters have numeric values from 128 to
+255. Finally, large mainframe systems use the EBCDIC character set,
+which uses all 256 values. While there are other character sets in use
+on some older systems, they are not really worth worrying about:
+
+ function ord(str, c)
+ {
+ # only first character is of interest
+ c = substr(str, 1, 1)
+ return _ord_[c]
+ }
+
+ function chr(c)
+ {
+ # force c to be numeric by adding 0
+ return sprintf("%c", c + 0)
+ }
+
+ #### test code ####
+ # BEGIN \
+ # {
+ # for (;;) {
+ # printf("enter a character: ")
+ # if (getline var <= 0)
+ # break
+ # printf("ord(%s) = %d\n", var, ord(var))
+ # }
+ # }
+
+An obvious improvement to these functions is to move the code for the
+`_ord_init' function into the body of the `BEGIN' rule. It was written
+this way initially for ease of development. There is a "test program"
+in a `BEGIN' rule, to test the function. It is commented out for
+production use.
+
+---------- Footnotes ----------
+
+(1) ASCII has been extended in many countries to use the values from
+128 to 255 for country-specific characters. If your system uses these
+extensions, you can simplify `_ord_init' to simply loop from 0 to 255.
+
+\1f
+File: gawk.info, Node: Join Function, Next: Gettimeofday Function, Prev: Ordinal Functions, Up: General Functions
+
+12.2.7 Merging an Array into a String
+-------------------------------------
+
+When doing string processing, it is often useful to be able to join all
+the strings in an array into one long string. The following function,
+`join', accomplishes this task. It is used later in several of the
+application programs (*note Sample Programs::).
+
+Good function design is important; this function needs to be general
+but it should also have a reasonable default behavior. It is called
+with an array as well as the beginning and ending indices of the
+elements in the array to be merged. This assumes that the array
+indices are numeric--a reasonable assumption since the array was likely
+created with `split' (*note String Functions::):
+
+ # join.awk --- join an array into a string
+ function join(array, start, end, sep, result, i)
+ {
+ if (sep == "")
+ sep = " "
+ else if (sep == SUBSEP) # magic value
+ sep = ""
+ result = array[start]
+ for (i = start + 1; i <= end; i++)
+ result = result sep array[i]
+ return result
+ }
+
+An optional additional argument is the separator to use when joining the
+strings back together. If the caller supplies a nonempty value, `join'
+uses it; if it is not supplied, it has a null value. In this case,
+`join' uses a single blank as a default separator for the strings. If
+the value is equal to `SUBSEP', then `join' joins the strings with no
+separator between them. `SUBSEP' serves as a "magic" value to indicate
+that there should be no separation between the component strings.(1)
+
+---------- Footnotes ----------
+
+(1) It would be nice if `awk' had an assignment operator for
+concatenation. The lack of an explicit operator for concatenation
+makes string operations more difficult than they really need to be.
+
+\1f
+File: gawk.info, Node: Gettimeofday Function, Prev: Join Function, Up: General Functions
+
+12.2.8 Managing the Time of Day
+-------------------------------
+
+The `systime' and `strftime' functions described in *Note Time
+Functions::, provide the minimum functionality necessary for dealing
+with the time of day in human readable form. While `strftime' is
+extensive, the control formats are not necessarily easy to remember or
+intuitively obvious when reading a program.
+
+The following function, `gettimeofday', populates a user-supplied array
+with preformatted time information. It returns a string with the
+current time formatted in the same way as the `date' utility:
+
+ # gettimeofday.awk --- get the time of day in a usable format
+
+ # Returns a string in the format of output of date(1)
+ # Populates the array argument time with individual values:
+ # time["second"] -- seconds (0 - 59)
+ # time["minute"] -- minutes (0 - 59)
+ # time["hour"] -- hours (0 - 23)
+ # time["althour"] -- hours (0 - 12)
+ # time["monthday"] -- day of month (1 - 31)
+ # time["month"] -- month of year (1 - 12)
+ # time["monthname"] -- name of the month
+ # time["shortmonth"] -- short name of the month
+ # time["year"] -- year modulo 100 (0 - 99)
+ # time["fullyear"] -- full year
+ # time["weekday"] -- day of week (Sunday = 0)
+ # time["altweekday"] -- day of week (Monday = 0)
+ # time["dayname"] -- name of weekday
+ # time["shortdayname"] -- short name of weekday
+ # time["yearday"] -- day of year (0 - 365)
+ # time["timezone"] -- abbreviation of timezone name
+ # time["ampm"] -- AM or PM designation
+ # time["weeknum"] -- week number, Sunday first day
+ # time["altweeknum"] -- week number, Monday first day
+
+ function gettimeofday(time, ret, now, i)
+ {
+ # get time once, avoids unnecessary system calls
+ now = systime()
+
+ # return date(1)-style output
+ ret = strftime("%a %b %d %H:%M:%S %Z %Y", now)
+
+ # clear out target array
+ delete time
+
+ # fill in values, force numeric values to be
+ # numeric by adding 0
+ time["second"] = strftime("%S", now) + 0
+ time["minute"] = strftime("%M", now) + 0
+ time["hour"] = strftime("%H", now) + 0
+ time["althour"] = strftime("%I", now) + 0
+ time["monthday"] = strftime("%d", now) + 0
+ time["month"] = strftime("%m", now) + 0
+ time["monthname"] = strftime("%B", now)
+ time["shortmonth"] = strftime("%b", now)
+ time["year"] = strftime("%y", now) + 0
+ time["fullyear"] = strftime("%Y", now) + 0
+ time["weekday"] = strftime("%w", now) + 0
+ time["altweekday"] = strftime("%u", now) + 0
+ time["dayname"] = strftime("%A", now)
+ time["shortdayname"] = strftime("%a", now)
+ time["yearday"] = strftime("%j", now) + 0
+ time["timezone"] = strftime("%Z", now)
+ time["ampm"] = strftime("%p", now)
+ time["weeknum"] = strftime("%U", now) + 0
+ time["altweeknum"] = strftime("%W", now) + 0
+
+ return ret
+ }
+
+The string indices are easier to use and read than the various formats
+required by `strftime'. The `alarm' program presented in *Note Alarm
+Program::, uses this function. A more general design for the
+`gettimeofday' function would have allowed the user to supply an
+optional timestamp value to use instead of the current time.
+
+\1f
+File: gawk.info, Node: Data File Management, Next: Getopt Function, Prev: General Functions, Up: Library Functions
+
+12.3 Data File Management
+=========================
+
+This minor node presents functions that are useful for managing
+command-line data files.
+
+* Menu:
+
+* Filetrans Function:: A function for handling data file transitions.
+* Rewind Function:: A function for rereading the current file.
+* File Checking:: Checking that data files are readable.
+* Empty Files:: Checking for zero-length files.
+* Ignoring Assigns:: Treating assignments as file names.
+
+\1f
+File: gawk.info, Node: Filetrans Function, Next: Rewind Function, Up: Data File Management
+
+12.3.1 Noting Data File Boundaries
+----------------------------------
+
+The `BEGIN' and `END' rules are each executed exactly once at the
+beginning and end of your `awk' program, respectively (*note
+BEGIN/END::). We (the `gawk' authors) once had a user who mistakenly
+thought that the `BEGIN' rule is executed at the beginning of each data
+file and the `END' rule is executed at the end of each data file. When
+informed that this was not the case, the user requested that we add new
+special patterns to `gawk', named `BEGIN_FILE' and `END_FILE', that
+would have the desired behavior. He even supplied us the code to do so.
+
+Adding these special patterns to `gawk' wasn't necessary; the job can
+be done cleanly in `awk' itself, as illustrated by the following
+library program. It arranges to call two user-supplied functions,
+`beginfile' and `endfile', at the beginning and end of each data file.
+Besides solving the problem in only nine(!) lines of code, it does so
+_portably_; this works with any implementation of `awk':
+
+ # transfile.awk
+ #
+ # Give the user a hook for filename transitions
+ #
+ # The user must supply functions beginfile() and endfile()
+ # that each take the name of the file being started or
+ # finished, respectively.
+
+ FILENAME != _oldfilename \
+ {
+ if (_oldfilename != "")
+ endfile(_oldfilename)
+ _oldfilename = FILENAME
+ beginfile(FILENAME)
+ }
+
+ END { endfile(FILENAME) }
+
+This file must be loaded before the user's "main" program, so that the
+rule it supplies is executed first.
+
+This rule relies on `awk''s `FILENAME' variable that automatically
+changes for each new data file. The current file name is saved in a
+private variable, `_oldfilename'. If `FILENAME' does not equal
+`_oldfilename', then a new data file is being processed and it is
+necessary to call `endfile' for the old file. Because `endfile' should
+only be called if a file has been processed, the program first checks
+to make sure that `_oldfilename' is not the null string. The program
+then assigns the current file name to `_oldfilename' and calls
+`beginfile' for the file. Because, like all `awk' variables,
+`_oldfilename' is initialized to the null string, this rule executes
+correctly even for the first data file.
+
+The program also supplies an `END' rule to do the final processing for
+the last file. Because this `END' rule comes before any `END' rules
+supplied in the "main" program, `endfile' is called first. Once again
+the value of multiple `BEGIN' and `END' rules should be clear.
+
+This version has same problem as the first version of `nextfile' (*note
+Nextfile Function::). If the same data file occurs twice in a row on
+the command line, then `endfile' and `beginfile' are not executed at
+the end of the first pass and at the beginning of the second pass. The
+following version solves the problem:
+
+ # ftrans.awk --- handle data file transitions
+ #
+ # user supplies beginfile() and endfile() functions
+ FNR == 1 {
+ if (_filename_ != "")
+ endfile(_filename_)
+ _filename_ = FILENAME
+ beginfile(FILENAME)
+ }
+
+ END { endfile(_filename_) }
+
+*Note Wc Program::, shows how this library function can be used and how
+it simplifies writing the main program.
+
+\1f
+File: gawk.info, Node: Rewind Function, Next: File Checking, Prev: Filetrans Function, Up: Data File Management
+
+12.3.2 Rereading the Current File
+---------------------------------
+
+Another request for a new built-in function was for a `rewind' function
+that would make it possible to reread the current file. The requesting
+user didn't want to have to use `getline' (*note Getline::) inside a
+loop.
+
+However, as long as you are not in the `END' rule, it is quite easy to
+arrange to immediately close the current input file and then start over
+with it from the top. For lack of a better name, we'll call it
+`rewind':
+
+ # rewind.awk --- rewind the current file and start over
+ function rewind( i)
+ {
+ # shift remaining arguments up
+ for (i = ARGC; i > ARGIND; i--)
+ ARGV[i] = ARGV[i-1]
+
+ # make sure gawk knows to keep going
+ ARGC++
+
+ # make current file next to get done
+ ARGV[ARGIND+1] = FILENAME
+
+ # do it
+ nextfile
+ }
+
+This code relies on the `ARGIND' variable (*note Auto-set::), which is
+specific to `gawk'. If you are not using `gawk', you can use ideas
+presented in *Note Filetrans Function::, to either update `ARGIND' on
+your own or modify this code as appropriate.
+
+The `rewind' function also relies on the `nextfile' keyword (*note
+Nextfile Statement::). *Note Nextfile Function::, for a function
+version of `nextfile'.
+
+\1f
+File: gawk.info, Node: File Checking, Next: Empty Files, Prev: Rewind Function, Up: Data File Management
+
+12.3.3 Checking for Readable Data Files
+---------------------------------------
+
+Normally, if you give `awk' a data file that isn't readable, it stops
+with a fatal error. There are times when you might want to just ignore
+such files and keep going. You can do this by prepending the following
+program to your `awk' program:
+
+ # readable.awk --- library file to skip over unreadable files
+ BEGIN {
+ for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] ~ /^[A-Za-z_][A-Za-z0-9_]*=.*/ \
+ || ARGV[i] == "-")
+ continue # assignment or standard input
+ else if ((getline junk < ARGV[i]) < 0) # unreadable
+ delete ARGV[i]
+ else
+ close(ARGV[i])
+ }
+ }
+
+In `gawk', the `getline' won't be fatal (unless `--posix' is in force).
+Removing the element from `ARGV' with `delete' skips the file (since
+it's no longer in the list).
+
+\1f
+File: gawk.info, Node: Empty Files, Next: Ignoring Assigns, Prev: File Checking, Up: Data File Management
+
+12.3.4 Checking For Zero-length Files
+-------------------------------------
+
+All known `awk' implementations silently skip over zero-length files.
+This is a by-product of `awk''s implicit
+read-a-record-and-match-against-the-rules loop: when `awk' tries to
+read a record from an empty file, it immediately receives an end of
+file indication, closes the file, and proceeds on to the next
+command-line data file, _without_ executing any user-level `awk'
+program code.
+
+Using `gawk''s `ARGIND' variable (*note Built-in Variables::), it is
+possible to detect when an empty data file has been skipped. Similar
+to the library file presented in *Note Filetrans Function::, the
+following library file calls a function named `zerofile' that the user
+must provide. The arguments passed are the file name and the position
+in `ARGV' where it was found:
+
+ # zerofile.awk --- library file to process empty input files
+ 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)
+ }
+
+The user-level variable `Argind' allows the `awk' program to track its
+progress through `ARGV'. Whenever the program detects that `ARGIND' is
+greater than `Argind + 1', it means that one or more empty files were
+skipped. The action then calls `zerofile' for each such file,
+incrementing `Argind' along the way.
+
+The `Argind != ARGIND' rule simply keeps `Argind' up to date in the
+normal case.
+
+Finally, the `END' rule catches the case of any empty files at the end
+of the command-line arguments. Note that the test in the condition of
+the `for' loop uses the `<=' operator, not `<'.
+
+As an exercise, you might consider whether this same problem can be
+solved without relying on `gawk''s `ARGIND' variable.
+
+As a second exercise, revise this code to handle the case where an
+intervening value in `ARGV' is a variable assignment.
+
+\1f
+File: gawk.info, Node: Ignoring Assigns, Prev: Empty Files, Up: Data File Management
+
+12.3.5 Treating Assignments as File Names
+-----------------------------------------
+
+Occasionally, you might not want `awk' to process command-line variable
+assignments (*note Assignment Options::). In particular, if you have
+file names that contain an `=' character, `awk' treats the file name as
+an assignment, and does not process it.
+
+Some users have suggested an additional command-line option for `gawk'
+to disable command-line assignments. However, some simple programming
+with a library file does the trick:
+
+ # noassign.awk --- library file to avoid the need for a
+ # special option that disables command-line assignments
+ function disable_assigns(argc, argv, i)
+ {
+ for (i = 1; i < argc; i++)
+ if (argv[i] ~ /^[A-Za-z_][A-Za-z_0-9]*=.*/)
+ argv[i] = ("./" argv[i])
+ }
+
+ BEGIN {
+ if (No_command_assign)
+ disable_assigns(ARGC, ARGV)
+ }
+
+You then run your program this way:
+
+ awk -v No_command_assign=1 -f noassign.awk -f yourprog.awk *
+
+The function works by looping through the arguments. It prepends `./'
+to any argument that matches the form of a variable assignment, turning
+that argument into a file name.
+
+The use of `No_command_assign' allows you to disable command-line
+assignments at invocation time, by giving the variable a true value.
+When not set, it is initially zero (i.e., false), so the command-line
+arguments are left alone.
+
+\1f
+File: gawk.info, Node: Getopt Function, Next: Passwd Functions, Prev: Data File Management, Up: Library Functions
+
+12.4 Processing Command-Line Options
+====================================
+
+Most utilities on POSIX compatible systems take options, or "switches,"
+on the command line that can be used to change the way a program
+behaves. `awk' is an example of such a program (*note Options::).
+Often, options take "arguments"; i.e., data that the program needs to
+correctly obey the command-line option. For example, `awk''s `-F'
+option requires a string to use as the field separator. The first
+occurrence on the command line of either `--' or a string that does not
+begin with `-' ends the options.
+
+Modern Unix systems provide a C function named `getopt' for processing
+command-line arguments. The programmer provides a string describing the
+one-letter options. If an option requires an argument, it is followed
+in the string with a colon. `getopt' is also passed the count and
+values of the command-line arguments and is called in a loop. `getopt'
+processes the command-line arguments for option letters. Each time
+around the loop, it returns a single character representing the next
+option letter that it finds, or `?' if it finds an invalid option.
+When it returns -1, there are no options left on the command line.
+
+When using `getopt', options that do not take arguments can be grouped
+together. Furthermore, options that take arguments require that the
+argument is present. The argument can immediately follow the option
+letter, or it can be a separate command-line argument.
+
+Given a hypothetical program that takes three command-line options,
+`-a', `-b', and `-c', where `-b' requires an argument, all of the
+following are valid ways of invoking the program:
+
+ prog -a -b foo -c data1 data2 data3
+ prog -ac -bfoo -- data1 data2 data3
+ prog -acbfoo data1 data2 data3
+
+Notice that when the argument is grouped with its option, the rest of
+the argument is considered to be the option's argument. In this
+example, `-acbfoo' indicates that all of the `-a', `-b', and `-c'
+options were supplied, and that `foo' is the argument to the `-b'
+option.
+
+`getopt' provides four external variables that the programmer can use:
+
+`optind'
+ The index in the argument value array (`argv') where the first
+ nonoption command-line argument can be found.
+
+`optarg'
+ The string value of the argument to an option.
+
+`opterr'
+ Usually `getopt' prints an error message when it finds an invalid
+ option. Setting `opterr' to zero disables this feature. (An
+ application might want to print its own error message.)
+
+`optopt'
+ The letter representing the command-line option.
+
+The following C fragment shows how `getopt' might process command-line
+arguments for `awk':
+
+ int
+ main(int argc, char *argv[])
+ {
+ ...
+ /* print our own message */
+ opterr = 0;
+ while ((c = getopt(argc, argv, "v:f:F:W:")) != -1) {
+ switch (c) {
+ case 'f': /* file */
+ ...
+ break;
+ case 'F': /* field separator */
+ ...
+ break;
+ case 'v': /* variable assignment */
+ ...
+ break;
+ case 'W': /* extension */
+ ...
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+ ...
+ }
+
+As a side point, `gawk' actually uses the GNU `getopt_long' function to
+process both normal and GNU-style long options (*note Options::).
+
+The abstraction provided by `getopt' is very useful and is quite handy
+in `awk' programs as well. Following is an `awk' version of `getopt'.
+This function highlights one of the greatest weaknesses in `awk', which
+is that it is very poor at manipulating single characters. Repeated
+calls to `substr' are necessary for accessing individual characters
+(*note String Functions::).(1)
+
+The discussion that follows walks through the code a bit at a time:
+
+ # getopt.awk --- do C library getopt(3) function in awk
+ # External variables:
+ # Optind -- index in ARGV of first nonoption argument
+ # Optarg -- string value of argument to current option
+ # Opterr -- if nonzero, print our own diagnostic
+ # Optopt -- current option letter
+
+ # Returns:
+ # -1 at end of options
+ # ? for unrecognized option
+ # <c> a character representing the current option
+
+ # Private Data:
+ # _opti -- index in multi-flag option, e.g., -abc
+
+The function starts out with a list of the global variables it uses,
+what the return values are, what they mean, and any global variables
+that are "private" to this library function. Such documentation is
+essential for any program, and particularly for library functions.
+
+The `getopt' function first checks that it was indeed called with a
+string of options (the `options' parameter). If `options' has a zero
+length, `getopt' immediately returns -1:
+
+ function getopt(argc, argv, options, thisopt, i)
+ {
+ if (length(options) == 0) # no options given
+ return -1
+
+ if (argv[Optind] == "--") { # all done
+ Optind++
+ _opti = 0
+ return -1
+ } else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) {
+ _opti = 0
+ return -1
+ }
+
+The next thing to check for is the end of the options. A `--' ends the
+command-line options, as does any command-line argument that does not
+begin with a `-'. `Optind' is used to step through the array of
+command-line arguments; it retains its value across calls to `getopt',
+because it is a global variable.
+
+The regular expression that is used, `/^-[^: \t\n\f\r\v\b]/', is
+perhaps a bit of overkill; it checks for a `-' followed by anything
+that is not whitespace and not a colon. If the current command-line
+argument does not match this pattern, it is not an option, and it ends
+option processing:
+
+ if (_opti == 0)
+ _opti = 2
+ thisopt = substr(argv[Optind], _opti, 1)
+ Optopt = thisopt
+ i = index(options, thisopt)
+ if (i == 0) {
+ if (Opterr)
+ printf("%c -- invalid option\n",
+ thisopt) > "/dev/stderr"
+ if (_opti >= length(argv[Optind])) {
+ Optind++
+ _opti = 0
+ } else
+ _opti++
+ return "?"
+ }
+
+The `_opti' variable tracks the position in the current command-line
+argument (`argv[Optind]'). If multiple options are grouped together
+with one `-' (e.g., `-abx'), it is necessary to return them to the user
+one at a time.
+
+If `_opti' is equal to zero, it is set to two, which is the index in
+the string of the next character to look at (we skip the `-', which is
+at position one). The variable `thisopt' holds the character, obtained
+with `substr'. It is saved in `Optopt' for the main program to use.
+
+If `thisopt' is not in the `options' string, then it is an invalid
+option. If `Opterr' is nonzero, `getopt' prints an error message on
+the standard error that is similar to the message from the C version of
+`getopt'.
+
+Because the option is invalid, it is necessary to skip it and move on
+to the next option character. If `_opti' is greater than or equal to
+the length of the current command-line argument, it is necessary to
+move on to the next argument, so `Optind' is incremented and `_opti' is
+reset to zero. Otherwise, `Optind' is left alone and `_opti' is merely
+incremented.
+
+In any case, because the option is invalid, `getopt' returns `?'. The
+main program can examine `Optopt' if it needs to know what the invalid
+option letter actually is. Continuing on:
+
+ if (substr(options, i + 1, 1) == ":") {
+ # get option argument
+ if (length(substr(argv[Optind], _opti + 1)) > 0)
+ Optarg = substr(argv[Optind], _opti + 1)
+ else
+ Optarg = argv[++Optind]
+ _opti = 0
+ } else
+ Optarg = ""
+
+If the option requires an argument, the option letter is followed by a
+colon in the `options' string. If there are remaining characters in the
+current command-line argument (`argv[Optind]'), then the rest of that
+string is assigned to `Optarg'. Otherwise, the next command-line
+argument is used (`-xFOO' versus `-x FOO'). In either case, `_opti' is
+reset to zero, because there are no more characters left to examine in
+the current command-line argument. Continuing:
+
+ if (_opti == 0 || _opti >= length(argv[Optind])) {
+ Optind++
+ _opti = 0
+ } else
+ _opti++
+ return thisopt
+ }
+
+Finally, if `_opti' is either zero or greater than the length of the
+current command-line argument, it means this element in `argv' is
+through being processed, so `Optind' is incremented to point to the
+next element in `argv'. If neither condition is true, then only
+`_opti' is incremented, so that the next option letter can be processed
+on the next call to `getopt'.
+
+The `BEGIN' rule initializes both `Opterr' and `Optind' to one.
+`Opterr' is set to one, since the default behavior is for `getopt' to
+print a diagnostic message upon seeing an invalid option. `Optind' is
+set to one, since there's no reason to look at the program name, which
+is in `ARGV[0]':
+
+ BEGIN {
+ Opterr = 1 # default is to diagnose
+ Optind = 1 # skip ARGV[0]
+
+ # test program
+ if (_getopt_test) {
+ while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
+ printf("c = <%c>, optarg = <%s>\n",
+ _go_c, Optarg)
+ printf("non-option arguments:\n")
+ for (; Optind < ARGC; Optind++)
+ printf("\tARGV[%d] = <%s>\n",
+ Optind, ARGV[Optind])
+ }
+ }
+
+The rest of the `BEGIN' rule is a simple test program. Here is the
+result of two sample runs of the test program:
+
+ $ awk -f getopt.awk -v _getopt_test=1 -- -a -cbARG bax -x
+ -| c = <a>, optarg = <>
+ -| c = <c>, optarg = <>
+ -| c = <b>, optarg = <ARG>
+ -| non-option arguments:
+ -| ARGV[3] = <bax>
+ -| ARGV[4] = <-x>
+
+ $ awk -f getopt.awk -v _getopt_test=1 -- -a -x -- xyz abc
+ -| c = <a>, optarg = <>
+ error--> x -- invalid option
+ -| c = <?>, optarg = <>
+ -| non-option arguments:
+ -| ARGV[4] = <xyz>
+ -| ARGV[5] = <abc>
+
+In both runs, the first `--' terminates the arguments to `awk', so that
+it does not try to interpret the `-a', etc., as its own options.
+Several of the sample programs presented in *Note Sample Programs::,
+use `getopt' to process their arguments.
+
+---------- Footnotes ----------
+
+(1) This function was written before `gawk' acquired the ability to
+split strings into single characters using `""' as the separator. We
+have left it alone, since using `substr' is more portable.
+
+\1f
+File: gawk.info, Node: Passwd Functions, Next: Group Functions, Prev: Getopt Function, Up: Library Functions
+
+12.5 Reading the User Database
+==============================
+
+The `PROCINFO' array (*note Built-in Variables::) provides access to
+the current user's real and effective user and group ID numbers, and if
+available, the user's supplementary group set. However, because these
+are numbers, they do not provide very useful information to the average
+user. There needs to be some way to find the user information
+associated with the user and group ID numbers. This minor node
+presents a suite of functions for retrieving information from the user
+database. *Note Group Functions::, for a similar suite that retrieves
+information from the group database.
+
+The POSIX standard does not define the file where user information is
+kept. Instead, it provides the `<pwd.h>' header file and several C
+language subroutines for obtaining user information. The primary
+function is `getpwent', for "get password entry." The "password" comes
+from the original user database file, `/etc/passwd', which stores user
+information, along with the encrypted passwords (hence the name).
+
+While an `awk' program could simply read `/etc/passwd' directly, this
+file may not contain complete information about the system's set of
+users.(1) To be sure you are able to produce a readable and complete
+version of the user database, it is necessary to write a small C
+program that calls `getpwent'. `getpwent' is defined as returning a
+pointer to a `struct passwd'. Each time it is called, it returns the
+next entry in the database. When there are no more entries, it returns
+`NULL', the null pointer. When this happens, the C program should call
+`endpwent' to close the database. Following is `pwcat', a C program
+that "cats" the password database:
+
+ /*
+ * pwcat.c
+ *
+ * Generate a printable version of the password database
+ */
+ #include <stdio.h>
+ #include <pwd.h>
+
+ int
+ main(argc, argv)
+ int argc;
+ char **argv;
+ {
+ struct passwd *p;
+
+ while ((p = getpwent()) != NULL)
+ 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);
+
+ endpwent();
+ return 0;
+ }
+
+If you don't understand C, don't worry about it. The output from
+`pwcat' is the user database, in the traditional `/etc/passwd' format
+of colon-separated fields. The fields are:
+
+Login name The user's login name.
+Encrypted password The user's encrypted password. This may not be
+ available on some systems.
+User-ID The user's numeric user ID number.
+Group-ID The user's numeric group ID number.
+Full name The user's full name, and perhaps other
+ information associated with the user.
+Home directory The user's login (or "home") directory
+ (familiar to shell programmers as `$HOME').
+Login shell The program that is run when the user logs in.
+ This is usually a shell, such as `bash'.
+
+A few lines representative of `pwcat''s output are as follows:
+
+ $ pwcat
+ -| root:3Ov02d5VaUPB6:0:1:Operator:/:/bin/sh
+ -| nobody:*:65534:65534::/:
+ -| daemon:*:1:1::/:
+ -| sys:*:2:2::/:/bin/csh
+ -| bin:*:3:3::/bin:
+ -| arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/sh
+ -| miriam:yxaay:112:10:Miriam Robbins:/home/miriam:/bin/sh
+ -| andy:abcca2:113:10:Andy Jacobs:/home/andy:/bin/sh
+ ...
+
+With that introduction, following is a group of functions for getting
+user information. There are several functions here, corresponding to
+the C functions of the same names:
+
+ # passwd.awk --- access password file information
+ BEGIN {
+ # tailor this to suit your system
+ _pw_awklib = "/usr/local/libexec/awk/"
+ }
+
+ function _pw_init( oldfs, oldrs, olddol0, pwcat, using_fw)
+ {
+ if (_pw_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ FS = ":"
+ RS = "\n"
+
+ pwcat = _pw_awklib "pwcat"
+ while ((pwcat | getline) > 0) {
+ _pw_byname[$1] = $0
+ _pw_byuid[$3] = $0
+ _pw_bycount[++_pw_total] = $0
+ }
+ close(pwcat)
+ _pw_count = 0
+ _pw_inited = 1
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+ }
+
+The `BEGIN' rule sets a private variable to the directory where `pwcat'
+is stored. Because it is used to help out an `awk' library routine, we
+have chosen to put it in `/usr/local/libexec/awk'; however, you might
+want it to be in a different directory on your system.
+
+The function `_pw_init' keeps three copies of the user information in
+three associative arrays. The arrays are indexed by username
+(`_pw_byname'), by user ID number (`_pw_byuid'), and by order of
+occurrence (`_pw_bycount'). The variable `_pw_inited' is used for
+efficiency; `_pw_init' needs only to be called once.
+
+Because this function uses `getline' to read information from `pwcat',
+it first saves the values of `FS', `RS', and `$0'. It notes in the
+variable `using_fw' whether field splitting with `FIELDWIDTHS' is in
+effect or not. Doing so is necessary, since these functions could be
+called from anywhere within a user's program, and the user may have his
+or her own way of splitting records and fields.
+
+The `using_fw' variable checks `PROCINFO["FS"]', which is
+`"FIELDWIDTHS"' if field splitting is being done with `FIELDWIDTHS'.
+This makes it possible to restore the correct field-splitting mechanism
+later. The test can only be true for `gawk'. It is false if using
+`FS' or on some other `awk' implementation.
+
+The main part of the function uses a loop to read database lines, split
+the line into fields, and then store the line into each array as
+necessary. When the loop is done, `_pw_init' cleans up by closing the
+pipeline, setting `_pw_inited' to one, and restoring `FS' (and
+`FIELDWIDTHS' if necessary), `RS', and `$0'. The use of `_pw_count' is
+explained shortly.
+
+The `getpwnam' function takes a username as a string argument. If that
+user is in the database, it returns the appropriate line. Otherwise, it
+returns the null string:
+
+ function getpwnam(name)
+ {
+ _pw_init()
+ if (name in _pw_byname)
+ return _pw_byname[name]
+ return ""
+ }
+
+Similarly, the `getpwuid' function takes a user ID number argument. If
+that user number is in the database, it returns the appropriate line.
+Otherwise, it returns the null string:
+
+ function getpwuid(uid)
+ {
+ _pw_init()
+ if (uid in _pw_byuid)
+ return _pw_byuid[uid]
+ return ""
+ }
+
+The `getpwent' function simply steps through the database, one entry at
+a time. It uses `_pw_count' to track its current position in the
+`_pw_bycount' array:
+
+ function getpwent()
+ {
+ _pw_init()
+ if (_pw_count < _pw_total)
+ return _pw_bycount[++_pw_count]
+ return ""
+ }
+
+The `endpwent' function resets `_pw_count' to zero, so that subsequent
+calls to `getpwent' start over again:
+
+ function endpwent()
+ {
+ _pw_count = 0
+ }
+
+A conscious design decision in this suite was made that each subroutine
+calls `_pw_init' to initialize the database arrays. The overhead of
+running a separate process to generate the user database, and the I/O
+to scan it, are only incurred if the user's main program actually calls
+one of these functions. If this library file is loaded along with a
+user's program, but none of the routines are ever called, then there is
+no extra runtime overhead. (The alternative is move the body of
+`_pw_init' into a `BEGIN' rule, which always runs `pwcat'. This
+simplifies the code but runs an extra process that may never be needed.)
+
+In turn, calling `_pw_init' is not too expensive, because the
+`_pw_inited' variable keeps the program from reading the data more than
+once. If you are worried about squeezing every last cycle out of your
+`awk' program, the check of `_pw_inited' could be moved out of
+`_pw_init' and duplicated in all the other functions. In practice,
+this is not necessary, since most `awk' programs are I/O-bound, and it
+clutters up the code.
+
+The `id' program in *Note Id Program::, uses these functions.
+
+---------- Footnotes ----------
+
+(1) It is often the case that password information is stored in a
+network database.
+
+\1f
+File: gawk.info, Node: Group Functions, Prev: Passwd Functions, Up: Library Functions
+
+12.6 Reading the Group Database
+===============================
+
+Much of the discussion presented in *Note Passwd Functions::, applies
+to the group database as well. Although there has traditionally been a
+well-known file (`/etc/group') in a well-known format, the POSIX
+standard only provides a set of C library routines (`<grp.h>' and
+`getgrent') for accessing the information. Even though this file may
+exist, it likely does not have complete information. Therefore, as
+with the user database, it is necessary to have a small C program that
+generates the group database as its output.
+
+`grcat', a C program that "cats" the group database, is as follows:
+
+ /*
+ * grcat.c
+ *
+ * Generate a printable version of the group database
+ */
+ #include <stdio.h>
+ #include <grp.h>
+
+ int
+ main(argc, argv)
+ int argc;
+ char **argv;
+ {
+ struct group *g;
+ int i;
+
+ while ((g = getgrent()) != NULL) {
+ printf("%s:%s:%ld:", g->gr_name, g->gr_passwd,
+ (long) g->gr_gid);
+ for (i = 0; g->gr_mem[i] != NULL; i++) {
+ printf("%s", g->gr_mem[i]);
+ if (g->gr_mem[i+1] != NULL)
+ putchar(',');
+ }
+ putchar('\n');
+ }
+ endgrent();
+ return 0;
+ }
+
+Each line in the group database represents one group. The fields are
+separated with colons and represent the following information:
+
+Group name The group's name.
+Group password The group's encrypted password. In practice,
+ this field is never used; it is usually empty
+ or set to `*'.
+Group-ID The group's numeric group ID number; this
+ number should be unique within the file.
+Group member list A comma-separated list of usernames. These
+ users are members of the group. Modern Unix
+ systems allow users to be members of several
+ groups simultaneously. If your system does,
+ then there are elements `"group1"' through
+ `"groupN"' in `PROCINFO' for those group ID
+ numbers. (Note that `PROCINFO' is a `gawk'
+ extension; *note Built-in Variables::.)
+
+Here is what running `grcat' might produce:
+
+ $ grcat
+ -| wheel:*:0:arnold
+ -| nogroup:*:65534:
+ -| daemon:*:1:
+ -| kmem:*:2:
+ -| staff:*:10:arnold,miriam,andy
+ -| other:*:20:
+ ...
+
+Here are the functions for obtaining information from the group
+database. There are several, modeled after the C library functions of
+the same names:
+
+ # group.awk --- functions for dealing with the group file
+ BEGIN \
+ {
+ # Change to suit your system
+ _gr_awklib = "/usr/local/libexec/awk/"
+ }
+
+ function _gr_init( oldfs, oldrs, olddol0, grcat,
+ using_fw, n, a, i)
+ {
+ if (_gr_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ 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_count] = $0
+ }
+ close(grcat)
+ _gr_count = 0
+ _gr_inited++
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+ }
+
+The `BEGIN' rule sets a private variable to the directory where `grcat'
+is stored. Because it is used to help out an `awk' library routine, we
+have chosen to put it in `/usr/local/libexec/awk'. You might want it
+to be in a different directory on your system.
+
+These routines follow the same general outline as the user database
+routines (*note Passwd Functions::). The `_gr_inited' variable is used
+to ensure that the database is scanned no more than once. The
+`_gr_init' function first saves `FS', `FIELDWIDTHS', `RS', and `$0',
+and then sets `FS' and `RS' to the correct values for scanning the
+group information.
+
+The group information is stored is several associative arrays. The
+arrays are indexed by group name (`_gr_byname'), by group ID number
+(`_gr_bygid'), and by position in the database (`_gr_bycount'). There
+is an additional array indexed by username (`_gr_groupsbyuser'), which
+is a space-separated list of groups to which each user belongs.
+
+Unlike the user database, it is possible to have multiple records in the
+database for the same group. This is common when a group has a large
+number of members. A pair of such entries might look like the
+following:
+
+ tvpeople:*:101:johnny,jay,arsenio
+ tvpeople:*:101:david,conan,tom,joan
+
+For this reason, `_gr_init' looks to see if a group name or group ID
+number is already seen. If it is, then the usernames are simply
+concatenated onto the previous list of users. (There is actually a
+subtle problem with the code just presented. Suppose that the first
+time there were no names. This code adds the names with a leading
+comma. It also doesn't check that there is a `$4'.)
+
+Finally, `_gr_init' closes the pipeline to `grcat', restores `FS' (and
+`FIELDWIDTHS' if necessary), `RS', and `$0', initializes `_gr_count' to
+zero (it is used later), and makes `_gr_inited' nonzero.
+
+The `getgrnam' function takes a group name as its argument, and if that
+group exists, it is returned. Otherwise, `getgrnam' returns the null
+string:
+
+ function getgrnam(group)
+ {
+ _gr_init()
+ if (group in _gr_byname)
+ return _gr_byname[group]
+ return ""
+ }
+
+The `getgrgid' function is similar, it takes a numeric group ID and
+looks up the information associated with that group ID:
+
+ function getgrgid(gid)
+ {
+ _gr_init()
+ if (gid in _gr_bygid)
+ return _gr_bygid[gid]
+ return ""
+ }
+
+The `getgruser' function does not have a C counterpart. It takes a
+username and returns the list of groups that have the user as a member:
+
+ function getgruser(user)
+ {
+ _gr_init()
+ if (user in _gr_groupsbyuser)
+ return _gr_groupsbyuser[user]
+ return ""
+ }
+
+The `getgrent' function steps through the database one entry at a time.
+It uses `_gr_count' to track its position in the list:
+
+ function getgrent()
+ {
+ _gr_init()
+ if (++_gr_count in _gr_bycount)
+ return _gr_bycount[_gr_count]
+ return ""
+ }
+
+The `endgrent' function resets `_gr_count' to zero so that `getgrent'
+can start over again:
+
+ function endgrent()
+ {
+ _gr_count = 0
+ }
+
+As with the user database routines, each function calls `_gr_init' to
+initialize the arrays. Doing so only incurs the extra overhead of
+running `grcat' if these functions are used (as opposed to moving the
+body of `_gr_init' into a `BEGIN' rule).
+
+Most of the work is in scanning the database and building the various
+associative arrays. The functions that the user calls are themselves
+very simple, relying on `awk''s associative arrays to do work.
+
+The `id' program in *Note Id Program::, uses these functions.
+
+\1f
+File: gawk.info, Node: Sample Programs, Next: Language History, Prev: Library Functions, Up: Top
+
+13 Practical `awk' Programs
+***************************
+
+*Note Library Functions::, presents the idea that reading programs in a
+language contributes to learning that language. This major node
+continues that theme, presenting a potpourri of `awk' programs for your
+reading enjoyment.
+
+Many of these programs use the library functions presented in *Note
+Library Functions::.
+
+* Menu:
+
+* Running Examples:: How to run these examples.
+* Clones:: Clones of common utilities.
+* Miscellaneous Programs:: Some interesting `awk' programs.
+
+\1f
+File: gawk.info, Node: Running Examples, Next: Clones, Up: Sample Programs
+
+13.1 Running the Example Programs
+=================================
+
+To run a given program, you would typically do something like this:
+
+ awk -f PROGRAM -- OPTIONS FILES
+
+Here, PROGRAM is the name of the `awk' program (such as `cut.awk'),
+OPTIONS are any command-line options for the program that start with a
+`-', and FILES are the actual data files.
+
+If your system supports the `#!' executable interpreter mechanism
+(*note Executable Scripts::), you can instead run your program directly:
+
+ cut.awk -c1-8 myfiles > results
+
+If your `awk' is not `gawk', you may instead need to use this:
+
+ cut.awk -- -c1-8 myfiles > results
+
+\1f
+File: gawk.info, Node: Clones, Next: Miscellaneous Programs, Prev: Running Examples, Up: Sample Programs
+
+13.2 Reinventing Wheels for Fun and Profit
+==========================================
+
+This minor node presents a number of POSIX utilities that are
+implemented in `awk'. Reinventing these programs in `awk' is often
+enjoyable, because the algorithms can be very clearly expressed, and
+the code is usually very concise and simple. This is true because
+`awk' does so much for you.
+
+It should be noted that these programs are not necessarily intended to
+replace the installed versions on your system. Instead, their purpose
+is to illustrate `awk' language programming for "real world" tasks.
+
+The programs are presented in alphabetical order.
+
+* Menu:
+
+* Cut Program:: The `cut' utility.
+* Egrep Program:: The `egrep' utility.
+* Id Program:: The `id' utility.
+* Split Program:: The `split' utility.
+* Tee Program:: The `tee' utility.
+* Uniq Program:: The `uniq' utility.
+* Wc Program:: The `wc' utility.
+
+\1f
+File: gawk.info, Node: Cut Program, Next: Egrep Program, Up: Clones
+
+13.2.1 Cutting out Fields and Columns
+-------------------------------------
+
+The `cut' utility selects, or "cuts," characters or fields from its
+standard input and sends them to its standard output. Fields are
+separated by tabs by default, but you may supply a command-line option
+to change the field "delimiter" (i.e., the field-separator character).
+`cut''s definition of fields is less general than `awk''s.
+
+A common use of `cut' might be to pull out just the login name of
+logged-on users from the output of `who'. For example, the following
+pipeline generates a sorted, unique list of the logged-on users:
+
+ who | cut -c1-8 | sort | uniq
+
+The options for `cut' are:
+
+`-c LIST'
+ Use LIST as the list of characters to cut out. Items within the
+ list may be separated by commas, and ranges of characters can be
+ separated with dashes. The list `1-8,15,22-35' specifies
+ characters 1 through 8, 15, and 22 through 35.
+
+`-f LIST'
+ Use LIST as the list of fields to cut out.
+
+`-d DELIM'
+ Use DELIM as the field-separator character instead of the tab
+ character.
+
+`-s'
+ Suppress printing of lines that do not contain the field delimiter.
+
+The `awk' implementation of `cut' uses the `getopt' library function
+(*note Getopt Function::) and the `join' library function (*note Join
+Function::).
+
+The program begins with a comment describing the options, the library
+functions needed, and a `usage' function that prints out a usage
+message and exits. `usage' is called if invalid arguments are supplied:
+
+ # cut.awk --- implement cut in awk
+ # Options:
+ # -f list Cut fields
+ # -d c Field delimiter character
+ # -c list Cut characters
+ #
+ # -s Suppress lines without the delimiter
+ #
+ # Requires getopt and join library functions
+
+ function usage( e1, e2)
+ {
+ e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
+ e2 = "usage: cut [-c list] [files...]"
+ print e1 > "/dev/stderr"
+ print e2 > "/dev/stderr"
+ exit 1
+ }
+
+The variables `e1' and `e2' are used so that the function fits nicely
+on the screen.
+
+Next comes a `BEGIN' rule that parses the command-line options. It
+sets `FS' to a single TAB character, because that is `cut''s default
+field separator. The output field separator is also set to be the same
+as the input field separator. Then `getopt' is used to step through
+the command-line options. Exactly one of the variables `by_fields' or
+`by_chars' is set to true, to indicate that processing should be done
+by fields or by characters, respectively. When cutting by characters,
+the output field separator is set to the null string:
+
+ BEGIN \
+ {
+ FS = "\t" # default
+ OFS = FS
+ while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) {
+ if (c == "f") {
+ by_fields = 1
+ fieldlist = Optarg
+ } else if (c == "c") {
+ by_chars = 1
+ fieldlist = Optarg
+ OFS = ""
+ } else if (c == "d") {
+ if (length(Optarg) > 1) {
+ printf("Using first character of %s" \
+ " for delimiter\n", Optarg) > "/dev/stderr"
+ Optarg = substr(Optarg, 1, 1)
+ }
+ FS = Optarg
+ OFS = FS
+ if (FS == " ") # defeat awk semantics
+ FS = "[ ]"
+ } else if (c == "s")
+ suppress++
+ else
+ usage()
+ }
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+Special care is taken when the field delimiter is a space. Using a
+single space (`" "') for the value of `FS' is incorrect--`awk' would
+separate fields with runs of spaces, tabs, and/or newlines, and we want
+them to be separated with individual spaces. Also, note that after
+`getopt' is through, we have to clear out all the elements of `ARGV'
+from 1 to `Optind', so that `awk' does not try to process the
+command-line options as file names.
+
+After dealing with the command-line options, the program verifies that
+the options make sense. Only one or the other of `-c' and `-f' should
+be used, and both require a field list. Then the program calls either
+`set_fieldlist' or `set_charlist' to pull apart the list of fields or
+characters:
+
+ if (by_fields && by_chars)
+ usage()
+
+ if (by_fields == 0 && by_chars == 0)
+ by_fields = 1 # default
+
+ if (fieldlist == "") {
+ print "cut: needs list for -c or -f" > "/dev/stderr"
+ exit 1
+ }
+
+ if (by_fields)
+ set_fieldlist()
+ else
+ set_charlist()
+ }
+
+`set_fieldlist' is used to split the field list apart at the commas
+and into an array. Then, for each element of the array, it looks to
+see if it is actually a range, and if so, splits it apart. The range is
+verified to make sure the first number is smaller than the second.
+Each number in the list is added to the `flist' array, which simply
+lists the fields that will be printed. Normal field splitting is used.
+The program lets `awk' handle the job of doing the field splitting:
+
+ function set_fieldlist( n, m, i, j, k, f, g)
+ {
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) {
+ if (index(f[i], "-") != 0) { # a range
+ m = split(f[i], g, "-")
+ if (m != 2 || g[1] >= g[2]) {
+ printf("bad field list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ }
+ for (k = g[1]; k <= g[2]; k++)
+ flist[j++] = k
+ } else
+ flist[j++] = f[i]
+ }
+ nfields = j - 1
+ }
+
+The `set_charlist' function is more complicated than `set_fieldlist'.
+The idea here is to use `gawk''s `FIELDWIDTHS' variable (*note Constant
+Size::), which describes constant-width input. When using a character
+list, that is exactly what we have.
+
+Setting up `FIELDWIDTHS' is more complicated than simply listing the
+fields that need to be printed. We have to keep track of the fields to
+print and also the intervening characters that have to be skipped. For
+example, suppose you wanted characters 1 through 8, 15, and 22 through
+35. You would use `-c 1-8,15,22-35'. The necessary value for
+`FIELDWIDTHS' is `"8 6 1 6 14"'. This yields five fields, and the
+fields to print are `$1', `$3', and `$5'. The intermediate fields are
+"filler", which is stuff in between the desired data. `flist' lists
+the fields to print, and `t' tracks the complete field list, including
+filler fields:
+
+ function set_charlist( field, i, j, f, g, t,
+ filler, last, len)
+ {
+ field = 1 # count total fields
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) {
+ if (index(f[i], "-") != 0) { # range
+ m = split(f[i], g, "-")
+ if (m != 2 || g[1] >= g[2]) {
+ printf("bad character list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ }
+ len = g[2] - g[1] + 1
+ if (g[1] > 1) # compute length of filler
+ filler = g[1] - last - 1
+ else
+ filler = 0
+ if (filler)
+ t[field++] = filler
+ t[field++] = len # length of field
+ last = g[2]
+ flist[j++] = field - 1
+ } else {
+ if (f[i] > 1)
+ filler = f[i] - last - 1
+ else
+ filler = 0
+ if (filler)
+ t[field++] = filler
+ t[field++] = 1
+ last = f[i]
+ flist[j++] = field - 1
+ }
+ }
+ FIELDWIDTHS = join(t, 1, field - 1)
+ nfields = j - 1
+ }
+
+Next is the rule that actually processes the data. If the `-s' option
+is given, then `suppress' is true. The first `if' statement makes sure
+that the input record does have the field separator. If `cut' is
+processing fields, `suppress' is true, and the field separator
+character is not in the record, then the record is skipped.
+
+If the record is valid, then `gawk' has split the data into fields,
+either using the character in `FS' or using fixed-length fields and
+`FIELDWIDTHS'. The loop goes through the list of fields that should be
+printed. The corresponding field is printed if it contains data. If
+the next field also has data, then the separator character is written
+out between the fields:
+
+ {
+ if (by_fields && suppress && index($0, FS) != 0)
+ next
+
+ for (i = 1; i <= nfields; i++) {
+ if ($flist[i] != "") {
+ printf "%s", $flist[i]
+ if (i < nfields && $flist[i+1] != "")
+ printf "%s", OFS
+ }
+ }
+ print ""
+ }
+
+This version of `cut' relies on `gawk''s `FIELDWIDTHS' variable to do
+the character-based cutting. While it is possible in other `awk'
+implementations to use `substr' (*note String Functions::), it is also
+extremely painful. The `FIELDWIDTHS' variable supplies an elegant
+solution to the problem of picking the input line apart by characters.
+
+\1f
+File: gawk.info, Node: Egrep Program, Next: Id Program, Prev: Cut Program, Up: Clones
+
+13.2.2 Searching for Regular Expressions in Files
+-------------------------------------------------
+
+The `egrep' utility searches files for patterns. It uses regular
+expressions that are almost identical to those available in `awk'
+(*note Regexp::). It is used in the following manner:
+
+ egrep [ OPTIONS ] 'PATTERN' FILES ...
+
+The PATTERN is a regular expression. In typical usage, the regular
+expression is quoted to prevent the shell from expanding any of the
+special characters as file name wildcards. Normally, `egrep' prints
+the lines that matched. If multiple file names are provided on the
+command line, each output line is preceded by the name of the file and
+a colon.
+
+The options to `egrep' are as follows:
+
+`-c'
+ Print out a count of the lines that matched the pattern, instead
+ of the lines themselves.
+
+`-s'
+ Be silent. No output is produced and the exit value indicates
+ whether the pattern was matched.
+
+`-v'
+ Invert the sense of the test. `egrep' prints the lines that do
+ _not_ match the pattern and exits successfully if the pattern is
+ not matched.
+
+`-i'
+ Ignore case distinctions in both the pattern and the input data.
+
+`-l'
+ Only print (list) the names of the files that matched, not the
+ lines that matched.
+
+`-e PATTERN'
+ Use PATTERN as the regexp to match. The purpose of the `-e'
+ option is to allow patterns that start with a `-'.
+
+This version uses the `getopt' library function (*note Getopt
+Function::) and the file transition library program (*note Filetrans
+Function::).
+
+The program begins with a descriptive comment and then a `BEGIN' rule
+that processes the command-line arguments with `getopt'. The `-i'
+(ignore case) option is particularly easy with `gawk'; we just use the
+`IGNORECASE' built-in variable (*note Built-in Variables::):
+
+ # egrep.awk --- simulate egrep in awk
+ # Options:
+ # -c count of lines
+ # -s silent - use exit value
+ # -v invert test, success if no match
+ # -i ignore case
+ # -l print filenames only
+ # -e argument is pattern
+ #
+ # Requires getopt and file transition library functions
+
+ BEGIN {
+ while ((c = getopt(ARGC, ARGV, "ce:svil")) != -1) {
+ if (c == "c")
+ count_only++
+ else if (c == "s")
+ no_print++
+ else if (c == "v")
+ invert++
+ else if (c == "i")
+ IGNORECASE = 1
+ else if (c == "l")
+ filenames_only++
+ else if (c == "e")
+ pattern = Optarg
+ else
+ usage()
+ }
+
+Next comes the code that handles the `egrep'-specific behavior. If no
+pattern is supplied with `-e', the first nonoption on the command line
+is used. The `awk' command-line arguments up to `ARGV[Optind]' are
+cleared, so that `awk' won't try to process them as files. If no files
+are specified, the standard input is used, and if multiple files are
+specified, we make sure to note this so that the file names can precede
+the matched lines in the output:
+
+ if (pattern == "")
+ pattern = ARGV[Optind++]
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+ if (Optind >= ARGC) {
+ ARGV[1] = "-"
+ ARGC = 2
+ } else if (ARGC - Optind > 1)
+ do_filenames++
+
+ # if (IGNORECASE)
+ # pattern = tolower(pattern)
+ }
+
+The last two lines are commented out, since they are not needed in
+`gawk'. They should be uncommented if you have to use another version
+of `awk'.
+
+The next set of lines should be uncommented if you are not using
+`gawk'. This rule translates all the characters in the input line into
+lowercase if the `-i' option is specified.(1) The rule is commented out
+since it is not necessary with `gawk':
+
+ #{
+ # if (IGNORECASE)
+ # $0 = tolower($0)
+ #}
+
+The `beginfile' function is called by the rule in `ftrans.awk' when
+each new file is processed. In this case, it is very simple; all it
+does is initialize a variable `fcount' to zero. `fcount' tracks how
+many lines in the current file matched the pattern (naming the
+parameter `junk' shows we know that `beginfile' is called with a
+parameter, but that we're not interested in its value):
+
+ function beginfile(junk)
+ {
+ fcount = 0
+ }
+
+The `endfile' function is called after each file has been processed.
+It affects the output only when the user wants a count of the number of
+lines that matched. `no_print' is true only if the exit status is
+desired. `count_only' is true if line counts are desired. `egrep'
+therefore only prints line counts if printing and counting are enabled.
+The output format must be adjusted depending upon the number of files to
+process. Finally, `fcount' is added to `total', so that we know the
+total number of lines that matched the pattern:
+
+ function endfile(file)
+ {
+ if (! no_print && count_only)
+ if (do_filenames)
+ print file ":" fcount
+ else
+ print fcount
+
+ total += fcount
+ }
+
+The following rule does most of the work of matching lines. The variable
+`matches' is true if the line matched the pattern. If the user wants
+lines that did not match, the sense of `matches' is inverted using the
+`!' operator. `fcount' is incremented with the value of `matches',
+which is either one or zero, depending upon a successful or
+unsuccessful match. If the line does not match, the `next' statement
+just moves on to the next record.
+
+A number of additional tests are made, but they are only done if we are
+not counting lines. First, if the user only wants exit status
+(`no_print' is true), then it is enough to know that _one_ line in this
+file matched, and we can skip on to the next file with `nextfile'.
+Similarly, if we are only printing file names, we can print the file
+name, and then skip to the next file with `nextfile'. Finally, each
+line is printed, with a leading file name and colon if necessary:
+
+ {
+ matches = ($0 ~ pattern)
+ if (invert)
+ matches = ! matches
+
+ fcount += matches # 1 or 0
+
+ if (! matches)
+ next
+
+ if (! count_only) {
+ if (no_print)
+ nextfile
+
+ if (filenames_only) {
+ print FILENAME
+ nextfile
+ }
+
+ if (do_filenames)
+ print FILENAME ":" $0
+ else
+ print
+ }
+ }
+
+The `END' rule takes care of producing the correct exit status. If
+there are no matches, the exit status is one; otherwise it is zero:
+
+ END \
+ {
+ if (total == 0)
+ exit 1
+ exit 0
+ }
+
+The `usage' function prints a usage message in case of invalid options,
+and then exits:
+
+ function usage( e)
+ {
+ e = "Usage: egrep [-csvil] [-e pat] [files ...]"
+ e = e "\n\tegrep [-csvil] pat [files ...]"
+ print e > "/dev/stderr"
+ exit 1
+ }
+
+The variable `e' is used so that the function fits nicely on the
+printed page.
+
+Just a note on programming style: you may have noticed that the `END'
+rule uses backslash continuation, with the open brace on a line by
+itself. This is so that it more closely resembles the way functions
+are written. Many of the examples in this major node use this style.
+You can decide for yourself if you like writing your `BEGIN' and `END'
+rules this way or not.
+
+---------- Footnotes ----------
+
+(1) It also introduces a subtle bug; if a match happens, we output the
+translated line, not the original.
+
+\1f
+File: gawk.info, Node: Id Program, Next: Split Program, Prev: Egrep Program, Up: Clones
+
+13.2.3 Printing out User Information
+------------------------------------
+
+The `id' utility lists a user's real and effective user ID numbers,
+real and effective group ID numbers, and the user's group set, if any.
+`id' only prints the effective user ID and group ID if they are
+different from the real ones. If possible, `id' also supplies the
+corresponding user and group names. The output might look like this:
+
+ $ id
+ -| uid=2076(arnold) gid=10(staff) groups=10(staff),4(tty)
+
+This information is part of what is provided by `gawk''s `PROCINFO'
+array (*note Built-in Variables::). However, the `id' utility provides
+a more palatable output than just individual numbers.
+
+Here is a simple version of `id' written in `awk'. It uses the user
+database library functions (*note Passwd Functions::) and the group
+database library functions (*note Group Functions::):
+
+The program is fairly straightforward. All the work is done in the
+`BEGIN' rule. The user and group ID numbers are obtained from
+`PROCINFO'. The code is repetitive. The entry in the user database
+for the real user ID number is split into parts at the `:'. The name is
+the first field. Similar code is used for the effective user ID number
+and the group numbers:
+
+ # id.awk --- implement id in awk
+ #
+ # Requires user and group library functions
+ # output is:
+ # uid=12(foo) euid=34(bar) gid=3(baz) \
+ # egid=5(blat) groups=9(nine),2(two),1(one)
+
+ BEGIN \
+ {
+ uid = PROCINFO["uid"]
+ euid = PROCINFO["euid"]
+ gid = PROCINFO["gid"]
+ egid = PROCINFO["egid"]
+
+ printf("uid=%d", uid)
+ pw = getpwuid(uid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+
+ if (euid != uid) {
+ printf(" euid=%d", euid)
+ pw = getpwuid(euid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ }
+
+ printf(" gid=%d", gid)
+ pw = getgrgid(gid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+
+ if (egid != gid) {
+ printf(" egid=%d", egid)
+ pw = getgrgid(egid)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ }
+
+ for (i = 1; ("group" i) in PROCINFO; i++) {
+ if (i == 1)
+ printf(" groups=")
+ group = PROCINFO["group" i]
+ printf("%d", group)
+ pw = getgrgid(group)
+ if (pw != "") {
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ }
+ if (("group" (i+1)) in PROCINFO)
+ printf(",")
+ }
+
+ print ""
+ }
+
+The test in the `for' loop is worth noting. Any supplementary groups
+in the `PROCINFO' array have the indices `"group1"' through `"groupN"'
+for some N, i.e., the total number of supplementary groups. However,
+we don't know in advance how many of these groups there are.
+
+This loop works by starting at one, concatenating the value with
+`"group"', and then using `in' to see if that value is in the array.
+Eventually, `i' is incremented past the last group in the array and the
+loop exits.
+
+The loop is also correct if there are _no_ supplementary groups; then
+the condition is false the first time it's tested, and the loop body
+never executes.
+
+\1f
+File: gawk.info, Node: Split Program, Next: Tee Program, Prev: Id Program, Up: Clones
+
+13.2.4 Splitting a Large File into Pieces
+-----------------------------------------
+
+The `split' program splits large text files into smaller pieces. Usage
+is as follows:
+
+ split [-COUNT] file [ PREFIX ]
+
+By default, the output files are named `xaa', `xab', and so on. Each
+file has 1000 lines in it, with the likely exception of the last file.
+To change the number of lines in each file, supply a number on the
+command line preceded with a minus; e.g., `-500' for files with 500
+lines in them instead of 1000. To change the name of the output files
+to something like `myfileaa', `myfileab', and so on, supply an
+additional argument that specifies the file name prefix.
+
+Here is a version of `split' in `awk'. It uses the `ord' and `chr'
+functions presented in *Note Ordinal Functions::.
+
+The program first sets its defaults, and then tests to make sure there
+are not too many arguments. It then looks at each argument in turn.
+The first argument could be a minus sign followed by a number. If it
+is, this happens to look like a negative number, so it is made
+positive, and that is the count of lines. The data file name is
+skipped over and the final argument is used as the prefix for the
+output file names:
+
+ # split.awk --- do split in awk
+ #
+ # Requires ord and chr library functions
+ # usage: split [-num] [file] [outname]
+
+ BEGIN {
+ outfile = "x" # default
+ count = 1000
+ if (ARGC > 4)
+ usage()
+
+ i = 1
+ if (ARGV[i] ~ /^-[0-9]+$/) {
+ count = -ARGV[i]
+ ARGV[i] = ""
+ i++
+ }
+ # test argv in case reading from stdin instead of file
+ if (i in ARGV)
+ i++ # skip data file name
+ if (i in ARGV) {
+ outfile = ARGV[i]
+ ARGV[i] = ""
+ }
+
+ s1 = s2 = "a"
+ out = (outfile s1 s2)
+ }
+
+The next rule does most of the work. `tcount' (temporary count) tracks
+how many lines have been printed to the output file so far. If it is
+greater than `count', it is time to close the current file and start a
+new one. `s1' and `s2' track the current suffixes for the file name. If
+they are both `z', the file is just too big. Otherwise, `s1' moves to
+the next letter in the alphabet and `s2' starts over again at `a':
+
+ {
+ if (++tcount > count) {
+ close(out)
+ if (s2 == "z") {
+ if (s1 == "z") {
+ printf("split: %s is too large to split\n",
+ FILENAME) > "/dev/stderr"
+ exit 1
+ }
+ s1 = chr(ord(s1) + 1)
+ s2 = "a"
+ }
+ else
+ s2 = chr(ord(s2) + 1)
+ out = (outfile s1 s2)
+ tcount = 1
+ }
+ print > out
+ }
+
+The `usage' function simply prints an error message and exits:
+
+ function usage( e)
+ {
+ e = "usage: split [-num] [file] [outname]"
+ print e > "/dev/stderr"
+ exit 1
+ }
+
+The variable `e' is used so that the function fits nicely on the screen.
+
+This program is a bit sloppy; it relies on `awk' to automatically close
+the last file instead of doing it in an `END' rule. It also assumes
+that letters are contiguous in the character set, which isn't true for
+EBCDIC systems.
+
+\1f
+File: gawk.info, Node: Tee Program, Next: Uniq Program, Prev: Split Program, Up: Clones
+
+13.2.5 Duplicating Output into Multiple Files
+---------------------------------------------
+
+The `tee' program is known as a "pipe fitting." `tee' copies its
+standard input to its standard output and also duplicates it to the
+files named on the command line. Its usage is as follows:
+
+ tee [-a] file ...
+
+The `-a' option tells `tee' to append to the named files, instead of
+truncating them and starting over.
+
+The `BEGIN' rule first makes a copy of all the command-line arguments
+into an array named `copy'. `ARGV[0]' is not copied, since it is not
+needed. `tee' cannot use `ARGV' directly, since `awk' attempts to
+process each file name in `ARGV' as input data.
+
+If the first argument is `-a', then the flag variable `append' is set
+to true, and both `ARGV[1]' and `copy[1]' are deleted. If `ARGC' is
+less than two, then no file names were supplied and `tee' prints a
+usage message and exits. Finally, `awk' is forced to read the standard
+input by setting `ARGV[1]' to `"-"' and `ARGC' to two:
+
+ # tee.awk --- tee in awk
+ BEGIN \
+ {
+ for (i = 1; i < ARGC; i++)
+ copy[i] = ARGV[i]
+
+ if (ARGV[1] == "-a") {
+ append = 1
+ delete ARGV[1]
+ delete copy[1]
+ ARGC--
+ }
+ if (ARGC < 2) {
+ print "usage: tee [-a] file ..." > "/dev/stderr"
+ exit 1
+ }
+ ARGV[1] = "-"
+ ARGC = 2
+ }
+
+The single rule does all the work. Since there is no pattern, it is
+executed for each line of input. The body of the rule simply prints the
+line into each file on the command line, and then to the standard
+output:
+
+ {
+ # moving the if outside the loop makes it run faster
+ if (append)
+ for (i in copy)
+ print >> copy[i]
+ else
+ for (i in copy)
+ print > copy[i]
+ print
+ }
+
+It is also possible to write the loop this way:
+
+ for (i in copy)
+ if (append)
+ print >> copy[i]
+ else
+ print > copy[i]
+
+This is more concise but it is also less efficient. The `if' is tested
+for each record and for each output file. By duplicating the loop
+body, the `if' is only tested once for each input record. If there are
+N input records and M output files, the first method only executes N
+`if' statements, while the second executes N`*'M `if' statements.
+
+Finally, the `END' rule cleans up by closing all the output files:
+
+ END \
+ {
+ for (i in copy)
+ close(copy[i])
+ }
+
+\1f
+File: gawk.info, Node: Uniq Program, Next: Wc Program, Prev: Tee Program, Up: Clones
+
+13.2.6 Printing Nonduplicated Lines of Text
+-------------------------------------------
+
+The `uniq' utility reads sorted lines of data on its standard input,
+and by default removes duplicate lines. In other words, it only prints
+unique lines--hence the name. `uniq' has a number of options. The
+usage is as follows:
+
+ uniq [-udc [-N]] [+N] [ INPUT FILE [ OUTPUT FILE ]]
+
+The options for `uniq' are:
+
+`-d'
+ Pnly print only repeated lines.
+
+`-u'
+ Print only nonrepeated lines.
+
+`-c'
+ Count lines. This option overrides `-d' and `-u'. Both repeated
+ and nonrepeated lines are counted.
+
+`-N'
+ Skip N fields before comparing lines. The definition of fields is
+ similar to `awk''s default: nonwhitespace characters separated by
+ runs of spaces and/or tabs.
+
+`+N'
+ Skip N characters before comparing lines. Any fields specified
+ with `-N' are skipped first.
+
+`INPUT FILE'
+ Data is read from the input file named on the command line,
+ instead of from the standard input.
+
+`OUTPUT FILE'
+ The generated output is sent to the named output file, instead of
+ to the standard output.
+
+Normally `uniq' behaves as if both the `-d' and `-u' options are
+provided.
+
+`uniq' uses the `getopt' library function (*note Getopt Function::) and
+the `join' library function (*note Join Function::).
+
+The program begins with a `usage' function and then a brief outline of
+the options and their meanings in a comment. The `BEGIN' rule deals
+with the command-line arguments and options. It uses a trick to get
+`getopt' to handle options of the form `-25', treating such an option
+as the option letter `2' with an argument of `5'. If indeed two or more
+digits are supplied (`Optarg' looks like a number), `Optarg' is
+concatenated with the option digit and then the result is added to zero
+to make it into a number. If there is only one digit in the option,
+then `Optarg' is not needed. In this case, `Optind' must be decremented
+so that `getopt' processes it next time. This code is admittedly a bit
+tricky.
+
+If no options are supplied, then the default is taken, to print both
+repeated and nonrepeated lines. The output file, if provided, is
+assigned to `outputfile'. Early on, `outputfile' is initialized to the
+standard output, `/dev/stdout':
+
+ # uniq.awk --- do uniq in awk
+ #
+ # Requires getopt and join library functions
+ function usage( e)
+ {
+ e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
+ print e > "/dev/stderr"
+ exit 1
+ }
+
+ # -c count lines. overrides -d and -u
+ # -d only repeated lines
+ # -u only non-repeated lines
+ # -n skip n fields
+ # +n skip n characters, skip fields first
+
+ BEGIN \
+ {
+ count = 1
+ outputfile = "/dev/stdout"
+ opts = "udc0:1:2:3:4:5:6:7:8:9:"
+ while ((c = getopt(ARGC, ARGV, opts)) != -1) {
+ if (c == "u")
+ non_repeated_only++
+ else if (c == "d")
+ repeated_only++
+ else if (c == "c")
+ do_count++
+ else if (index("0123456789", c) != 0) {
+ # getopt requires args to options
+ # this messes us up for things like -5
+ if (Optarg ~ /^[0-9]+$/)
+ fcount = (c Optarg) + 0
+ else {
+ fcount = c + 0
+ Optind--
+ }
+ } else
+ usage()
+ }
+
+ if (ARGV[Optind] ~ /^\+[0-9]+$/) {
+ charcount = substr(ARGV[Optind], 2) + 0
+ Optind++
+ }
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ if (repeated_only == 0 && non_repeated_only == 0)
+ repeated_only = non_repeated_only = 1
+
+ if (ARGC - Optind == 2) {
+ outputfile = ARGV[ARGC - 1]
+ ARGV[ARGC - 1] = ""
+ }
+ }
+
+The following function, `are_equal', compares the current line, `$0',
+to the previous line, `last'. It handles skipping fields and
+characters. If no field count and no character count are specified,
+`are_equal' simply returns one or zero depending upon the result of a
+simple string comparison of `last' and `$0'. Otherwise, things get more
+complicated. If fields have to be skipped, each line is broken into an
+array using `split' (*note String Functions::); the desired fields are
+then joined back into a line using `join'. The joined lines are stored
+in `clast' and `cline'. If no fields are skipped, `clast' and `cline'
+are set to `last' and `$0', respectively. Finally, if characters are
+skipped, `substr' is used to strip off the leading `charcount'
+characters in `clast' and `cline'. The two strings are then compared
+and `are_equal' returns the result:
+
+ function are_equal( n, m, clast, cline, alast, aline)
+ {
+ if (fcount == 0 && charcount == 0)
+ return (last == $0)
+
+ if (fcount > 0) {
+ n = split(last, alast)
+ m = split($0, aline)
+ clast = join(alast, fcount+1, n)
+ cline = join(aline, fcount+1, m)
+ } else {
+ clast = last
+ cline = $0
+ }
+ if (charcount) {
+ clast = substr(clast, charcount + 1)
+ cline = substr(cline, charcount + 1)
+ }
+
+ return (clast == cline)
+ }
+
+The following two rules are the body of the program. The first one is
+executed only for the very first line of data. It sets `last' equal to
+`$0', so that subsequent lines of text have something to be compared to.
+
+The second rule does the work. The variable `equal' is one or zero,
+depending upon the results of `are_equal''s comparison. If `uniq' is
+counting repeated lines, and the lines are equal, then it increments
+the `count' variable. Otherwise, it prints the line and resets `count',
+since the two lines are not equal.
+
+If `uniq' is not counting, and if the lines are equal, `count' is
+incremented. Nothing is printed, since the point is to remove
+duplicates. Otherwise, if `uniq' is counting repeated lines and more
+than one line is seen, or if `uniq' is counting nonrepeated lines and
+only one line is seen, then the line is printed, and `count' is reset.
+
+Finally, similar logic is used in the `END' rule to print the final
+line of input data:
+
+ NR == 1 {
+ last = $0
+ next
+ }
+
+ {
+ equal = are_equal()
+
+ if (do_count) { # overrides -d and -u
+ if (equal)
+ count++
+ else {
+ printf("%4d %s\n", count, last) > outputfile
+ last = $0
+ count = 1 # reset
+ }
+ next
+ }
+
+ if (equal)
+ count++
+ else {
+ if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+ last = $0
+ count = 1
+ }
+ }
+
+ END {
+ if (do_count)
+ printf("%4d %s\n", count, last) > outputfile
+ else if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+ }
+
+\1f
+File: gawk.info, Node: Wc Program, Prev: Uniq Program, Up: Clones
+
+13.2.7 Counting Things
+----------------------
+
+The `wc' (word count) utility counts lines, words, and characters in
+one or more input files. Its usage is as follows:
+
+ wc [-lwc] [ FILES ... ]
+
+If no files are specified on the command line, `wc' reads its standard
+input. If there are multiple files, it also prints total counts for all
+the files. The options and their meanings are shown in the following
+list:
+
+`-l'
+ Count only lines.
+
+`-w'
+ Count only words. A "word" is a contiguous sequence of
+ nonwhitespace characters, separated by spaces and/or tabs.
+ Luckily, this is the normal way `awk' separates fields in its
+ input data.
+
+`-c'
+ Count only characters.
+
+Implementing `wc' in `awk' is particularly elegant, since `awk' does a
+lot of the work for us; it splits lines into words (i.e., fields) and
+counts them, it counts lines (i.e., records), and it can easily tell us
+how long a line is.
+
+This uses the `getopt' library function (*note Getopt Function::) and
+the file-transition functions (*note Filetrans Function::).
+
+This version has one notable difference from traditional versions of
+`wc': it always prints the counts in the order lines, words, and
+characters. Traditional versions note the order of the `-l', `-w', and
+`-c' options on the command line, and print the counts in that order.
+
+The `BEGIN' rule does the argument processing. The variable
+`print_total' is true if more than one file is named on the command
+line:
+
+ # wc.awk --- count lines, words, characters
+
+ # Options:
+ # -l only count lines
+ # -w only count words
+ # -c only count characters
+ #
+ # Default is to count lines, words, characters
+ #
+ # Requires getopt and file transition library functions
+
+ BEGIN {
+ # let getopt print a message about
+ # invalid options. we ignore them
+ while ((c = getopt(ARGC, ARGV, "lwc")) != -1) {
+ if (c == "l")
+ do_lines = 1
+ else if (c == "w")
+ do_words = 1
+ else if (c == "c")
+ do_chars = 1
+ }
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ # if no options, do all
+ if (! do_lines && ! do_words && ! do_chars)
+ do_lines = do_words = do_chars = 1
+
+ print_total = (ARGC - i > 2)
+ }
+
+The `beginfile' function is simple; it just resets the counts of lines,
+words, and characters to zero, and saves the current file name in
+`fname':
+
+ function beginfile(file)
+ {
+ chars = lines = words = 0
+ fname = FILENAME
+ }
+
+The `endfile' function adds the current file's numbers to the running
+totals of lines, words, and characters.(1) It then prints out those
+numbers for the file that was just read. It relies on `beginfile' to
+reset the numbers for the following data file:
+
+ function endfile(file)
+ {
+ tchars += chars
+ tlines += lines
+ twords += words
+ if (do_lines)
+ printf "\t%d", lines
+ if (do_words)
+ printf "\t%d", words
+ if (do_chars)
+ printf "\t%d", chars
+ printf "\t%s\n", fname
+ }
+
+There is one rule that is executed for each line. It adds the length of
+the record, plus one, to `chars'. Adding one plus the record length is
+needed because the newline character separating records (the value of
+`RS') is not part of the record itself, and thus not included in its
+length. Next, `lines' is incremented for each line read, and `words'
+is incremented by the value of `NF', which is the number of "words" on
+this line:
+
+ # do per line
+ {
+ chars += length($0) + 1 # get newline
+ lines++
+ words += NF
+ }
+
+Finally, the `END' rule simply prints the totals for all the files:
+
+ END {
+ if (print_total) {
+ if (do_lines)
+ printf "\t%d", tlines
+ if (do_words)
+ printf "\t%d", twords
+ if (do_chars)
+ printf "\t%d", tchars
+ print "\ttotal"
+ }
+ }
+
+---------- Footnotes ----------
+
+(1) `wc' can't just use the value of `FNR' in `endfile'. If you examine
+the code in *Note Filetrans Function::, you will see that `FNR' has
+already been reset by the time `endfile' is called.
+
+\1f
+File: gawk.info, Node: Miscellaneous Programs, Prev: Clones, Up: Sample Programs
+
+13.3 A Grab Bag of `awk' Programs
+=================================
+
+This minor node is a large "grab bag" of miscellaneous programs. We
+hope you find them both interesting and enjoyable.
+
+* Menu:
+
+* Dupword Program:: Finding duplicated words in a document.
+* Alarm Program:: An alarm clock.
+* Translate Program:: A program similar to the `tr' utility.
+* Labels Program:: Printing mailing labels.
+* Word Sorting:: A program to produce a word usage count.
+* History Sorting:: Eliminating duplicate entries from a history
+ file.
+* Extract Program:: Pulling out programs from Texinfo source
+ files.
+* Simple Sed:: A Simple Stream Editor.
+* Igawk Program:: A wrapper for `awk' that includes
+ files.
+
+\1f
+File: gawk.info, Node: Dupword Program, Next: Alarm Program, Up: Miscellaneous Programs
+
+13.3.1 Finding Duplicated Words in a Document
+---------------------------------------------
+
+A common error when writing large amounts of prose is to accidentally
+duplicate words. Typically you will see this in text as something like
+"the the program does the following..." When the text is online, often
+the duplicated words occur at the end of one line and the beginning of
+another, making them very difficult to spot.
+
+This program, `dupword.awk', scans through a file one line at a time
+and looks for adjacent occurrences of the same word. It also saves the
+last word on a line (in the variable `prev') for comparison with the
+first word on the next line.
+
+The first two statements make sure that the line is all lowercase, so
+that, for example, "The" and "the" compare equal to each other. The
+next statement replaces nonalphanumeric and nonwhitespace characters
+with spaces, so that punctuation does not affect the comparison either.
+The characters are replaced with spaces so that formatting controls
+don't create nonsense words (e.g., the Texinfo `@code{NF}' becomes
+`codeNF' if punctuation is simply deleted). The record is then resplit
+into fields, yielding just the actual words on the line, and ensuring
+that there are no empty fields.
+
+If there are no fields left after removing all the punctuation, the
+current record is skipped. Otherwise, the program loops through each
+word, comparing it to the previous one:
+
+ # dupword.awk --- find duplicate words in text
+ {
+ $0 = tolower($0)
+ gsub(/[^[:alnum:][:blank:]]/, " ");
+ $0 = $0 # re-split
+ if (NF == 0)
+ next
+ if ($1 == prev)
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $1)
+ for (i = 2; i <= NF; i++)
+ if ($i == $(i-1))
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $i)
+ prev = $NF
+ }
+
+\1f
+File: gawk.info, Node: Alarm Program, Next: Translate Program, Prev: Dupword Program, Up: Miscellaneous Programs
+
+13.3.2 An Alarm Clock Program
+-----------------------------
+
+ Nothing cures insomnia like a ringing alarm clock.
+ Arnold Robbins
+
+The following program is a simple "alarm clock" program. You give it a
+time of day and an optional message. At the specified time, it prints
+the message on the standard output. In addition, you can give it the
+number of times to repeat the message as well as a delay between
+repetitions.
+
+This program uses the `gettimeofday' function from *Note Gettimeofday
+Function::.
+
+All the work is done in the `BEGIN' rule. The first part is argument
+checking and setting of defaults: the delay, the count, and the message
+to print. If the user supplied a message without the ASCII BEL
+character (known as the "alert" character, `"\a"'), then it is added to
+the message. (On many systems, printing the ASCII BEL generates an
+audible alert. Thus when the alarm goes off, the system calls attention
+to itself in case the user is not looking at the computer or terminal.)
+Here is the program:
+
+ # alarm.awk --- set an alarm
+ #
+ # Requires gettimeofday library function
+ # usage: alarm time [ "message" [ count [ delay ] ] ]
+
+ BEGIN \
+ {
+ # Initial argument sanity checking
+ usage1 = "usage: alarm time ['message' [count [delay]]]"
+ usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
+
+ if (ARGC < 2) {
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ } else if (ARGC == 5) {
+ delay = ARGV[4] + 0
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ } else if (ARGC == 4) {
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ } else if (ARGC == 3) {
+ message = ARGV[2]
+ } else if (ARGV[1] !~ /[0-9]?[0-9]:[0-9][0-9]/) {
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ }
+
+ # set defaults for once we reach the desired time
+ if (delay == 0)
+ delay = 180 # 3 minutes
+ if (count == 0)
+ count = 5
+ if (message == "")
+ message = sprintf("\aIt is now %s!\a", ARGV[1])
+ else if (index(message, "\a") == 0)
+ message = "\a" message "\a"
+
+The next minor node of code turns the alarm time into hours and minutes,
+converts it (if necessary) to a 24-hour clock, and then turns that time
+into a count of the seconds since midnight. Next it turns the current
+time into a count of seconds since midnight. The difference between
+the two is how long to wait before setting off the alarm:
+
+ # split up alarm time
+ split(ARGV[1], atime, ":")
+ hour = atime[1] + 0 # force numeric
+ minute = atime[2] + 0 # force numeric
+
+ # get current broken down time
+ gettimeofday(now)
+
+ # if time given is 12-hour hours and it's after that
+ # hour, e.g., `alarm 5:30' at 9 a.m. means 5:30 p.m.,
+ # then add 12 to real hour
+ if (hour < 12 && now["hour"] > hour)
+ hour += 12
+
+ # set target time in seconds since midnight
+ target = (hour * 60 * 60) + (minute * 60)
+
+ # get current time in seconds since midnight
+ current = (now["hour"] * 60 * 60) + \
+ (now["minute"] * 60) + now["second"]
+
+ # how long to sleep for
+ naptime = target - current
+ if (naptime <= 0) {
+ print "time is in the past!" > "/dev/stderr"
+ exit 1
+ }
+
+Finally, the program uses the `system' function (*note I/O Functions::)
+to call the `sleep' utility. The `sleep' utility simply pauses for the
+given number of seconds. If the exit status is not zero, the program
+assumes that `sleep' was interrupted and exits. If `sleep' exited with
+an OK status (zero), then the program prints the message in a loop,
+again using `sleep' to delay for however many seconds are necessary:
+
+ # zzzzzz..... go away if interrupted
+ if (system(sprintf("sleep %d", naptime)) != 0)
+ exit 1
+
+ # time to notify!
+ command = sprintf("sleep %d", delay)
+ for (i = 1; i <= count; i++) {
+ print message
+ # if sleep command interrupted, go away
+ if (system(command) != 0)
+ break
+ }
+
+ exit 0
+ }
+
+\1f
+File: gawk.info, Node: Translate Program, Next: Labels Program, Prev: Alarm Program, Up: Miscellaneous Programs
+
+13.3.3 Transliterating Characters
+---------------------------------
+
+The system `tr' utility transliterates characters. For example, it is
+often used to map uppercase letters into lowercase for further
+processing:
+
+ GENERATE DATA | tr 'A-Z' 'a-z' | PROCESS DATA ...
+
+`tr' requires two lists of characters.(1) When processing the input,
+the first character in the first list is replaced with the first
+character in the second list, the second character in the first list is
+replaced with the second character in the second list, and so on. If
+there are more characters in the "from" list than in the "to" list, the
+last character of the "to" list is used for the remaining characters in
+the "from" list.
+
+Some time ago, a user proposed that a transliteration function should
+be added to `gawk'. The following program was written to prove that
+character transliteration could be done with a user-level function.
+This program is not as complete as the system `tr' utility but it does
+most of the job.
+
+The `translate' program demonstrates one of the few weaknesses of
+standard `awk': dealing with individual characters is very painful,
+requiring repeated use of the `substr', `index', and `gsub' built-in
+functions (*note String Functions::).(2) There are two functions. The
+first, `stranslate', takes three arguments:
+
+`from'
+ A list of characters from which to translate.
+
+`to'
+ A list of characters to which to translate.
+
+`target'
+ The string on which to do the translation.
+
+Associative arrays make the translation part fairly easy. `t_ar' holds
+the "to" characters, indexed by the "from" characters. Then a simple
+loop goes through `from', one character at a time. For each character
+in `from', if the character appears in `target', `gsub' is used to
+change it to the corresponding `to' character.
+
+The `translate' function simply calls `stranslate' using `$0' as the
+target. The main program sets two global variables, `FROM' and `TO',
+from the command line, and then changes `ARGV' so that `awk' reads from
+the standard input.
+
+Finally, the processing rule simply calls `translate' for each record:
+
+ # translate.awk --- do tr-like stuff
+ # Bugs: does not handle things like: tr A-Z a-z, it has
+ # to be spelled out. However, if `to' is shorter than `from',
+ # the last character in `to' is used for the rest of `from'.
+
+ function stranslate(from, to, target, lf, lt, t_ar, i, c)
+ {
+ lf = length(from)
+ lt = length(to)
+ for (i = 1; i <= lt; i++)
+ t_ar[substr(from, i, 1)] = substr(to, i, 1)
+ if (lt < lf)
+ for (; i <= lf; i++)
+ t_ar[substr(from, i, 1)] = substr(to, lt, 1)
+ for (i = 1; i <= lf; i++) {
+ c = substr(from, i, 1)
+ if (index(target, c) > 0)
+ gsub(c, t_ar[c], target)
+ }
+ return target
+ }
+
+ function translate(from, to)
+ {
+ return $0 = stranslate(from, to, $0)
+ }
+
+ # main program
+ BEGIN {
+ if (ARGC < 3) {
+ print "usage: translate from to" > "/dev/stderr"
+ exit
+ }
+ FROM = ARGV[1]
+ TO = ARGV[2]
+ ARGC = 2
+ ARGV[1] = "-"
+ }
+
+ {
+ translate(FROM, TO)
+ print
+ }
+
+While it is possible to do character transliteration in a user-level
+function, it is not necessarily efficient, and we (the `gawk' authors)
+started to consider adding a built-in function. However, shortly after
+writing this program, we learned that the System V Release 4 `awk' had
+added the `toupper' and `tolower' functions (*note String Functions::).
+These functions handle the vast majority of the cases where character
+transliteration is necessary, and so we chose to simply add those
+functions to `gawk' as well and then leave well enough alone.
+
+An obvious improvement to this program would be to set up the `t_ar'
+array only once, in a `BEGIN' rule. However, this assumes that the
+"from" and "to" lists will never change throughout the lifetime of the
+program.
+
+---------- Footnotes ----------
+
+(1) On some older System V systems, `tr' may require that the lists be
+written as range expressions enclosed in square brackets (`[a-z]') and
+quoted, to prevent the shell from attempting a file name expansion.
+This is not a feature.
+
+(2) This program was written before `gawk' acquired the ability to
+split each character in a string into separate array elements.
+
+\1f
+File: gawk.info, Node: Labels Program, Next: Word Sorting, Prev: Translate Program, Up: Miscellaneous Programs
+
+13.3.4 Printing Mailing Labels
+------------------------------
+
+Here is a "real world"(1) program. This script reads lists of names and
+addresses and generates mailing labels. Each page of labels has 20
+labels on it, 2 across and 10 down. The addresses are guaranteed to be
+no more than 5 lines of data. Each address is separated from the next
+by a blank line.
+
+The basic idea is to read 20 labels worth of data. Each line of each
+label is stored in the `line' array. The single rule takes care of
+filling the `line' array and printing the page when 20 labels have been
+read.
+
+The `BEGIN' rule simply sets `RS' to the empty string, so that `awk'
+splits records at blank lines (*note Records::). It sets `MAXLINES' to
+100, since 100 is the maximum number of lines on the page (20 * 5 =
+100).
+
+Most of the work is done in the `printpage' function. The label lines
+are stored sequentially in the `line' array. But they have to print
+horizontally; `line[1]' next to `line[6]', `line[2]' next to `line[7]',
+and so on. Two loops are used to accomplish this. The outer loop,
+controlled by `i', steps through every 10 lines of data; this is each
+row of labels. The inner loop, controlled by `j', goes through the
+lines within the row. As `j' goes from 0 to 4, `i+j' is the `j'-th
+line in the row, and `i+j+5' is the entry next to it. The output ends
+up looking something like this:
+
+ line 1 line 6
+ line 2 line 7
+ line 3 line 8
+ line 4 line 9
+ line 5 line 10
+ ...
+
+As a final note, an extra blank line is printed at lines 21 and 61, to
+keep the output lined up on the labels. This is dependent on the
+particular brand of labels in use when the program was written. You
+will also note that there are 2 blank lines at the top and 2 blank
+lines at the bottom.
+
+The `END' rule arranges to flush the final page of labels; there may
+not have been an even multiple of 20 labels in the data:
+
+ # labels.awk --- print mailing labels
+
+ # Each label is 5 lines of data that may have blank lines.
+ # The label sheets have 2 blank lines at the top and 2 at
+ # the bottom.
+
+ BEGIN { RS = "" ; MAXLINES = 100 }
+
+ function printpage( i, j)
+ {
+ if (Nlines <= 0)
+ return
+
+ printf "\n\n" # header
+
+ for (i = 1; i <= Nlines; i += 10) {
+ if (i == 21 || i == 61)
+ print ""
+ for (j = 0; j < 5; j++) {
+ if (i + j > MAXLINES)
+ break
+ printf " %-41s %s\n", line[i+j], line[i+j+5]
+ }
+ print ""
+ }
+
+ printf "\n\n" # footer
+
+ for (i in line)
+ line[i] = ""
+ }
+
+ # main rule
+ {
+ if (Count >= 20) {
+ printpage()
+ Count = 0
+ Nlines = 0
+ }
+ n = split($0, a, "\n")
+ for (i = 1; i <= n; i++)
+ line[++Nlines] = a[i]
+ for (; i <= 5; i++)
+ line[++Nlines] = ""
+ Count++
+ }
+
+ END \
+ {
+ printpage()
+ }
+
+---------- Footnotes ----------
+
+(1) "Real world" is defined as "a program actually used to get
+something done."
+
+\1f
+File: gawk.info, Node: Word Sorting, Next: History Sorting, Prev: Labels Program, Up: Miscellaneous Programs
+
+13.3.5 Generating Word-Usage Counts
+-----------------------------------
+
+The following `awk' program prints the number of occurrences of each
+word in its input. It illustrates the associative nature of `awk'
+arrays by using strings as subscripts. It also demonstrates the `for
+INDEX in ARRAY' mechanism. Finally, it shows how `awk' is used in
+conjunction with other utility programs to do a useful task of some
+complexity with a minimum of effort. Some explanations follow the
+program listing:
+
+ # Print list of word frequencies
+ {
+ for (i = 1; i <= NF; i++)
+ freq[$i]++
+ }
+
+ END {
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+ }
+
+This program has two rules. The first rule, because it has an empty
+pattern, is executed for every input line. It uses `awk''s
+field-accessing mechanism (*note Fields::) to pick out the individual
+words from the line, and the built-in variable `NF' (*note Built-in
+Variables::) to know how many fields are available. For each input
+word, it increments an element of the array `freq' to reflect that the
+word has been seen an additional time.
+
+The second rule, because it has the pattern `END', is not executed
+until the input has been exhausted. It prints out the contents of the
+`freq' table that has been built up inside the first action. This
+program has several problems that would prevent it from being useful by
+itself on real text files:
+
+ * Words are detected using the `awk' convention that fields are
+ separated just by whitespace. Other characters in the input
+ (except newlines) don't have any special meaning to `awk'. This
+ means that punctuation characters count as part of words.
+
+ * The `awk' language considers upper- and lowercase characters to be
+ distinct. Therefore, "bartender" and "Bartender" are not treated
+ as the same word. This is undesirable, since in normal text, words
+ are capitalized if they begin sentences, and a frequency analyzer
+ should not be sensitive to capitalization.
+
+ * The output does not come out in any useful order. You're more
+ likely to be interested in which words occur most frequently or in
+ having an alphabetized table of how frequently each word occurs.
+
+The way to solve these problems is to use some of `awk''s more advanced
+features. First, we use `tolower' to remove case distinctions. Next,
+we use `gsub' to remove punctuation characters. Finally, we use the
+system `sort' utility to process the output of the `awk' script. Here
+is the new version of the program:
+
+ # wordfreq.awk --- print list of word frequencies
+
+ {
+ $0 = tolower($0) # remove case distinctions
+ # remove punctuation
+ gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
+ for (i = 1; i <= NF; i++)
+ freq[$i]++
+ }
+
+ END {
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+ }
+
+Assuming we have saved this program in a file named `wordfreq.awk', and
+that the data is in `file1', the following pipeline:
+
+ awk -f wordfreq.awk file1 | sort -k 2nr
+
+produces a table of the words appearing in `file1' in order of
+decreasing frequency. The `awk' program suitably massages the data and
+produces a word frequency table, which is not ordered.
+
+The `awk' script's output is then sorted by the `sort' utility and
+printed on the terminal. The options given to `sort' specify a sort
+that uses the second field of each input line (skipping one field),
+that the sort keys should be treated as numeric quantities (otherwise
+`15' would come before `5'), and that the sorting should be done in
+descending (reverse) order.
+
+The `sort' could even be done from within the program, by changing the
+`END' action to:
+
+ END {
+ sort = "sort -k 2nr"
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word] | sort
+ close(sort)
+ }
+
+This way of sorting must be used on systems that do not have true pipes
+at the command-line (or batch-file) level. See the general operating
+system documentation for more information on how to use the `sort'
+program.
+
+\1f
+File: gawk.info, Node: History Sorting, Next: Extract Program, Prev: Word Sorting, Up: Miscellaneous Programs
+
+13.3.6 Removing Duplicates from Unsorted Text
+---------------------------------------------
+
+The `uniq' program (*note Uniq Program::), removes duplicate lines from
+_sorted_ data.
+
+Suppose, however, you need to remove duplicate lines from a data file
+but that you want to preserve the order the lines are in. A good
+example of this might be a shell history file. The history file keeps
+a copy of all the commands you have entered, and it is not unusual to
+repeat a command several times in a row. Occasionally you might want
+to compact the history by removing duplicate entries. Yet it is
+desirable to maintain the order of the original commands.
+
+This simple program does the job. It uses two arrays. The `data'
+array is indexed by the text of each line. For each line, `data[$0]'
+is incremented. If a particular line has not been seen before, then
+`data[$0]' is zero. In this case, the text of the line is stored in
+`lines[count]'. Each element of `lines' is a unique command, and the
+indices of `lines' indicate the order in which those lines are
+encountered. The `END' rule simply prints out the lines, in order:
+
+ # histsort.awk --- compact a shell history file
+ # Thanks to Byron Rakitzis for the general idea
+ {
+ if (data[$0]++ == 0)
+ lines[++count] = $0
+ }
+
+ END {
+ for (i = 1; i <= count; i++)
+ print lines[i]
+ }
+
+This program also provides a foundation for generating other useful
+information. For example, using the following `print' statement in the
+`END' rule indicates how often a particular command is used:
+
+ print data[lines[i]], lines[i]
+
+This works because `data[$0]' is incremented each time a line is seen.
+
+\1f
+File: gawk.info, Node: Extract Program, Next: Simple Sed, Prev: History Sorting, Up: Miscellaneous Programs
+
+13.3.7 Extracting Programs from Texinfo Source Files
+----------------------------------------------------
+
+The nodes *Note Library Functions::, and *Note Sample Programs::, are
+the top level nodes for a large number of `awk' programs. If you want
+to experiment with these programs, it is tedious to have to type them
+in by hand. Here we present a program that can extract parts of a
+Texinfo input file into separate files.
+
+This Info file is written in Texinfo, the GNU project's document
+formatting language. A single Texinfo source file can be used to
+produce both printed and online documentation. The Texinfo language is
+described fully, starting with *Note Top::.
+
+For our purposes, it is enough to know three things about Texinfo input
+files:
+
+ * The "at" symbol (`@') is special in Texinfo, much as the backslash
+ (`\') is in C or `awk'. Literal `@' symbols are represented in
+ Texinfo source files as `@@'.
+
+ * Comments start with either `@c' or `@comment'. The
+ file-extraction program works by using special comments that start
+ at the beginning of a line.
+
+ * Lines containing `@group' and `@end group' commands bracket
+ example text that should not be split across a page boundary.
+ (Unfortunately, TeX isn't always smart enough to do things exactly
+ right, and we have to give it some help.)
+
+The following program, `extract.awk', reads through a Texinfo source
+file and does two things, based on the special comments. Upon seeing
+`@c system ...', it runs a command, by extracting the command text from
+the control line and passing it on to the `system' function (*note I/O
+Functions::). Upon seeing `@c file FILENAME', each subsequent line is
+sent to the file FILENAME, until `@c endfile' is encountered. The
+rules in `extract.awk' match either `@c' or `@comment' by letting the
+`omment' part be optional. Lines containing `@group' and `@end group'
+are simply removed. `extract.awk' uses the `join' library function
+(*note Join Function::).
+
+The example programs in the online Texinfo source for `GAWK: Effective
+AWK Programming' (`gawk.texi') have all been bracketed inside `file' and
+`endfile' lines. The `gawk' distribution uses a copy of `extract.awk'
+to extract the sample programs and install many of them in a standard
+directory where `gawk' can find them. The Texinfo file looks something
+like this:
+
+ ...
+ This program has a @code{BEGIN} rule,
+ that prints a nice message:
+
+ @example
+ @c file examples/messages.awk
+ BEGIN @{ print "Don't panic!" @}
+ @c end file
+ @end example
+
+ It also prints some final advice:
+
+ @example
+ @c file examples/messages.awk
+ END @{ print "Always avoid bored archeologists!" @}
+ @c end file
+ @end example
+ ...
+
+`extract.awk' begins by setting `IGNORECASE' to one, so that mixed
+upper- and lowercase letters in the directives won't matter.
+
+The first rule handles calling `system', checking that a command is
+given (`NF' is at least three) and also checking that the command exits
+with a zero exit status, signifying OK:
+
+ # extract.awk --- extract files and run programs
+ # from texinfo files
+ BEGIN { IGNORECASE = 1 }
+
+ /^@c(omment)?[ \t]+system/ \
+ {
+ if (NF < 3) {
+ e = (FILENAME ":" FNR)
+ e = (e ": badly formed `system' line")
+ print e > "/dev/stderr"
+ next
+ }
+ $1 = ""
+ $2 = ""
+ stat = system($0)
+ if (stat != 0) {
+ e = (FILENAME ":" FNR)
+ e = (e ": warning: system returned " stat)
+ print e > "/dev/stderr"
+ }
+ }
+
+The variable `e' is used so that the function fits nicely on the screen.
+
+The second rule handles moving data into files. It verifies that a
+file name is given in the directive. If the file named is not the
+current file, then the current file is closed. Keeping the current file
+open until a new file is encountered allows the use of the `>'
+redirection for printing the contents, keeping open file management
+simple.
+
+The `for' loop does the work. It reads lines using `getline' (*note
+Getline::). For an unexpected end of file, it calls the
+`unexpected_eof' function. If the line is an "endfile" line, then it
+breaks out of the loop. If the line is an `@group' or `@end group'
+line, then it ignores it and goes on to the next line. Similarly,
+comments within examples are also ignored.
+
+Most of the work is in the following few lines. If the line has no `@'
+symbols, the program can print it directly. Otherwise, each leading
+`@' must be stripped off. To remove the `@' symbols, the line is split
+into separate elements of the array `a', using the `split' function
+(*note String Functions::). The `@' symbol is used as the separator
+character. Each element of `a' that is empty indicates two successive
+`@' symbols in the original line. For each two empty elements (`@@' in
+the original file), we have to add a single `@' symbol back in.
+
+When the processing of the array is finished, `join' is called with the
+value of `SUBSEP', to rejoin the pieces back into a single line. That
+line is then printed to the output file:
+
+ /^@c(omment)?[ \t]+file/ \
+ {
+ if (NF != 3) {
+ e = (FILENAME ":" FNR ": badly formed `file' line")
+ print e > "/dev/stderr"
+ next
+ }
+ if ($3 != curfile) {
+ if (curfile != "")
+ close(curfile)
+ curfile = $3
+ }
+
+ for (;;) {
+ if ((getline line) <= 0)
+ unexpected_eof()
+ if (line ~ /^@c(omment)?[ \t]+endfile/)
+ break
+ else if (line ~ /^@(end[ \t]+)?group/)
+ continue
+ else if (line ~ /^@c(omment+)?[ \t]+/)
+ continue
+ if (index(line, "@") == 0) {
+ print line > curfile
+ continue
+ }
+ n = split(line, a, "@")
+ # if a[1] == "", means leading @,
+ # don't add one back in.
+ for (i = 2; i <= n; i++) {
+ if (a[i] == "") { # was an @@
+ a[i] = "@"
+ if (a[i+1] == "")
+ i++
+ }
+ }
+ print join(a, 1, n, SUBSEP) > curfile
+ }
+ }
+
+An important thing to note is the use of the `>' redirection. Output
+done with `>' only opens the file once; it stays open and subsequent
+output is appended to the file (*note Redirection::). This makes it
+easy to mix program text and explanatory prose for the same sample
+source file (as has been done here!) without any hassle. The file is
+only closed when a new data file name is encountered or at the end of
+the input file.
+
+Finally, the function `unexpected_eof' prints an appropriate error
+message and then exits. The `END' rule handles the final cleanup,
+closing the open file:
+
+ function unexpected_eof() {
+ printf("%s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
+ exit 1
+ }
+
+ END {
+ if (curfile)
+ close(curfile)
+ }
+
+\1f
+File: gawk.info, Node: Simple Sed, Next: Igawk Program, Prev: Extract Program, Up: Miscellaneous Programs
+
+13.3.8 A Simple Stream Editor
+-----------------------------
+
+The `sed' utility is a stream editor, a program that reads a stream of
+data, makes changes to it, and passes it on. It is often used to make
+global changes to a large file or to a stream of data generated by a
+pipeline of commands. While `sed' is a complicated program in its own
+right, its most common use is to perform global substitutions in the
+middle of a pipeline:
+
+ command1 < orig.data | sed 's/old/new/g' | command2 > result
+
+Here, `s/old/new/g' tells `sed' to look for the regexp `old' on each
+input line and globally replace it with the text `new', i.e., all the
+occurrences on a line. This is similar to `awk''s `gsub' function
+(*note String Functions::).
+
+The following program, `awksed.awk', accepts at least two command-line
+arguments: the pattern to look for and the text to replace it with. Any
+additional arguments are treated as data file names to process. If none
+are provided, the standard input is used:
+
+ # awksed.awk --- do s/foo/bar/g using just print
+ # Thanks to Michael Brennan for the idea
+ function usage()
+ {
+ print "usage: awksed pat repl [files...]" > "/dev/stderr"
+ exit 1
+ }
+
+ BEGIN {
+ # validate arguments
+ if (ARGC < 3)
+ usage()
+
+ RS = ARGV[1]
+ ORS = ARGV[2]
+
+ # don't use arguments as files
+ ARGV[1] = ARGV[2] = ""
+ }
+
+ # look ma, no hands!
+ {
+ if (RT == "")
+ printf "%s", $0
+ else
+ print
+ }
+
+The program relies on `gawk''s ability to have `RS' be a regexp, as
+well as on the setting of `RT' to the actual text that terminates the
+record (*note Records::).
+
+The idea is to have `RS' be the pattern to look for. `gawk'
+automatically sets `$0' to the text between matches of the pattern.
+This is text that we want to keep, unmodified. Then, by setting `ORS'
+to the replacement text, a simple `print' statement outputs the text we
+want to keep, followed by the replacement text.
+
+There is one wrinkle to this scheme, which is what to do if the last
+record doesn't end with text that matches `RS'. Using a `print'
+statement unconditionally prints the replacement text, which is not
+correct. However, if the file did not end in text that matches `RS',
+`RT' is set to the null string. In this case, we can print `$0' using
+`printf' (*note Printf::).
+
+The `BEGIN' rule handles the setup, checking for the right number of
+arguments and calling `usage' if there is a problem. Then it sets `RS'
+and `ORS' from the command-line arguments and sets `ARGV[1]' and
+`ARGV[2]' to the null string, so that they are not treated as file names
+(*note ARGC and ARGV::).
+
+The `usage' function prints an error message and exits. Finally, the
+single rule handles the printing scheme outlined above, using `print'
+or `printf' as appropriate, depending upon the value of `RT'.
+
+\1f
+File: gawk.info, Node: Igawk Program, Prev: Simple Sed, Up: Miscellaneous Programs
+
+13.3.9 An Easy Way to Use Library Functions
+-------------------------------------------
+
+Using library functions in `awk' can be very beneficial. It encourages
+code reuse and the writing of general functions. Programs are smaller
+and therefore clearer. However, using library functions is only easy
+when writing `awk' programs; it is painful when running them, requiring
+multiple `-f' options. If `gawk' is unavailable, then so too is the
+`AWKPATH' environment variable and the ability to put `awk' functions
+into a library directory (*note Options::). It would be nice to be
+able to write programs in the following manner:
+
+ # library functions
+ @include getopt.awk
+ @include join.awk
+ ...
+
+ # main program
+ BEGIN {
+ while ((c = getopt(ARGC, ARGV, "a:b:cde")) != -1)
+ ...
+ ...
+ }
+
+The following program, `igawk.sh', provides this service. It simulates
+`gawk''s searching of the `AWKPATH' variable and also allows "nested"
+includes; i.e., a file that is included with `@include' can contain
+further `@include' statements. `igawk' makes an effort to only include
+files once, so that nested includes don't accidentally include a
+library function twice.
+
+`igawk' should behave just like `gawk' externally. This means it
+should accept all of `gawk''s command-line arguments, including the
+ability to have multiple source files specified via `-f', and the
+ability to mix command-line and library source files.
+
+The program is written using the POSIX Shell (`sh') command
+language.(1) It works as follows:
+
+ 1. Loop through the arguments, saving anything that doesn't represent
+ `awk' source code for later, when the expanded program is run.
+
+ 2. For any arguments that do represent `awk' text, put the arguments
+ into a shell variable that will be expanded. There are two cases:
+
+ a. Literal text, provided with `--source' or `--source='. This
+ text is just appended directly.
+
+ b. Source file names, provided with `-f'. We use a neat trick
+ and append `@include FILENAME' to the shell variable's
+ contents. Since the file-inclusion program works the way
+ `gawk' does, this gets the text of the file included into the
+ program at the correct point.
+
+ 3. Run an `awk' program (naturally) over the shell variable's
+ contents to expand `@include' statements. The expanded program is
+ placed in a second shell variable.
+
+ 4. Run the expanded program with `gawk' and any other original
+ command-line arguments that the user supplied (such as the data
+ file names).
+
+This program uses shell variables extensively; for storing command line
+arguments, the text of the `awk' program that will expand the user's
+program, for the user's original program, and for the expanded program.
+Doing so removes some potential problems that might arise were we to
+use temporary files instead, at the cost of making the script somewhat
+more complicated.
+
+The initial part of the program turns on shell tracing if the first
+argument is `debug'.
+
+The next part loops through all the command-line arguments. There are
+several cases of interest:
+
+`--'
+ This ends the arguments to `igawk'. Anything else should be
+ passed on to the user's `awk' program without being evaluated.
+
+`-W'
+ This indicates that the next option is specific to `gawk'. To make
+ argument processing easier, the `-W' is appended to the front of
+ the remaining arguments and the loop continues. (This is an `sh'
+ programming trick. Don't worry about it if you are not familiar
+ with `sh'.)
+
+`-v, -F'
+ These are saved and passed on to `gawk'.
+
+`-f, --file, --file=, -Wfile='
+ The file name is appended to the shell variable `program' with an
+ `@include' statement. The `expr' utility is used to remove the
+ leading option part of the argument (e.g., `--file='). (Typical
+ `sh' usage would be to use the `echo' and `sed' utilities to do
+ this work. Unfortunately, some versions of `echo' evaluate escape
+ sequences in their arguments, possibly mangling the program text.
+ Using `expr' avoids this problem.)
+
+`--source, --source=, -Wsource='
+ The source text is appended to `program'.
+
+`--version, -Wversion'
+ `igawk' prints its version number, runs `gawk --version' to get
+ the `gawk' version information, and then exits.
+
+If none of the `-f', `--file', `-Wfile', `--source', or `-Wsource'
+arguments are supplied, then the first nonoption argument should be the
+`awk' program. If there are no command-line arguments left, `igawk'
+prints an error message and exits. Otherwise, the first argument is
+appended to `program'. In any case, after the arguments have been
+processed, `program' contains the complete text of the original `awk'
+program.
+
+The program is as follows:
+
+ #! /bin/sh
+ # igawk --- like gawk but do @include processing
+ if [ "$1" = debug ]
+ then
+ set -x
+ shift
+ fi
+
+ # A literal newline, so that program text is formmatted correctly
+ n='
+ '
+
+ # Initialize variables to empty
+ program=
+ opts=
+
+ while [ $# -ne 0 ] # loop over arguments
+ do
+ case $1 in
+ --) shift; break;;
+
+ -W) shift
+ # The ${x?'message here'} construct prints a
+ # diagnostic if $x is the null string
+ set -- -W"${@?'missing operand'}"
+ continue;;
+
+ -[vF]) opts="$opts $1 '${2?'missing operand'}'"
+ shift;;
+
+ -[vF]*) opts="$opts '$1'" ;;
+
+ -f) program="$program$n@include ${2?'missing operand'}"
+ shift;;
+
+ -f*) f=`expr "$1" : '-f\(.*\)'`
+ program="$program$n@include $f";;
+
+ -[W-]file=*)
+ f=`expr "$1" : '-.file=\(.*\)'`
+ program="$program$n@include $f";;
+
+ -[W-]file)
+ program="$program$n@include ${2?'missing operand'}"
+ shift;;
+
+ -[W-]source=*)
+ t=`expr "$1" : '-.source=\(.*\)'`
+ program="$program$n$t";;
+
+ -[W-]source)
+ program="$program$n${2?'missing operand'}"
+ shift;;
+
+ -[W-]version)
+ echo igawk: version 2.0 1>&2
+ gawk --version
+ exit 0 ;;
+
+ -[W-]*) opts="$opts '$1'" ;;
+
+ *) break;;
+ esac
+ shift
+ done
+
+ if [ -z "$program" ]
+ then
+ program=${1?'missing program'}
+ shift
+ fi
+
+ # At this point, `program' has the program.
+
+The `awk' program to process `@include' directives is stored in the
+shell variable `expand_prog'. Doing this keeps the shell script
+readable. The `awk' program reads through the user's program, one line
+at a time, using `getline' (*note Getline::). The input file names and
+`@include' statements are managed using a stack. As each `@include' is
+encountered, the current file name is "pushed" onto the stack and the
+file named in the `@include' directive becomes the current file name.
+As each file is finished, the stack is "popped," and the previous input
+file becomes the current input file again. The process is started by
+making the original file the first one on the stack.
+
+The `pathto' function does the work of finding the full path to a file.
+It simulates `gawk''s behavior when searching the `AWKPATH'
+environment variable (*note AWKPATH Variable::). If a file name has a
+`/' in it, no path search is done. Otherwise, the file name is
+concatenated with the name of each directory in the path, and an
+attempt is made to open the generated file name. The only way to test
+if a file can be read in `awk' is to go ahead and try to read it with
+`getline'; this is what `pathto' does.(2) If the file can be read, it
+is closed and the file name is returned:
+
+ expand_prog='
+
+ function pathto(file, i, t, junk)
+ {
+ if (index(file, "/") != 0)
+ return file
+
+ for (i = 1; i <= ndirs; i++) {
+ t = (pathlist[i] "/" file)
+ if ((getline junk < t) > 0) {
+ # found it
+ close(t)
+ return t
+ }
+ }
+ return ""
+ }
+
+The main program is contained inside one `BEGIN' rule. The first thing
+it does is set up the `pathlist' array that `pathto' uses. After
+splitting the path on `:', null elements are replaced with `"."', which
+represents the current directory:
+
+ BEGIN {
+ path = ENVIRON["AWKPATH"]
+ ndirs = split(path, pathlist, ":")
+ for (i = 1; i <= ndirs; i++) {
+ if (pathlist[i] == "")
+ pathlist[i] = "."
+ }
+
+The stack is initialized with `ARGV[1]', which will be `/dev/stdin'.
+The main loop comes next. Input lines are read in succession. Lines
+that do not start with `@include' are printed verbatim. If the line
+does start with `@include', the file name is in `$2'. `pathto' is
+called to generate the full path. If it cannot, then we print an error
+message and continue.
+
+The next thing to check is if the file is included already. The
+`processed' array is indexed by the full file name of each included
+file and it tracks this information for us. If the file is seen again,
+a warning message is printed. Otherwise, the new file name is pushed
+onto the stack and processing continues.
+
+Finally, when `getline' encounters the end of the input file, the file
+is closed and the stack is popped. When `stackptr' is less than zero,
+the program is done:
+
+ stackptr = 0
+ input[stackptr] = ARGV[1] # ARGV[1] is first file
+
+ for (; stackptr >= 0; stackptr--) {
+ while ((getline < input[stackptr]) > 0) {
+ if (tolower($1) != "@include") {
+ print
+ continue
+ }
+ fpath = pathto($2)
+ if (fpath == "") {
+ printf("igawk:%s:%d: cannot find %s\n",
+ input[stackptr], FNR, $2) > "/dev/stderr"
+ continue
+ }
+ if (! (fpath in processed)) {
+ processed[fpath] = input[stackptr]
+ input[++stackptr] = fpath # push onto stack
+ } else
+ print $2, "included in", input[stackptr],
+ "already included in",
+ processed[fpath] > "/dev/stderr"
+ }
+ close(input[stackptr])
+ }
+ }' # close quote ends `expand_prog' variable
+
+ processed_program=`gawk -- "$expand_prog" /dev/stdin <<EOF
+ $program
+ EOF
+ `
+
+The shell construct `COMMAND << MARKER' is called a "here document".
+Everything in the shell script up to the MARKER is fed to COMMAND as
+input. The shell processes the contents of the here document for
+variable and command substitution (and possibly other things as well,
+depending upon the shell).
+
+The shell construct ``...`' is called "command substitution". The
+output of the command between the two backquotes (grave accents) is
+substituted into the command line. It is saved as a single string,
+even if the results contain whitespace.
+
+The expanded program is saved in the variable `processed_program'.
+It's done in these steps:
+
+ 1. Run `gawk' with the `@include'-processing program (the value of
+ the `expand_prog' shell variable) on standard input.
+
+ 2. Standard input is the contents of the user's program, from the
+ shell variable `program'. Its contents are fed to `gawk' via a
+ here document.
+
+ 3. The results of this processing are saved in the shell variable
+ `processed_program' by using command substitution.
+
+The last step is to call `gawk' with the expanded program, along with
+the original options and command-line arguments that the user supplied.
+
+ eval gawk $opts -- '"$processed_program"' '"$@"'
+
+The `eval' command is a shell construct that reruns the shell's parsing
+process. This keeps things properly quoted.
+
+This version of `igawk' represents my fourth attempt at this program.
+There are four key simplifications that make the program work better:
+
+ * Using `@include' even for the files named with `-f' makes building
+ the initial collected `awk' program much simpler; all the
+ `@include' processing can be done once.
+
+ * Not trying to save the line read with `getline' in the `pathto'
+ function when testing for the file's accessibility for use with
+ the main program simplifies things considerably.
+
+ * Using a `getline' loop in the `BEGIN' rule does it all in one
+ place. It is not necessary to call out to a separate loop for
+ processing nested `@include' statements.
+
+ * Instead of saving the expanded program in a temporary file,
+ putting it in a shell variable avoids some potential security
+ problems. This has the disadvantage that the script relies upon
+ more features of the `sh' language, making it harder to follow for
+ those who aren't familiar with `sh'.
+
+Also, this program illustrates that it is often worthwhile to combine
+`sh' and `awk' programming together. You can usually accomplish quite
+a lot, without having to resort to low-level programming in C or C++,
+and it is frequently easier to do certain kinds of string and argument
+manipulation using the shell than it is in `awk'.
+
+Finally, `igawk' shows that it is not always necessary to add new
+features to a program; they can often be layered on top. With `igawk',
+there is no real reason to build `@include' processing into `gawk'
+itself.
+
+As an additional example of this, consider the idea of having two files
+in a directory in the search path:
+
+`default.awk'
+ This file contains a set of default library functions, such as
+ `getopt' and `assert'.
+
+`site.awk'
+ This file contains library functions that are specific to a site or
+ installation; i.e., locally developed functions. Having a
+ separate file allows `default.awk' to change with new `gawk'
+ releases, without requiring the system administrator to update it
+ each time by adding the local functions.
+
+One user suggested that `gawk' be modified to automatically read these
+files upon startup. Instead, it would be very simple to modify `igawk'
+to do this. Since `igawk' can process nested `@include' directives,
+`default.awk' could simply contain `@include' statements for the
+desired library functions.
+
+---------- Footnotes ----------
+
+(1) Fully explaining the `sh' language is beyond the scope of this
+book. We provide some minimal explanations, but see a good shell
+programming book if you wish to understand things in more depth.
+
+(2) On some very old versions of `awk', the test `getline junk < t' can
+loop forever if the file exists but is empty. Caveat emptor.
+
+\1f
+File: gawk.info, Node: Language History, Next: Installation, Prev: Sample Programs, Up: Top
+
+Appendix A The Evolution of the `awk' Language
+**********************************************
+
+This Info file describes the GNU implementation of `awk', which follows
+the POSIX specification. Many long-time `awk' users learned `awk'
+programming with the original `awk' implementation in Version 7 Unix.
+(This implementation was the basis for `awk' in Berkeley Unix, through
+4.3-Reno. Subsequent versions of Berkeley Unix, and systems derived
+from 4.4BSD-Lite, use various versions of `gawk' for their `awk'.)
+This major node briefly describes the evolution of the `awk' language,
+with cross-references to other parts of the Info file where you can
+find more information.
+
+* Menu:
+
+* V7/SVR3.1:: The major changes between V7 and System V
+ Release 3.1.
+* SVR4:: Minor changes between System V Releases 3.1
+ and 4.
+* POSIX:: New features from the POSIX standard.
+* BTL:: New features from the Bell Laboratories
+ version of `awk'.
+* POSIX/GNU:: The extensions in `gawk' not in POSIX
+ `awk'.
+* Contributors:: The major contributors to `gawk'.
+
+\1f
+File: gawk.info, Node: V7/SVR3.1, Next: SVR4, Up: Language History
+
+A.1 Major Changes Between V7 and SVR3.1
+=======================================
+
+The `awk' language evolved considerably between the release of Version
+7 Unix (1978) and the new version that was first made generally
+available in System V Release 3.1 (1987). This minor node summarizes
+the changes, with cross-references to further details:
+
+ * The requirement for `;' to separate rules on a line (*note
+ Statements/Lines::).
+
+ * User-defined functions and the `return' statement (*note
+ User-defined::).
+
+ * The `delete' statement (*note Delete::).
+
+ * The `do'-`while' statement (*note Do Statement::).
+
+ * The built-in functions `atan2', `cos', `sin', `rand', and `srand'
+ (*note Numeric Functions::).
+
+ * The built-in functions `gsub', `sub', and `match' (*note String
+ Functions::).
+
+ * The built-in functions `close' and `system' (*note I/O
+ Functions::).
+
+ * The `ARGC', `ARGV', `FNR', `RLENGTH', `RSTART', and `SUBSEP'
+ built-in variables (*note Built-in Variables::).
+
+ * The conditional expression using the ternary operator `?:' (*note
+ Conditional Exp::).
+
+ * The exponentiation operator `^' (*note Arithmetic Ops::) and its
+ assignment operator form `^=' (*note Assignment Ops::).
+
+ * C-compatible operator precedence, which breaks some old `awk'
+ programs (*note Precedence::).
+
+ * Regexps as the value of `FS' (*note Field Separators::) and as the
+ third argument to the `split' function (*note String Functions::).
+
+ * Dynamic regexps as operands of the `~' and `!~' operators (*note
+ Regexp Usage::).
+
+ * The escape sequences `\b', `\f', and `\r' (*note Escape
+ Sequences::). (Some vendors have updated their old versions of
+ `awk' to recognize `\b', `\f', and `\r', but this is not something
+ you can rely on.)
+
+ * Redirection of input for the `getline' function (*note Getline::).
+
+ * Multiple `BEGIN' and `END' rules (*note BEGIN/END::).
+
+ * Multidimensional arrays (*note Multi-dimensional::).
+
+\1f
+File: gawk.info, Node: SVR4, Next: POSIX, Prev: V7/SVR3.1, Up: Language History
+
+A.2 Changes Between SVR3.1 and SVR4
+===================================
+
+The System V Release 4 (1989) version of Unix `awk' added these features
+(some of which originated in `gawk'):
+
+ * The `ENVIRON' variable (*note Built-in Variables::).
+
+ * Multiple `-f' options on the command line (*note Options::).
+
+ * The `-v' option for assigning variables before program execution
+ begins (*note Options::).
+
+ * The `--' option for terminating command-line options.
+
+ * The `\a', `\v', and `\x' escape sequences (*note Escape
+ Sequences::).
+
+ * A defined return value for the `srand' built-in function (*note
+ Numeric Functions::).
+
+ * The `toupper' and `tolower' built-in string functions for case
+ translation (*note String Functions::).
+
+ * A cleaner specification for the `%c' format-control letter in the
+ `printf' function (*note Control Letters::).
+
+ * The ability to dynamically pass the field width and precision
+ (`"%*.*d"') in the argument list of the `printf' function (*note
+ Control Letters::).
+
+ * The use of regexp constants, such as `/foo/', as expressions, where
+ they are equivalent to using the matching operator, as in `$0 ~
+ /foo/' (*note Using Constant Regexps::).
+
+ * Processing of escape sequences inside command-line variable
+ assignments (*note Assignment Options::).
+
+\1f
+File: gawk.info, Node: POSIX, Next: BTL, Prev: SVR4, Up: Language History
+
+A.3 Changes Between SVR4 and POSIX `awk'
+========================================
+
+The POSIX Command Language and Utilities standard for `awk' (1992)
+introduced the following changes into the language:
+
+ * The use of `-W' for implementation-specific options (*note
+ Options::).
+
+ * The use of `CONVFMT' for controlling the conversion of numbers to
+ strings (*note Conversion::).
+
+ * The concept of a numeric string and tighter comparison rules to go
+ with it (*note Typing and Comparison::).
+
+ * More complete documentation of many of the previously undocumented
+ features of the language.
+
+The following common extensions are not permitted by the POSIX standard:
+
+ * `\x' escape sequences are not recognized (*note Escape
+ Sequences::).
+
+ * Newlines do not act as whitespace to separate fields when `FS' is
+ equal to a single space (*note Fields::).
+
+ * Newlines are not allowed after `?' or `:' (*note Conditional
+ Exp::).
+
+ * The synonym `func' for the keyword `function' is not recognized
+ (*note Definition Syntax::).
+
+ * The operators `**' and `**=' cannot be used in place of `^' and
+ `^=' (*note Arithmetic Ops::, and *Note Assignment Ops::).
+
+ * Specifying `-Ft' on the command line does not set the value of
+ `FS' to be a single TAB character (*note Field Separators::).
+
+ * The `fflush' built-in function is not supported (*note I/O
+ Functions::).
+
+\1f
+File: gawk.info, Node: BTL, Next: POSIX/GNU, Prev: POSIX, Up: Language History
+
+A.4 Extensions in the Bell Laboratories `awk'
+=============================================
+
+Brian Kernighan, one of the original designers of Unix `awk', has made
+his version available via his home page (*note Other Versions::). This
+minor node describes extensions in his version of `awk' that are not in
+POSIX `awk':
+
+ * The `-mf N' and `-mr N' command-line options to set the maximum
+ number of fields and the maximum record size, respectively (*note
+ Options::). As a side note, his `awk' no longer needs these
+ options; it continues to accept them to avoid breaking old
+ programs.
+
+ * The `fflush' built-in function for flushing buffered output (*note
+ I/O Functions::).
+
+ * The `**' and `**=' operators (*note Arithmetic Ops:: and *Note
+ Assignment Ops::).
+
+ * The use of `func' as an abbreviation for `function' (*note
+ Definition Syntax::).
+
+
+The Bell Laboratories `awk' also incorporates the following extensions,
+originally developed for `gawk':
+
+ * The `\x' escape sequence (*note Escape Sequences::).
+
+ * The `/dev/stdin', `/dev/stdout', and `/dev/stderr' special files
+ (*note Special Files::).
+
+ * The ability for `FS' and for the third argument to `split' to be
+ null strings (*note Single Character Fields::).
+
+ * The `nextfile' statement (*note Nextfile Statement::).
+
+ * The ability to delete all of an array at once with `delete ARRAY'
+ (*note Delete::).
+
+\1f
+File: gawk.info, Node: POSIX/GNU, Next: Contributors, Prev: BTL, Up: Language History
+
+A.5 Extensions in `gawk' Not in POSIX `awk'
+===========================================
+
+The GNU implementation, `gawk', adds a large number of features. This
+minor node lists them in the order they were added to `gawk'. They can
+all be disabled with either the `--traditional' or `--posix' options
+(*note Options::).
+
+Version 2.10 of `gawk' introduced the following features:
+
+ * The `AWKPATH' environment variable for specifying a path search for
+ the `-f' command-line option (*note Options::).
+
+ * The `IGNORECASE' variable and its effects (*note
+ Case-sensitivity::).
+
+ * The `/dev/stdin', `/dev/stdout', `/dev/stderr' and `/dev/fd/N'
+ special file names (*note Special Files::).
+
+Version 2.13 of `gawk' introduced the following features:
+
+ * The `FIELDWIDTHS' variable and its effects (*note Constant Size::).
+
+ * The `systime' and `strftime' built-in functions for obtaining and
+ printing timestamps (*note Time Functions::).
+
+ * The `-W lint' option to provide error and portability checking for
+ both the source code and at runtime (*note Options::).
+
+ * The `-W compat' option to turn off the GNU extensions (*note
+ Options::).
+
+ * The `-W posix' option for full POSIX compliance (*note Options::).
+
+Version 2.14 of `gawk' introduced the following feature:
+
+ * The `next file' statement for skipping to the next data file
+ (*note Nextfile Statement::).
+
+Version 2.15 of `gawk' introduced the following features:
+
+ * The `ARGIND' variable, which tracks the movement of `FILENAME'
+ through `ARGV' (*note Built-in Variables::).
+
+ * The `ERRNO' variable, which contains the system error message when
+ `getline' returns -1 or `close' fails (*note Built-in Variables::).
+
+ * The `/dev/pid', `/dev/ppid', `/dev/pgrpid', and `/dev/user' file
+ name interpretation (*note Special Files::).
+
+ * The ability to delete all of an array at once with `delete ARRAY'
+ (*note Delete::).
+
+ * The ability to use GNU-style long-named options that start with
+ `--' (*note Options::).
+
+ * The `--source' option for mixing command-line and library-file
+ source code (*note Options::).
+
+Version 3.0 of `gawk' introduced the following features:
+
+ * `IGNORECASE' changed, now applying to string comparison as well as
+ regexp operations (*note Case-sensitivity::).
+
+ * The `RT' variable that contains the input text that matched `RS'
+ (*note Records::).
+
+ * Full support for both POSIX and GNU regexps (*note Regexp::).
+
+ * The `gensub' function for more powerful text manipulation (*note
+ String Functions::).
+
+ * The `strftime' function acquired a default time format, allowing
+ it to be called with no arguments (*note Time Functions::).
+
+ * The ability for `FS' and for the third argument to `split' to be
+ null strings (*note Single Character Fields::).
+
+ * The ability for `RS' to be a regexp (*note Records::).
+
+ * The `next file' statement became `nextfile' (*note Nextfile
+ Statement::).
+
+ * The `--lint-old' option to warn about constructs that are not
+ available in the original Version 7 Unix version of `awk' (*note
+ V7/SVR3.1::).
+
+ * The `-m' option and the `fflush' function from the Bell
+ Laboratories research version of `awk' (*note Options::; also
+ *note I/O Functions::).
+
+ * The `--re-interval' option to provide interval expressions in
+ regexps (*note Regexp Operators::).
+
+ * The `--traditional' option was added as a better name for
+ `--compat' (*note Options::).
+
+ * The use of GNU Autoconf to control the configuration process
+ (*note Quick Installation::).
+
+ * Amiga support (*note Amiga Installation::).
+
+
+Version 3.1 of `gawk' introduced the following features:
+
+ * The `BINMODE' special variable for non-POSIX systems, which allows
+ binary I/O for input and/or output files (*note PC Using::).
+
+ * The `LINT' special variable, which dynamically controls lint
+ warnings (*note Built-in Variables::).
+
+ * The `PROCINFO' array for providing process-related information
+ (*note Built-in Variables::).
+
+ * The `TEXTDOMAIN' special variable for setting an application's
+ internationalization text domain (*note Built-in Variables::, and
+ *Note Internationalization::).
+
+ * The ability to use octal and hexadecimal constants in `awk'
+ program source code (*note Nondecimal-numbers::).
+
+ * The `|&' operator for two-way I/O to a coprocess (*note Two-way
+ I/O::).
+
+ * The `/inet' special files for TCP/IP networking using `|&' (*note
+ TCP/IP Networking::).
+
+ * The optional second argument to `close' that allows closing one end
+ of a two-way pipe to a coprocess (*note Two-way I/O::).
+
+ * The optional third argument to the `match' function for capturing
+ text-matching subexpressions within a regexp (*note String
+ Functions::).
+
+ * Positional specifiers in `printf' formats for making translations
+ easier (*note Printf Ordering::).
+
+ * The `asort' and `asorti' functions for sorting arrays (*note Array
+ Sorting::).
+
+ * The `bindtextdomain', `dcgettext' and `dcngettext' functions for
+ internationalization (*note Programmer i18n::).
+
+ * The `extension' built-in function and the ability to add new
+ built-in functions dynamically (*note Dynamic Extensions::).
+
+ * The `mktime' built-in function for creating timestamps (*note Time
+ Functions::).
+
+ * The `and', `or', `xor', `compl', `lshift', `rshift', and
+ `strtonum' built-in functions (*note Bitwise Functions::).
+
+ * The support for `next file' as two words was removed completely
+ (*note Nextfile Statement::).
+
+ * The `--dump-variables' option to print a list of all global
+ variables (*note Options::).
+
+ * The `--gen-po' command-line option and the use of a leading
+ underscore to mark strings that should be translated (*note String
+ Extraction::).
+
+ * The `--non-decimal-data' option to allow non-decimal input data
+ (*note Nondecimal Data::).
+
+ * The `--profile' option and `pgawk', the profiling version of
+ `gawk', for producing execution profiles of `awk' programs (*note
+ Profiling::).
+
+ * The `--enable-portals' configuration option to enable special
+ treatment of pathnames that begin with `/p' as BSD portals (*note
+ Portal Files::).
+
+ * The use of GNU Automake to help in standardizing the configuration
+ process (*note Quick Installation::).
+
+ * The use of GNU `gettext' for `gawk''s own message output (*note
+ Gawk I18N::).
+
+ * BeOS support (*note BeOS Installation::).
+
+ * Tandem support (*note Tandem Installation::).
+
+ * The Atari port became officially unsupported (*note Atari
+ Installation::).
+
+ * The source code now uses new-style function definitions, with
+ `ansi2knr' to convert the code on systems with old compilers.
+
+ * The `--disable-lint' configuration option to disable lint checking
+ at compile time (*note Additional Configuration Options::).
+
+ * POSIX compliance for `sub' and `gsub' (*note Gory Details::).
+
+ * The `--exec' option, for use in CGI scripts. (*note Options::).
+
+ * The `length' function was extended to accept an array argument and
+ return the number of elements in the array (*note String
+ Functions::).
+
+
+\1f
+File: gawk.info, Node: Contributors, Prev: POSIX/GNU, Up: Language History
+
+A.6 Major Contributors to `gawk'
+================================
+
+ Always give credit where credit is due.
+ Anonymous
+
+This minor node names the major contributors to `gawk' and/or this
+Info file, in approximate chronological order:
+
+ * Dr. Alfred V. Aho, Dr. Peter J. Weinberger, and Dr. Brian W.
+ Kernighan, all of Bell Laboratories, designed and implemented Unix
+ `awk', from which `gawk' gets the majority of its feature set.
+
+ * Paul Rubin did the initial design and implementation in 1986, and
+ wrote the first draft (around 40 pages) of this Info file.
+
+ * Jay Fenlason finished the initial implementation.
+
+ * Diane Close revised the first draft of this Info file, bringing it
+ to around 90 pages.
+
+ * Richard Stallman helped finish the implementation and the initial
+ draft of this Info file. He is also the founder of the FSF and
+ the GNU project.
+
+ * John Woods contributed parts of the code (mostly fixes) in the
+ initial version of `gawk'.
+
+ * In 1988, David Trueman took over primary maintenance of `gawk',
+ making it compatible with "new" `awk', and greatly improving its
+ performance.
+
+ * Pat Rankin provided the VMS port and its documentation.
+
+ * Conrad Kwok, Scott Garfinkle, and Kent Williams did the initial
+ ports to MS-DOS with various versions of MSC.
+
+ * Hal Peterson provided help in porting `gawk' to Cray systems.
+
+ * Kai Uwe Rommel provided the initial port to OS/2 and its
+ documentation.
+
+ * Michal Jaegermann provided the port to Atari systems and its
+ documentation. He continues to provide portability checking with
+ DEC Alpha systems, and has done a lot of work to make sure `gawk'
+ works on non-32-bit systems.
+
+ * Fred Fish provided the port to Amiga systems and its documentation.
+
+ * Scott Deifik currently maintains the MS-DOS port.
+
+ * Juan Grigera maintains the port to Windows32 systems.
+
+ * Dr. Darrel Hankerson acts as coordinator for the various ports to
+ different PC platforms and creates binary distributions for
+ various PC operating systems. He is also instrumental in keeping
+ the documentation up to date for the various PC platforms.
+
+ * Christos Zoulas provided the `extension' built-in function for
+ dynamically adding new modules.
+
+ * Ju"rgen Kahrs contributed the initial version of the TCP/IP
+ networking code and documentation, and motivated the inclusion of
+ the `|&' operator.
+
+ * Stephen Davies provided the port to Tandem systems and its
+ documentation.
+
+ * Martin Brown provided the port to BeOS and its documentation.
+
+ * Arno Peters did the initial work to convert `gawk' to use GNU
+ Automake and `gettext'.
+
+ * Alan J. Broder provided the initial version of the `asort' function
+ as well as the code for the new optional third argument to the
+ `match' function.
+
+ * Andreas Buening updated the `gawk' port for OS/2.
+
+ Isamu Hasegawa, of IBM in Japan, contributed support for multibyte
+ characters.
+
+ Michael Benzinger contributed the initial code for `switch'
+ statements.
+
+ Patrick T.J. McPhee contributed the code for dynamic loading in
+ Windows32 environments.
+
+ * Arnold Robbins has been working on `gawk' since 1988, at first
+ helping David Trueman, and as the primary maintainer since around
+ 1994.
+
+\1f
+File: gawk.info, Node: Installation, Next: Notes, Prev: Language History, Up: Top
+
+Appendix B Installing `gawk'
+****************************
+
+This appendix provides instructions for installing `gawk' on the
+various platforms that are supported by the developers. The primary
+developer supports GNU/Linux (and Unix), whereas the other ports are
+contributed. *Note Bugs::, for the electronic mail addresses of the
+people who did the respective ports.
+
+* Menu:
+
+* Gawk Distribution:: What is in the `gawk' distribution.
+* Unix Installation:: Installing `gawk' under various
+ versions of Unix.
+* Non-Unix Installation:: Installation on Other Operating Systems.
+* Unsupported:: Systems whose ports are no longer supported.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available `awk'
+ implementations.
+
+\1f
+File: gawk.info, Node: Gawk Distribution, Next: Unix Installation, Up: Installation
+
+B.1 The `gawk' Distribution
+===========================
+
+This minor node describes how to get the `gawk' distribution, how to
+extract it, and then what is in the various files and subdirectories.
+
+* Menu:
+
+* Getting:: How to get the distribution.
+* Extracting:: How to extract the distribution.
+* Distribution contents:: What is in the distribution.
+
+\1f
+File: gawk.info, Node: Getting, Next: Extracting, Up: Gawk Distribution
+
+B.1.1 Getting the `gawk' Distribution
+-------------------------------------
+
+There are three ways to get GNU software:
+
+ * Copy it from someone else who already has it.
+
+ * Order `gawk' directly from the Free Software Foundation. Software
+ distributions are available for Gnu/Linux, Unix, and MS-Windows,
+ in several CD packages. Their address is:
+
+ Free Software Foundation
+ 51 Franklin Street, Fifth Floor
+ Boston, MA 02110-1301 USA
+ Phone: +1-617-542-5942
+ Fax (including Japan): +1-617-542-2652
+ Email: <gnu@gnu.org>
+ URL: `http://www.gnu.org'
+
+ Ordering from the FSF directly contributes to the support of the
+ foundation and to the production of more free software.
+
+ * Retrieve `gawk' by using anonymous `ftp' to the Internet host
+ `ftp.gnu.org', in the directory `/gnu/gawk'.
+
+The GNU software archive is mirrored around the world. The up-to-date
+list of mirror sites is available from the main FSF web site
+(http://www.gnu.org/order/ftp.html). Try to use one of the mirrors;
+they will be less busy, and you can usually find one closer to your
+site.
+
+\1f
+File: gawk.info, Node: Extracting, Next: Distribution contents, Prev: Getting, Up: Gawk Distribution
+
+B.1.2 Extracting the Distribution
+---------------------------------
+
+`gawk' is distributed as a `tar' file compressed with the GNU Zip
+program, `gzip'.
+
+Once you have the distribution (for example, `gawk-3.1.5.tar.gz'), use
+`gzip' to expand the file and then use `tar' to extract it. You can
+use the following pipeline to produce the `gawk' distribution:
+
+ # Under System V, add 'o' to the tar options
+ gzip -d -c gawk-3.1.5.tar.gz | tar -xvpf -
+
+This creates a directory named `gawk-3.1.5' in the current directory.
+
+The distribution file name is of the form `gawk-V.R.P.tar.gz'. The V
+represents the major version of `gawk', the R represents the current
+release of version V, and the P represents a "patch level", meaning
+that minor bugs have been fixed in the release. The current patch
+level is 5, but when retrieving distributions, you should get the
+version with the highest version, release, and patch level. (Note,
+however, that patch levels greater than or equal to 80 denote "beta" or
+nonproduction software; you might not want to retrieve such a version
+unless you don't mind experimenting.) If you are not on a Unix system,
+you need to make other arrangements for getting and extracting the
+`gawk' distribution. You should consult a local expert.
+
+\1f
+File: gawk.info, Node: Distribution contents, Prev: Extracting, Up: Gawk Distribution
+
+B.1.3 Contents of the `gawk' Distribution
+-----------------------------------------
+
+The `gawk' distribution has a number of C source files, documentation
+files, subdirectories, and files related to the configuration process
+(*note Unix Installation::), as well as several subdirectories related
+to different non-Unix operating systems:
+
+Various `.c', `.y', and `.h' files
+ The actual `gawk' source code.
+
+`README'
+`README_d/README.*'
+ Descriptive files: `README' for `gawk' under Unix and the rest for
+ the various hardware and software combinations.
+
+`INSTALL'
+ A file providing an overview of the configuration and installation
+ process.
+
+`ChangeLog'
+ A detailed list of source code changes as bugs are fixed or
+ improvements made.
+
+`NEWS'
+ A list of changes to `gawk' since the last release or patch.
+
+`COPYING'
+ The GNU General Public License.
+
+`FUTURES'
+ A brief list of features and changes being contemplated for future
+ releases, with some indication of the time frame for the feature,
+ based on its difficulty.
+
+`LIMITATIONS'
+ A list of those factors that limit `gawk''s performance. Most of
+ these depend on the hardware or operating system software and are
+ not limits in `gawk' itself.
+
+`POSIX.STD'
+ A description of one area in which the POSIX standard for `awk' is
+ incorrect as well as how `gawk' handles the problem.
+
+`doc/awkforai.txt'
+ A short article describing why `gawk' is a good language for AI
+ (Artificial Intelligence) programming.
+
+`doc/README.card'
+`doc/ad.block'
+`doc/awkcard.in'
+`doc/cardfonts'
+`doc/colors'
+`doc/macros'
+`doc/no.colors'
+`doc/setter.outline'
+ The `troff' source for a five-color `awk' reference card. A
+ modern version of `troff' such as GNU `troff' (`groff') is needed
+ to produce the color version. See the file `README.card' for
+ instructions if you have an older `troff'.
+
+`doc/gawk.1'
+ The `troff' source for a manual page describing `gawk'. This is
+ distributed for the convenience of Unix users.
+
+`doc/gawk.texi'
+ The Texinfo source file for this Info file. It should be
+ processed with TeX to produce a printed document, and with
+ `makeinfo' to produce an Info or HTML file.
+
+`doc/gawk.info'
+ The generated Info file for this Info file.
+
+`doc/gawkinet.texi'
+ The Texinfo source file for *Note Top::. It should be processed
+ with TeX to produce a printed document and with `makeinfo' to
+ produce an Info or HTML file.
+
+`doc/gawkinet.info'
+ The generated Info file for `TCP/IP Internetworking with `gawk''.
+
+`doc/igawk.1'
+ The `troff' source for a manual page describing the `igawk'
+ program presented in *Note Igawk Program::.
+
+`doc/Makefile.in'
+ The input file used during the configuration process to generate
+ the actual `Makefile' for creating the documentation.
+
+`Makefile.am'
+`*/Makefile.am'
+ Files used by the GNU `automake' software for generating the
+ `Makefile.in' files used by `autoconf' and `configure'.
+
+`Makefile.in'
+`acconfig.h'
+`acinclude.m4'
+`aclocal.m4'
+`configh.in'
+`configure.in'
+`configure'
+`custom.h'
+`missing_d/*'
+`m4/*'
+ These files and subdirectories are used when configuring `gawk'
+ for various Unix systems. They are explained in *Note Unix
+ Installation::.
+
+`po/*'
+ The `po' library contains message translations.
+
+`awklib/extract.awk'
+`awklib/Makefile.am'
+`awklib/Makefile.in'
+`awklib/eg/*'
+ The `awklib' directory contains a copy of `extract.awk' (*note
+ Extract Program::), which can be used to extract the sample
+ programs from the Texinfo source file for this Info file. It also
+ contains a `Makefile.in' file, which `configure' uses to generate
+ a `Makefile'. `Makefile.am' is used by GNU Automake to create
+ `Makefile.in'. The library functions from *Note Library
+ Functions::, and the `igawk' program from *Note Igawk Program::,
+ are included as ready-to-use files in the `gawk' distribution.
+ They are installed as part of the installation process. The rest
+ of the programs in this Info file are available in appropriate
+ subdirectories of `awklib/eg'.
+
+`unsupported/atari/*'
+ Files needed for building `gawk' on an Atari ST (*note Atari
+ Installation::, for details).
+
+`unsupported/tandem/*'
+ Files needed for building `gawk' on a Tandem (*note Tandem
+ Installation::, for details).
+
+`posix/*'
+ Files needed for building `gawk' on POSIX-compliant systems.
+
+`pc/*'
+ Files needed for building `gawk' under MS-DOS, MS Windows and OS/2
+ (*note PC Installation::, for details).
+
+`vms/*'
+ Files needed for building `gawk' under VMS (*note VMS
+ Installation::, for details).
+
+`test/*'
+ A test suite for `gawk'. You can use `make check' from the
+ top-level `gawk' directory to run your version of `gawk' against
+ the test suite. If `gawk' successfully passes `make check', then
+ you can be confident of a successful port.
+
+\1f
+File: gawk.info, Node: Unix Installation, Next: Non-Unix Installation, Prev: Gawk Distribution, Up: Installation
+
+B.2 Compiling and Installing `gawk' on Unix
+===========================================
+
+Usually, you can compile and install `gawk' by typing only two
+commands. However, if you use an unusual system, you may need to
+configure `gawk' for your system yourself.
+
+* Menu:
+
+* Quick Installation:: Compiling `gawk' under Unix.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+
+\1f
+File: gawk.info, Node: Quick Installation, Next: Additional Configuration Options, Up: Unix Installation
+
+B.2.1 Compiling `gawk' for Unix
+-------------------------------
+
+After you have extracted the `gawk' distribution, `cd' to
+`gawk-3.1.5'. Like most GNU software, `gawk' is configured
+automatically for your Unix system by running the `configure' program.
+This program is a Bourne shell script that is generated automatically
+using GNU `autoconf'. (The `autoconf' software is described fully
+starting with *Note Top::.)
+
+To configure `gawk', simply run `configure':
+
+ sh ./configure
+
+This produces a `Makefile' and `config.h' tailored to your system. The
+`config.h' file describes various facts about your system. You might
+want to edit the `Makefile' to change the `CFLAGS' variable, which
+controls the command-line options that are passed to the C compiler
+(such as optimization levels or compiling for debugging).
+
+Alternatively, you can add your own values for most `make' variables on
+the command line, such as `CC' and `CFLAGS', when running `configure':
+
+ CC=cc CFLAGS=-g sh ./configure
+
+See the file `INSTALL' in the `gawk' distribution for all the details.
+
+After you have run `configure' and possibly edited the `Makefile', type:
+
+ make
+
+Shortly thereafter, you should have an executable version of `gawk'.
+That's all there is to it! To verify that `gawk' is working properly,
+run `make check'. All of the tests should succeed. If these steps do
+not work, or if any of the tests fail, check the files in the
+`README_d' directory to see if you've found a known problem. If the
+failure is not described there, please send in a bug report (*note
+Bugs::.)
+
+\1f
+File: gawk.info, Node: Additional Configuration Options, Next: Configuration Philosophy, Prev: Quick Installation, Up: Unix Installation
+
+B.2.2 Additional Configuration Options
+--------------------------------------
+
+There are several additional options you may use on the `configure'
+command line when compiling `gawk' from scratch, including:
+
+`--enable-portals'
+ Treat pathnames that begin with `/p' as BSD portal files when
+ doing two-way I/O with the `|&' operator (*note Portal Files::).
+
+`--enable-switch'
+ Enable the recognition and execution of C-style `switch' statements
+ in `awk' programs (*note Switch Statement::.)
+
+`--disable-lint'
+ This option disables all lint checking within `gawk'. The
+ `--lint' and `--lint-old' options (*note Options::) are accepted,
+ but silently do nothing. Similarly, setting the `LINT' variable
+ (*note User-modified::) has no effect on the running `awk' program.
+
+ When used with GCC's automatic dead-code-elimination, this option
+ cuts almost 200K bytes off the size of the `gawk' executable on
+ GNU/Linux x86 systems. Results on other systems and with other
+ compilers are likely to vary. Using this option may bring you
+ some slight performance improvement.
+
+ Using this option will cause some of the tests in the test suite
+ to fail. This option may be removed at a later date.
+
+`--disable-nls'
+ Disable all message-translation facilities. This is usually not
+ desirable, but it may bring you some slight performance
+ improvement.
+
+As of version 3.1.5, the `--with-included-gettext' configuration option
+is no longer available, since `gawk' expects the GNU `gettext' library
+to be installed as an external library.
+
+\1f
+File: gawk.info, Node: Configuration Philosophy, Prev: Additional Configuration Options, Up: Unix Installation
+
+B.2.3 The Configuration Process
+-------------------------------
+
+This minor node is of interest only if you know something about using
+the C language and the Unix operating system.
+
+The source code for `gawk' generally attempts to adhere to formal
+standards wherever possible. This means that `gawk' uses library
+routines that are specified by the ISO C standard and by the POSIX
+operating system interface standard. When using an ISO C compiler,
+function prototypes are used to help improve the compile-time checking.
+
+Many Unix systems do not support all of either the ISO or the POSIX
+standards. The `missing_d' subdirectory in the `gawk' distribution
+contains replacement versions of those functions that are most likely
+to be missing.
+
+The `config.h' file that `configure' creates contains definitions that
+describe features of the particular operating system where you are
+attempting to compile `gawk'. The three things described by this file
+are: what header files are available, so that they can be correctly
+included, what (supposedly) standard functions are actually available
+in your C libraries, and various miscellaneous facts about your variant
+of Unix. For example, there may not be an `st_blksize' element in the
+`stat' structure. In this case, `HAVE_ST_BLKSIZE' is undefined.
+
+It is possible for your C compiler to lie to `configure'. It may do so
+by not exiting with an error when a library function is not available.
+To get around this, edit the file `custom.h'. Use an `#ifdef' that is
+appropriate for your system, and either `#define' any constants that
+`configure' should have defined but didn't, or `#undef' any constants
+that `configure' defined and should not have. `custom.h' is
+automatically included by `config.h'.
+
+It is also possible that the `configure' program generated by
+`autoconf' will not work on your system in some other fashion. If you
+do have a problem, the file `configure.in' is the input for `autoconf'.
+You may be able to change this file and generate a new version of
+`configure' that works on your system (*note Bugs::, for information on
+how to report problems in configuring `gawk'). The same mechanism may
+be used to send in updates to `configure.in' and/or `custom.h'.
+
+\1f
+File: gawk.info, Node: Non-Unix Installation, Next: Unsupported, Prev: Unix Installation, Up: Installation
+
+B.3 Installation on Other Operating Systems
+===========================================
+
+This minor node describes how to install `gawk' on various non-Unix
+systems.
+
+* Menu:
+
+* Amiga Installation:: Installing `gawk' on an Amiga.
+* BeOS Installation:: Installing `gawk' on BeOS.
+* PC Installation:: Installing and Compiling `gawk' on
+ MS-DOS and OS/2.
+* VMS Installation:: Installing `gawk' on VMS.
+
+\1f
+File: gawk.info, Node: Amiga Installation, Next: BeOS Installation, Up: Non-Unix Installation
+
+B.3.1 Installing `gawk' on an Amiga
+-----------------------------------
+
+You can install `gawk' on an Amiga system using a Unix emulation
+environment, available via anonymous `ftp' from `ftp.ninemoons.com' in
+the directory `pub/ade/current'. This includes a shell based on
+`pdksh'. The primary component of this environment is a Unix emulation
+library, `ixemul.lib'.
+
+A more complete distribution for the Amiga is available on the Geek
+Gadgets CD-ROM, available from:
+
+ CRONUS
+ 1840 E. Warner Road #105-265
+ Tempe, AZ 85284 USA
+ US Toll Free: (800) 804-0833
+ Phone: +1-602-491-0442
+ FAX: +1-602-491-0048
+ Email: <info@ninemoons.com>
+ WWW: `http://www.ninemoons.com'
+ Anonymous `ftp' site: `ftp.ninemoons.com'
+
+Once you have the distribution, you can configure `gawk' simply by
+running `configure':
+
+ configure -v m68k-amigaos
+
+Then run `make' and you should be all set! If these steps do not work,
+please send in a bug report (*note Bugs::).
+
+\1f
+File: gawk.info, Node: BeOS Installation, Next: PC Installation, Prev: Amiga Installation, Up: Non-Unix Installation
+
+B.3.2 Installing `gawk' on BeOS
+-------------------------------
+
+Since BeOS DR9, all the tools that you should need to build `gawk' are
+included with BeOS. The process is basically identical to the Unix
+process of running `configure' and then `make'. Full instructions are
+given below.
+
+You can compile `gawk' under BeOS by extracting the standard sources
+and running `configure'. You _must_ specify the location prefix for the
+installation directory. For BeOS DR9 and beyond, the best directory to
+use is `/boot/home/config', so the `configure' command is:
+
+ configure --prefix=/boot/home/config
+
+This installs the compiled application into `/boot/home/config/bin',
+which is already specified in the standard `PATH'.
+
+Once the configuration process is completed, you can run `make', and
+then `make install':
+
+ $ make
+ ...
+ $ make install
+
+BeOS uses `bash' as its shell; thus, you use `gawk' the same way you
+would under Unix. If these steps do not work, please send in a bug
+report (*note Bugs::).
+
+\1f
+File: gawk.info, Node: PC Installation, Next: VMS Installation, Prev: BeOS Installation, Up: Non-Unix Installation
+
+B.3.3 Installation on PC Operating Systems
+------------------------------------------
+
+This minor node covers installation and usage of `gawk' on x86 machines
+running DOS, any version of Windows, or OS/2. In this minor node, the
+term "Windows32" refers to any of Windows-95/98/ME/NT/2000.
+
+The limitations of DOS (and DOS shells under Windows or OS/2) has meant
+that various "DOS extenders" are often used with programs such as
+`gawk'. The varying capabilities of Microsoft Windows 3.1 and
+Windows32 can add to the confusion. For an overview of the
+considerations, please refer to `README_d/README.pc' in the
+distribution.
+
+* Menu:
+
+* PC Binary Installation:: Installing a prepared distribution.
+* PC Compiling:: Compiling `gawk' for MS-DOS, Windows32,
+ and OS/2.
+* PC Dynamic:: Compiling `gawk' for dynamic libraries.
+* PC Using:: Running `gawk' on MS-DOS, Windows32 and
+ OS/2.
+* Cygwin:: Building and running `gawk' for
+ Cygwin.
+
+\1f
+File: gawk.info, Node: PC Binary Installation, Next: PC Compiling, Up: PC Installation
+
+B.3.3.1 Installing a Prepared Distribution for PC Systems
+.........................................................
+
+If you have received a binary distribution prepared by the DOS
+maintainers, then `gawk' and the necessary support files appear under
+the `gnu' directory, with executables in `gnu/bin', libraries in
+`gnu/lib/awk', and manual pages under `gnu/man'. This is designed for
+easy installation to a `/gnu' directory on your drive--however, the
+files can be installed anywhere provided `AWKPATH' is set properly.
+Regardless of the installation directory, the first line of `igawk.cmd'
+and `igawk.bat' (in `gnu/bin') may need to be edited.
+
+The binary distribution contains a separate file describing the
+contents. In particular, it may include more than one version of the
+`gawk' executable.
+
+OS/2 (32 bit, EMX) binary distributions are prepared for the `/usr'
+directory of your preferred drive. Set `UNIXROOT' to your installation
+drive (e.g., `e:') if you want to install `gawk' onto another drive
+than the hardcoded default `c:'. Executables appear in `/usr/bin',
+libraries under `/usr/share/awk', manual pages under `/usr/man',
+Texinfo documentation under `/usr/info' and NLS files under
+`/usr/share/locale'. If you already have a file `/usr/info/dir' from
+another package _do not overwrite it!_ Instead enter the following
+commands at your prompt (replace `x:' by your installation drive):
+
+ install-info --info-dir=x:/usr/info x:/usr/info/gawk.info
+ install-info --info-dir=x:/usr/info x:/usr/info/gawkinet.info
+
+However, the files can be installed anywhere provided `AWKPATH' is set
+properly.
+
+The binary distribution may contain a separate file containing
+additional or more detailed installation instructions.
+
+\1f
+File: gawk.info, Node: PC Compiling, Next: PC Dynamic, Prev: PC Binary Installation, Up: PC Installation
+
+B.3.3.2 Compiling `gawk' for PC Operating Systems
+.................................................
+
+`gawk' can be compiled for MS-DOS, Windows32, and OS/2 using the GNU
+development tools from DJ Delorie (DJGPP; MS-DOS only) or Eberhard
+Mattes (EMX; MS-DOS, Windows32 and OS/2). Microsoft Visual C/C++ can
+be used to build a Windows32 version, and Microsoft C/C++ can be used
+to build 16-bit versions for MS-DOS and OS/2. (As of `gawk' 3.1.2, the
+MSC version doesn't work. However, the maintainer is working on fixing
+it.) The file `README_d/README.pc' in the `gawk' distribution contains
+additional notes, and `pc/Makefile' contains important information on
+compilation options.
+
+To build `gawk' for MS-DOS, Windows32, and OS/2 (16 bit only; for 32 bit
+(EMX) you can use the `configure' script and skip the following
+paragraphs; for details see below), copy the files in the `pc'
+directory (_except_ for `ChangeLog') to the directory with the rest of
+the `gawk' sources. The `Makefile' contains a configuration section
+with comments and may need to be edited in order to work with your
+`make' utility.
+
+The `Makefile' contains a number of targets for building various MS-DOS,
+Windows32, and OS/2 versions. A list of targets is printed if the `make'
+command is given without a target. As an example, to build `gawk' using
+the DJGPP tools, enter `make djgpp'. (The DJGPP tools may be found at
+`ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/'.)
+
+Using `make' to run the standard tests and to install `gawk' requires
+additional Unix-like tools, including `sh', `sed', and `cp'. In order
+to run the tests, the `test/*.ok' files may need to be converted so
+that they have the usual DOS-style end-of-line markers. Most of the
+tests work properly with Stewartson's shell along with the companion
+utilities or appropriate GNU utilities. However, some editing of
+`test/Makefile' is required. It is recommended that you copy the file
+`pc/Makefile.tst' over the file `test/Makefile' as a replacement.
+Details can be found in `README_d/README.pc' and in the file
+`pc/Makefile.tst'.
+
+The 32 bit EMX version of `gawk' works "out of the box" under OS/2. In
+principle, it is possible to compile `gawk' the following way:
+
+ $ ./configure
+ $ make
+
+This is not recommended, though. To get an OMF executable you should
+use the following commands at your `sh' prompt:
+
+ $ CPPFLAGS="-D__ST_MT_ERRNO__"
+ $ export CPPFLAGS
+ $ CFLAGS="-O2 -Zomf -Zmt"
+ $ export CFLAGS
+ $ LDFLAGS="-s -Zcrtdll -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x6000"
+ $ export LDFLAGS
+ $ RANLIB="echo"
+ $ export RANLIB
+ $ ./configure --prefix=c:/usr --without-included-gettext
+ $ make AR=emxomfar
+
+These are just suggestions. You may use any other set of
+(self-consistent) environment variables and compiler flags.
+
+To get an FHS-compliant file hierarchy it is recommended to use the
+additional `configure' options `--infodir=c:/usr/share/info',
+`--mandir=c:/usr/share/man' and `--libexecdir=c:/usr/lib'.
+
+If you use GCC 2.95 it is recommended to use also:
+
+ $ LIBS="-lgcc"
+ $ export LIBS
+
+You can also get an `a.out' executable if you prefer:
+
+ $ CPPFLAGS="-D__ST_MT_ERRNO__"
+ $ export CPPFLAGS
+ $ CFLAGS="-O2 -Zmt"
+ $ export CFLAGS
+ $ LDFLAGS="-s -Zstack 0x6000"
+ $ LIBS="-lgcc"
+ $ unset RANLIB
+ $ ./configure --prefix=c:/usr
+ $ make
+
+ NOTE: Versions later than GCC 2.95, i.e., GCC 3.x using the
+ Innotek libc were not tested.
+
+ NOTE: Even if the compiled `gawk.exe' (`a.out') executable
+ contains a DOS header, it does _not_ work under DOS. To compile an
+ executable that runs under DOS, `"-DPIPES_SIMULATED"' must be
+ added to `CPPFLAGS'. But then some nonstandard extensions of
+ `gawk' (e.g., `|&') do not work!
+
+After compilation the internal tests can be performed. Enter `make
+check CMP="diff -a"' at your command prompt. All tests except for the
+`pid' test are expected to work properly. The `pid' test fails because
+child processes are not started by `fork()'.
+
+`make install' works as expected.
+
+ NOTE: Most OS/2 ports of GNU `make' are not able to handle the
+ Makefiles of this package. If you encounter any problems with
+ `make' try GNU Make 3.79.1 or later versions. You should find the
+ latest version on `http://www.unixos2.org/sw/pub/binary/make/' or
+ on `ftp://hobbes.nmsu.edu/pub/os2/'.
+
+\1f
+File: gawk.info, Node: PC Dynamic, Next: PC Using, Prev: PC Compiling, Up: PC Installation
+
+B.3.3.3 Compiling `gawk' For Dynamic Libraries
+..............................................
+
+To compile `gawk' with dynamic extension support, uncomment the
+definitions of `DYN_FLAGS', `DYN_EXP', `DYN_OBJ', and `DYN_MAKEXP' in
+the configuration section of the `Makefile'. There are two definitions
+for `DYN_MAKEXP': pick the one that matches your target.
+
+To build some of the example extension libraries, `cd' to the extension
+directory and copy `Makefile.pc' to `Makefile'. You can then build
+using the same two targets. To run the example `awk' scripts, you'll
+need to either change the call to the `extension' function to match the
+name of the library (for instance, change `"./ordchr.so"' to
+`"ordchr.dll"' or simply `"ordchr"'), or rename the library to match
+the call (for instance, rename `ordchr.dll' to `ordchr.so').
+
+If you build `gawk.exe' with one compiler but want to build an
+extension library with the other, you need to copy the import library.
+Visual C uses a library called `gawk.lib', while MinGW uses a library
+called `libgawk.a'. These files are equivalent and will interoperate if
+you give them the correct name. The resulting shared libraries are
+also interoperable.
+
+To create your own extension library, you can use the examples as
+models, but you're essentially on your own. Post to `comp.lang.awk' or
+send electronic mail to <ptjm@interlog.com> if you have problems getting
+started. If you need to access functions or variables which are not
+exported by `gawk.exe', add them to `gawkw32.def' and rebuild. You
+should also add `ATTRIBUTE_EXPORTED' to the declaration in `awk.h' of
+any variables you add to `gawkw32.def'.
+
+Note that extension libraries have the name of the `awk' executable
+embedded in them at link time, so they will work only with `gawk.exe'.
+In particular, they won't work if you rename `gawk.exe' to `awk.exe' or
+if you try to use `pgawk.exe'. You can perform profiling by temporarily
+renaming `pgawk.exe' to `gawk.exe'. You can resolve this problem by
+changing the program name in the definition of `DYN_MAKEXP' for your
+compiler.
+
+On Windows32, libraries are sought first in the current directory, then
+in the directory containing `gawk.exe', and finally through the `PATH'
+environment variable.
+
+\1f
+File: gawk.info, Node: PC Using, Next: Cygwin, Prev: PC Dynamic, Up: PC Installation
+
+B.3.3.4 Using `gawk' on PC Operating Systems
+............................................
+
+With the exception of the Cygwin environment, the `|&' operator and
+TCP/IP networking (*note TCP/IP Networking::) are not supported for
+MS-DOS or MS-Windows. EMX (OS/2 only) does support at least the `|&'
+operator.
+
+The OS/2 and MS-DOS versions of `gawk' search for program files as
+described in *Note AWKPATH Variable::. However, semicolons (rather
+than colons) separate elements in the `AWKPATH' variable. If `AWKPATH'
+is not set or is empty, then the default search path for OS/2 (16 bit)
+and MS-DOS versions is `".;c:/lib/awk;c:/gnu/lib/awk"'.
+
+The search path for OS/2 (32 bit, EMX) is determined by the prefix
+directory (most likely `/usr' or `c:/usr') that has been specified as
+an option of the `configure' script like it is the case for the Unix
+versions. If `c:/usr' is the prefix directory then the default search
+path contains `.' and `c:/usr/share/awk'. Additionally, to support
+binary distributions of `gawk' for OS/2 systems whose drive `c:' might
+not support long file names or might not exist at all, there is a
+special environment variable. If `UNIXROOT' specifies a drive then this
+specific drive is also searched for program files. E.g., if `UNIXROOT'
+is set to `e:' the complete default search path is
+`".;c:/usr/share/awk;e:/usr/share/awk"'.
+
+An `sh'-like shell (as opposed to `command.com' under MS-DOS or
+`cmd.exe' under OS/2) may be useful for `awk' programming. Ian
+Stewartson has written an excellent shell for MS-DOS and OS/2, Daisuke
+Aoyama has ported GNU `bash' to MS-DOS using the DJGPP tools, and
+several shells are available for OS/2, including `ksh'. The file
+`README_d/README.pc' in the `gawk' distribution contains information on
+these shells. Users of Stewartson's shell on DOS should examine its
+documentation for handling command lines; in particular, the setting
+for `gawk' in the shell configuration may need to be changed and the
+`ignoretype' option may also be of interest.
+
+Under OS/2 and DOS, `gawk' (and many other text programs) silently
+translate end-of-line `"\r\n"' to `"\n"' on input and `"\n"' to
+`"\r\n"' on output. A special `BINMODE' variable allows control over
+these translations and is interpreted as follows:
+
+ * If `BINMODE' is `"r"', or `(BINMODE & 1)' is nonzero, then binary
+ mode is set on read (i.e., no translations on reads).
+
+ * If `BINMODE' is `"w"', or `(BINMODE & 2)' is nonzero, then binary
+ mode is set on write (i.e., no translations on writes).
+
+ * If `BINMODE' is `"rw"' or `"wr"', binary mode is set for both read
+ and write (same as `(BINMODE & 3)').
+
+ * `BINMODE=NON-NULL-STRING' is the same as `BINMODE=3' (i.e., no
+ translations on reads or writes). However, `gawk' issues a warning
+ message if the string is not one of `"rw"' or `"wr"'.
+
+The modes for standard input and standard output are set one time only
+(after the command line is read, but before processing any of the `awk'
+program). Setting `BINMODE' for standard input or standard output is
+accomplished by using an appropriate `-v BINMODE=N' option on the
+command line. `BINMODE' is set at the time a file or pipe is opened
+and cannot be changed mid-stream.
+
+The name `BINMODE' was chosen to match `mawk' (*note Other Versions::).
+Both `mawk' and `gawk' handle `BINMODE' similarly; however, `mawk' adds
+a `-W BINMODE=N' option and an environment variable that can set
+`BINMODE', `RS', and `ORS'. The files `binmode[1-3].awk' (under
+`gnu/lib/awk' in some of the prepared distributions) have been chosen
+to match `mawk''s `-W BINMODE=N' option. These can be changed or
+discarded; in particular, the setting of `RS' giving the fewest
+"surprises" is open to debate. `mawk' uses `RS = "\r\n"' if binary
+mode is set on read, which is appropriate for files with the DOS-style
+end-of-line.
+
+To illustrate, the following examples set binary mode on writes for
+standard output and other files, and set `ORS' as the "usual" DOS-style
+end-of-line:
+
+ gawk -v BINMODE=2 -v ORS="\r\n" ...
+
+or:
+
+ gawk -v BINMODE=w -f binmode2.awk ...
+
+These give the same result as the `-W BINMODE=2' option in `mawk'. The
+following changes the record separator to `"\r\n"' and sets binary mode
+on reads, but does not affect the mode on standard input:
+
+ gawk -v RS="\r\n" --source "BEGIN { BINMODE = 1 }" ...
+
+or:
+
+ gawk -f binmode1.awk ...
+
+With proper quoting, in the first example the setting of `RS' can be
+moved into the `BEGIN' rule.
+
+\1f
+File: gawk.info, Node: Cygwin, Prev: PC Using, Up: PC Installation
+
+B.3.3.5 Using `gawk' In The Cygwin Environment
+..............................................
+
+`gawk' can be used "out of the box" under Windows if you are using the
+Cygwin environment.(1) This environment provides an excellent
+simulation of Unix, using the GNU tools, such as `bash', the GNU
+Compiler Collection (GCC), GNU Make, and other GNU tools. Compilation
+and installation for Cygwin is the same as for a Unix system:
+
+ tar -xvpzf gawk-3.1.5.tar.gz
+ cd gawk-3.1.5
+ ./configure
+ make
+
+When compared to GNU/Linux on the same system, the `configure' step on
+Cygwin takes considerably longer. However, it does finish, and then
+the `make' proceeds as usual.
+
+ NOTE: The `|&' operator and TCP/IP networking (*note TCP/IP
+ Networking::) are fully supported in the Cygwin environment. This
+ is not true for any other environment for MS-DOS or MS-Windows.
+
+---------- Footnotes ----------
+
+(1) `http://www.cygwin.com'
+
+\1f
+File: gawk.info, Node: VMS Installation, Prev: PC Installation, Up: Non-Unix Installation
+
+B.3.4 How to Compile and Install `gawk' on VMS
+----------------------------------------------
+
+This node describes how to compile and install `gawk' under VMS.
+
+* Menu:
+
+* VMS Compilation:: How to compile `gawk' under VMS.
+* VMS Installation Details:: How to install `gawk' under VMS.
+* VMS Running:: How to run `gawk' under VMS.
+* VMS POSIX:: Alternate instructions for VMS POSIX.
+
+\1f
+File: gawk.info, Node: VMS Compilation, Next: VMS Installation Details, Up: VMS Installation
+
+B.3.4.1 Compiling `gawk' on VMS
+...............................
+
+To compile `gawk' under VMS, there is a `DCL' command procedure that
+issues all the necessary `CC' and `LINK' commands. There is also a
+`Makefile' for use with the `MMS' utility. From the source directory,
+use either:
+
+ $ @[.VMS]VMSBUILD.COM
+
+or:
+
+ $ MMS/DESCRIPTION=[.VMS]DESCRIP.MMS GAWK
+
+Depending upon which C compiler you are using, follow one of the sets
+of instructions in this table:
+
+VAX C V3.x
+ Use either `vmsbuild.com' or `descrip.mms' as is. These use
+ `CC/OPTIMIZE=NOLINE', which is essential for Version 3.0.
+
+VAX C V2.x
+ You must have Version 2.3 or 2.4; older ones won't work. Edit
+ either `vmsbuild.com' or `descrip.mms' according to the comments
+ in them. For `vmsbuild.com', this just entails removing two `!'
+ delimiters. Also edit `config.h' (which is a copy of file
+ `[.config]vms-conf.h') and comment out or delete the two lines
+ `#define __STDC__ 0' and `#define VAXC_BUILTINS' near the end.
+
+GNU C
+ Edit `vmsbuild.com' or `descrip.mms'; the changes are different
+ from those for VAX C V2.x but equally straightforward. No changes
+ to `config.h' are needed.
+
+DEC C
+ Edit `vmsbuild.com' or `descrip.mms' according to their comments.
+ No changes to `config.h' are needed.
+
+`gawk' has been tested under VAX/VMS 5.5-1 using VAX C V3.2, and GNU C
+1.40 and 2.3. It should work without modifications for VMS V4.6 and up.
+
+\1f
+File: gawk.info, Node: VMS Installation Details, Next: VMS Running, Prev: VMS Compilation, Up: VMS Installation
+
+B.3.4.2 Installing `gawk' on VMS
+................................
+
+To install `gawk', all you need is a "foreign" command, which is a
+`DCL' symbol whose value begins with a dollar sign. For example:
+
+ $ GAWK :== $disk1:[gnubin]GAWK
+
+Substitute the actual location of `gawk.exe' for `$disk1:[gnubin]'. The
+symbol should be placed in the `login.com' of any user who wants to run
+`gawk', so that it is defined every time the user logs on.
+Alternatively, the symbol may be placed in the system-wide
+`sylogin.com' procedure, which allows all users to run `gawk'.
+
+Optionally, the help entry can be loaded into a VMS help library:
+
+ $ LIBRARY/HELP SYS$HELP:HELPLIB [.VMS]GAWK.HLP
+
+(You may want to substitute a site-specific help library rather than
+the standard VMS library `HELPLIB'.) After loading the help text, the
+command:
+
+ $ HELP GAWK
+
+provides information about both the `gawk' implementation and the `awk'
+programming language.
+
+The logical name `AWK_LIBRARY' can designate a default location for
+`awk' program files. For the `-f' option, if the specified file name
+has no device or directory path information in it, `gawk' looks in the
+current directory first, then in the directory specified by the
+translation of `AWK_LIBRARY' if the file is not found. If, after
+searching in both directories, the file still is not found, `gawk'
+appends the suffix `.awk' to the filename and retries the file search.
+If `AWK_LIBRARY' is not defined, that portion of the file search fails
+benignly.
+
+\1f
+File: gawk.info, Node: VMS Running, Next: VMS POSIX, Prev: VMS Installation Details, Up: VMS Installation
+
+B.3.4.3 Running `gawk' on VMS
+.............................
+
+Command-line parsing and quoting conventions are significantly different
+on VMS, so examples in this Info file or from other sources often need
+minor changes. They _are_ minor though, and all `awk' programs should
+run correctly.
+
+Here are a couple of trivial tests:
+
+ $ gawk -- "BEGIN {print ""Hello, World!""}"
+ $ gawk -"W" version
+ ! could also be -"W version" or "-W version"
+
+Note that uppercase and mixed-case text must be quoted.
+
+The VMS port of `gawk' includes a `DCL'-style interface in addition to
+the original shell-style interface (see the help entry for details).
+One side effect of dual command-line parsing is that if there is only a
+single parameter (as in the quoted string program above), the command
+becomes ambiguous. To work around this, the normally optional `--'
+flag is required to force Unix style rather than `DCL' parsing. If any
+other dash-type options (or multiple parameters such as data files to
+process) are present, there is no ambiguity and `--' can be omitted.
+
+The default search path, when looking for `awk' program files specified
+by the `-f' option, is `"SYS$DISK:[],AWK_LIBRARY:"'. The logical name
+`AWKPATH' can be used to override this default. The format of
+`AWKPATH' is a comma-separated list of directory specifications. When
+defining it, the value should be quoted so that it retains a single
+translation and not a multitranslation `RMS' searchlist.
+
+\1f
+File: gawk.info, Node: VMS POSIX, Prev: VMS Running, Up: VMS Installation
+
+B.3.4.4 Building and Using `gawk' on VMS POSIX
+..............................................
+
+Ignore the instructions above, although `vms/gawk.hlp' should still be
+made available in a help library. The source tree should be unpacked
+into a container file subsystem rather than into the ordinary VMS
+filesystem. Make sure that the two scripts, `configure' and
+`vms/posix-cc.sh', are executable; use `chmod +x' on them if necessary.
+Then execute the following two commands:
+
+ psx> CC=vms/posix-cc.sh configure
+ psx> make CC=c89 gawk
+
+The first command constructs files `config.h' and `Makefile' out of
+templates, using a script to make the C compiler fit `configure''s
+expectations. The second command compiles and links `gawk' using the C
+compiler directly; ignore any warnings from `make' about being unable
+to redefine `CC'. `configure' takes a very long time to execute, but
+at least it provides incremental feedback as it runs.
+
+This has been tested with VAX/VMS V6.2, VMS POSIX V2.0, and DEC C V5.2.
+
+Once built, `gawk' works like any other shell utility. Unlike the
+normal VMS port of `gawk', no special command-line manipulation is
+needed in the VMS POSIX environment.
+
+\1f
+File: gawk.info, Node: Unsupported, Next: Bugs, Prev: Non-Unix Installation, Up: Installation
+
+B.4 Unsupported Operating System Ports
+======================================
+
+This sections describes systems for which the `gawk' port is no longer
+supported.
+
+* Menu:
+
+* Atari Installation:: Installing `gawk' on the Atari ST.
+* Tandem Installation:: Installing `gawk' on a Tandem.
+
+\1f
+File: gawk.info, Node: Atari Installation, Next: Tandem Installation, Up: Unsupported
+
+B.4.1 Installing `gawk' on the Atari ST
+---------------------------------------
+
+The Atari port is no longer supported. It is included for those who
+might want to use it but it is no longer being actively maintained.
+
+There are no substantial differences when installing `gawk' on various
+Atari models. Compiled `gawk' executables do not require a large
+amount of memory with most `awk' programs, and should run on all
+Motorola processor-based models (called further ST, even if that is not
+exactly right).
+
+In order to use `gawk', you need to have a shell, either text or
+graphics, that does not map all the characters of a command line to
+uppercase. Maintaining case distinction in option flags is very
+important (*note Options::). These days this is the default and it may
+only be a problem for some very old machines. If your system does not
+preserve the case of option flags, you need to upgrade your tools.
+Support for I/O redirection is necessary to make it easy to import
+`awk' programs from other environments. Pipes are nice to have but not
+vital.
+
+* Menu:
+
+* Atari Compiling:: Compiling `gawk' on Atari.
+* Atari Using:: Running `gawk' on Atari.
+
+\1f
+File: gawk.info, Node: Atari Compiling, Next: Atari Using, Up: Atari Installation
+
+B.4.1.1 Compiling `gawk' on the Atari ST
+........................................
+
+A proper compilation of `gawk' sources when `sizeof(int)' differs from
+`sizeof(void *)' requires an ISO C compiler. An initial port was done
+with `gcc'. You may actually prefer executables where `int's are four
+bytes wide but the other variant works as well.
+
+You may need quite a bit of memory when trying to recompile the `gawk'
+sources, as some source files (`regex.c' in particular) are quite big.
+If you run out of memory compiling such a file, try reducing the
+optimization level for this particular file, which may help.
+
+With a reasonable shell (`bash' will do), you have a pretty good chance
+that the `configure' utility will succeed, and in particular if you run
+GNU/Linux, MiNT or a similar operating system. Otherwise sample
+versions of `config.h' and `Makefile.st' are given in the `atari'
+subdirectory and can be edited and copied to the corresponding files in
+the main source directory. Even if `configure' produces something, it
+might be advisable to compare its results with the sample versions and
+possibly make adjustments.
+
+Some `gawk' source code fragments depend on a preprocessor define
+`atarist'. This basically assumes the TOS environment with `gcc'.
+Modify these sections as appropriate if they are not right for your
+environment. Also see the remarks about `AWKPATH' and `envsep' in
+*Note Atari Using::.
+
+As shipped, the sample `config.h' claims that the `system' function is
+missing from the libraries, which is not true, and an alternative
+implementation of this function is provided in
+`unsupported/atari/system.c'. Depending upon your particular
+combination of shell and operating system, you might want to change the
+file to indicate that `system' is available.
+
+\1f
+File: gawk.info, Node: Atari Using, Prev: Atari Compiling, Up: Atari Installation
+
+B.4.1.2 Running `gawk' on the Atari ST
+......................................
+
+An executable version of `gawk' should be placed, as usual, anywhere in
+your `PATH' where your shell can find it.
+
+While executing, the Atari version of `gawk' creates a number of
+temporary files. When using `gcc' libraries for TOS, `gawk' looks for
+either of the environment variables, `TEMP' or `TMPDIR', in that order.
+If either one is found, its value is assumed to be a directory for
+temporary files. This directory must exist, and if you can spare the
+memory, it is a good idea to put it on a RAM drive. If neither `TEMP'
+nor `TMPDIR' are found, then `gawk' uses the current directory for its
+temporary files.
+
+The ST version of `gawk' searches for its program files, as described in
+*Note AWKPATH Variable::. The default value for the `AWKPATH' variable
+is taken from `DEFPATH' defined in `Makefile'. The sample `gcc'/TOS
+`Makefile' for the ST in the distribution sets `DEFPATH' to
+`".,c:\lib\awk,c:\gnu\lib\awk"'. The search path can be modified by
+explicitly setting `AWKPATH' to whatever you want. Note that colons
+cannot be used on the ST to separate elements in the `AWKPATH'
+variable, since they have another reserved meaning. Instead, you must
+use a comma to separate elements in the path. When recompiling, the
+separating character can be modified by initializing the `envsep'
+variable in `unsupported/atari/gawkmisc.atr' to another value.
+
+Although `awk' allows great flexibility in doing I/O redirections from
+within a program, this facility should be used with care on the ST
+running under TOS. In some circumstances, the OS routines for
+file-handle pool processing lose track of certain events, causing the
+computer to crash and requiring a reboot. Often a warm reboot is
+sufficient. Fortunately, this happens infrequently and in rather
+esoteric situations. In particular, avoid having one part of an `awk'
+program using `print' statements explicitly redirected to
+`/dev/stdout', while other `print' statements use the default standard
+output, and a calling shell has redirected standard output to a file.
+
+When `gawk' is compiled with the ST version of `gcc' and its usual
+libraries, it accepts both `/' and `\' as path separators. While this
+is convenient, it should be remembered that this removes one
+technically valid character (`/') from your file name. It may also
+create problems for external programs called via the `system' function,
+which may not support this convention. Whenever it is possible that a
+file created by `gawk' will be used by some other program, use only
+backslashes. Also remember that in `awk', backslashes in strings have
+to be doubled in order to get literal backslashes (*note Escape
+Sequences::).
+
+\1f
+File: gawk.info, Node: Tandem Installation, Prev: Atari Installation, Up: Unsupported
+
+B.4.2 Installing `gawk' on a Tandem
+-----------------------------------
+
+The Tandem port is only minimally supported. The port's contributor no
+longer has access to a Tandem system.
+
+The Tandem port was done on a Cyclone machine running D20. The port is
+pretty clean and all facilities seem to work except for the I/O piping
+facilities (*note Getline/Pipe::, *Note Getline/Variable/Pipe::, and
+*Note Redirection::), which is just too foreign a concept for Tandem.
+
+To build a Tandem executable from source, download all of the files so
+that the file names on the Tandem box conform to the restrictions of
+D20. For example, `array.c' becomes `ARRAYC', and `awk.h' becomes
+`AWKH'. The totally Tandem-specific files are in the `tandem'
+"subvolume" (`unsupported/tandem' in the `gawk' distribution) and
+should be copied to the main source directory before building `gawk'.
+
+The file `compit' can then be used to compile and bind an executable.
+Alas, there is no `configure' or `make'.
+
+Usage is the same as for Unix, except that D20 requires all `{' and `}'
+characters to be escaped with `~' on the command line (but _not_ in
+script files). Also, the standard Tandem syntax for `/in filename,out
+filename/' must be used instead of the usual Unix `<' and `>' for file
+redirection. (Redirection options on `getline', `print' etc., are
+supported.)
+
+The `-mr VAL' option (*note Options::) has been "stolen" to enable
+Tandem users to process fixed-length records with no "end-of-line"
+character. That is, `-mr 74' tells `gawk' to read the input file as
+fixed 74-byte records.
+
+\1f
+File: gawk.info, Node: Bugs, Next: Other Versions, Prev: Unsupported, Up: Installation
+
+B.5 Reporting Problems and Bugs
+===============================
+
+ There is nothing more dangerous than a bored archeologist.
+ The Hitchhiker's Guide to the Galaxy
+
+If you have problems with `gawk' or think that you have found a bug,
+please report it to the developers; we cannot promise to do anything
+but we might well want to fix it.
+
+Before reporting a bug, make sure you have actually found a real bug.
+Carefully reread the documentation and see if it really says you can do
+what you're trying to do. If it's not clear whether you should be able
+to do something or not, report that too; it's a bug in the
+documentation!
+
+Before reporting a bug or trying to fix it yourself, try to isolate it
+to the smallest possible `awk' program and input data file that
+reproduces the problem. Then send us the program and data file, some
+idea of what kind of Unix system you're using, the compiler you used to
+compile `gawk', and the exact results `gawk' gave you. Also say what
+you expected to occur; this helps us decide whether the problem is
+really in the documentation.
+
+Once you have a precise problem, send email to <bug-gawk@gnu.org>.
+
+Please include the version number of `gawk' you are using. You can get
+this information with the command `gawk --version'. Using this address
+automatically sends a carbon copy of your mail to me. If necessary, I
+can be reached directly at <arnold@gnu.org>. The bug reporting address
+is preferred since the email list is archived at the GNU Project. _All
+email should be in English, since that is my native language._
+
+*Caution:* Do _not_ try to report bugs in `gawk' by posting to the
+Usenet/Internet newsgroup `comp.lang.awk'. While the `gawk' developers
+do occasionally read this newsgroup, there is no guarantee that we will
+see your posting. The steps described above are the official
+recognized ways for reporting bugs.
+
+Non-bug suggestions are always welcome as well. If you have questions
+about things that are unclear in the documentation or are just obscure
+features, ask me; I will try to help you out, although I may not have
+the time to fix the problem. You can send me electronic mail at the
+Internet address noted previously.
+
+If you find bugs in one of the non-Unix ports of `gawk', please send an
+electronic mail message to the person who maintains that port. They
+are named in the following list, as well as in the `README' file in the
+`gawk' distribution. Information in the `README' file should be
+considered authoritative if it conflicts with this Info file.
+
+The people maintaining the non-Unix ports of `gawk' are as follows:
+
+Amiga Fred Fish, <fnf@ninemoons.com>.
+BeOS Martin Brown, <mc@whoever.com>.
+MS-DOS Scott Deifik, <scottd@amgen.com> and Darrel
+ Hankerson, <hankedr@mail.auburn.edu>.
+MS-Windows Juan Grigera, <juan@biophnet.unlp.edu.ar>.
+OS/2 The Unix for OS/2 team,
+ <gawk-maintainer@unixos2.org>.
+Tandem Stephen Davies, <scldad@sdc.com.au>.
+VMS Pat Rankin, <rankin@pactechdata.com>.
+
+If your bug is also reproducible under Unix, please send a copy of your
+report to the <bug-gawk@gnu.org> email list as well.
+
+\1f
+File: gawk.info, Node: Other Versions, Prev: Bugs, Up: Installation
+
+B.6 Other Freely Available `awk' Implementations
+================================================
+
+ It's kind of fun to put comments like this in your awk code.
+ `// Do C++ comments work? answer: yes! of course'
+ Michael Brennan
+
+There are three other freely available `awk' implementations. This
+minor node briefly describes where to get them:
+
+Unix `awk'
+ Brian Kernighan has made his implementation of `awk' freely
+ available. You can retrieve this version via the World Wide Web
+ from his home page.(1) It is available in several archive formats:
+
+ Shell archive
+ `http://cm.bell-labs.com/who/bwk/awk.shar'
+
+ Compressed `tar' file
+ `http://cm.bell-labs.com/who/bwk/awk.tar.gz'
+
+ Zip file
+ `http://cm.bell-labs.com/who/bwk/awk.zip'
+
+ This version requires an ISO C (1990 standard) compiler; the C
+ compiler from GCC (the GNU Compiler Collection) works quite nicely.
+
+ *Note BTL::, for a list of extensions in this `awk' that are not
+ in POSIX `awk'.
+
+`mawk'
+ Michael Brennan has written an independent implementation of `awk',
+ called `mawk'. It is available under the GPL (*note Copying::),
+ just as `gawk' is.
+
+ You can get it via anonymous `ftp' to the host `ftp.whidbey.net'.
+ Change directory to `/pub/brennan'. Use "binary" or "image" mode,
+ and retrieve `mawk1.3.3.tar.gz' (or the latest version that is
+ there).
+
+ `gunzip' may be used to decompress this file. Installation is
+ similar to `gawk''s (*note Unix Installation::).
+
+ `mawk' has the following extensions that are not in POSIX `awk':
+
+ * The `fflush' built-in function for flushing buffered output
+ (*note I/O Functions::).
+
+ * The `**' and `**=' operators (*note Arithmetic Ops:: and also
+ see *Note Assignment Ops::).
+
+ * The use of `func' as an abbreviation for `function' (*note
+ Definition Syntax::).
+
+ * The `\x' escape sequence (*note Escape Sequences::).
+
+ * The `/dev/stdout', and `/dev/stderr' special files (*note
+ Special Files::). Use `"-"' instead of `"/dev/stdin"' with
+ `mawk'.
+
+ * The ability for `FS' and for the third argument to `split' to
+ be null strings (*note Single Character Fields::).
+
+ * The ability to delete all of an array at once with `delete
+ ARRAY' (*note Delete::).
+
+ * The ability for `RS' to be a regexp (*note Records::).
+
+ * The `BINMODE' special variable for non-Unix operating systems
+ (*note PC Using::).
+
+ The next version of `mawk' will support `nextfile'.
+
+`awka'
+ Written by Andrew Sumner, `awka' translates `awk' programs into C,
+ compiles them, and links them with a library of functions that
+ provides the core `awk' functionality. It also has a number of
+ extensions.
+
+ The `awk' translator is released under the GPL, and the library is
+ under the LGPL.
+
+ To get `awka', go to `http://awka.sourceforge.net'. You can reach
+ Andrew Sumner at <andrew@zbcom.net>.
+
+`pawk'
+ Nelson H.F. Beebe at the University of Utah has modified the Bell
+ Labs `awk' to provide timing and profiling information. It is
+ different from `pgawk' (*note Profiling::), in that it uses
+ CPU-based profiling, not line-count profiling. You may find it at
+ either `ftp://ftp.math.utah.edu/pub/pawk/pawk-20020210.tar.gz' or
+ `http://www.math.utah.edu/pub/pawk/pawk-20020210.tar.gz'.
+
+
+---------- Footnotes ----------
+
+(1) `http://cm.bell-labs.com/who/bwk'
+
+\1f
+File: gawk.info, Node: Notes, Next: Basic Concepts, Prev: Installation, Up: Top
+
+Appendix C Implementation Notes
+*******************************
+
+This appendix contains information mainly of interest to implementors
+and maintainers of `gawk'. Everything in it applies specifically to
+`gawk' and not to other implementations.
+
+* Menu:
+
+* Compatibility Mode:: How to disable certain `gawk'
+ extensions.
+* Additions:: Making Additions To `gawk'.
+* Dynamic Extensions:: Adding new built-in functions to
+ `gawk'.
+* Future Extensions:: New features that may be implemented one day.
+
+\1f
+File: gawk.info, Node: Compatibility Mode, Next: Additions, Up: Notes
+
+C.1 Downward Compatibility and Debugging
+========================================
+
+*Note POSIX/GNU::, for a summary of the GNU extensions to the `awk'
+language and program. All of these features can be turned off by
+invoking `gawk' with the `--traditional' option or with the `--posix'
+option.
+
+If `gawk' is compiled for debugging with `-DDEBUG', then there is one
+more option available on the command line:
+
+`-W parsedebug'
+`--parsedebug'
+ Prints out the parse stack information as the program is being
+ parsed.
+
+This option is intended only for serious `gawk' developers and not for
+the casual user. It probably has not even been compiled into your
+version of `gawk', since it slows down execution.
+
+\1f
+File: gawk.info, Node: Additions, Next: Dynamic Extensions, Prev: Compatibility Mode, Up: Notes
+
+C.2 Making Additions to `gawk'
+==============================
+
+If you find that you want to enhance `gawk' in a significant fashion,
+you are perfectly free to do so. That is the point of having free
+software; the source code is available and you are free to change it as
+you want (*note Copying::).
+
+This minor node discusses the ways you might want to change `gawk' as
+well as any considerations you should bear in mind.
+
+* Menu:
+
+* Adding Code:: Adding code to the main body of
+ `gawk'.
+* New Ports:: Porting `gawk' to a new operating
+ system.
+
+\1f
+File: gawk.info, Node: Adding Code, Next: New Ports, Up: Additions
+
+C.2.1 Adding New Features
+-------------------------
+
+You are free to add any new features you like to `gawk'. However, if
+you want your changes to be incorporated into the `gawk' distribution,
+there are several steps that you need to take in order to make it
+possible for me to include your changes:
+
+ 1. Before building the new feature into `gawk' itself, consider
+ writing it as an extension module (*note Dynamic Extensions::).
+ If that's not possible, continue with the rest of the steps in
+ this list.
+
+ 2. Get the latest version. It is much easier for me to integrate
+ changes if they are relative to the most recent distributed
+ version of `gawk'. If your version of `gawk' is very old, I may
+ not be able to integrate them at all. (*Note Getting::, for
+ information on getting the latest version of `gawk'.)
+
+ 3. See *note (Version)Top:: standards, GNU Coding Standards. This
+ document describes how GNU software should be written. If you
+ haven't read it, please do so, preferably _before_ starting to
+ modify `gawk'. (The `GNU Coding Standards' are available from the
+ GNU Project's `ftp' site, at
+ `ftp://ftp.gnu.org/gnu/GNUinfo/standards.text'. An HTML version,
+ suitable for reading with a WWW browser, is available at
+ `http://www.gnu.org/prep/standards_toc.html'. Texinfo, Info, and
+ DVI versions are also available.)
+
+ 4. Use the `gawk' coding style. The C code for `gawk' follows the
+ instructions in the `GNU Coding Standards', with minor exceptions.
+ The code is formatted using the traditional "K&R" style,
+ particularly as regards to the placement of braces and the use of
+ tabs. In brief, the coding rules for `gawk' are as follows:
+
+ * Use ANSI/ISO style (prototype) function headers when defining
+ functions.
+
+ * Put the name of the function at the beginning of its own line.
+
+ * Put the return type of the function, even if it is `int', on
+ the line above the line with the name and arguments of the
+ function.
+
+ * Put spaces around parentheses used in control structures
+ (`if', `while', `for', `do', `switch', and `return').
+
+ * Do not put spaces in front of parentheses used in function
+ calls.
+
+ * Put spaces around all C operators and after commas in
+ function calls.
+
+ * Do not use the comma operator to produce multiple side
+ effects, except in `for' loop initialization and increment
+ parts, and in macro bodies.
+
+ * Use real tabs for indenting, not spaces.
+
+ * Use the "K&R" brace layout style.
+
+ * Use comparisons against `NULL' and `'\0'' in the conditions of
+ `if', `while', and `for' statements, as well as in the `case's
+ of `switch' statements, instead of just the plain pointer or
+ character value.
+
+ * Use the `TRUE', `FALSE' and `NULL' symbolic constants and the
+ character constant `'\0'' where appropriate, instead of `1'
+ and `0'.
+
+ * Use the `ISALPHA', `ISDIGIT', etc. macros, instead of the
+ traditional lowercase versions; these macros are better
+ behaved for non-ASCII character sets.
+
+ * Provide one-line descriptive comments for each function.
+
+ * Do not use `#elif'. Many older Unix C compilers cannot handle
+ it.
+
+ * Do not use the `alloca' function for allocating memory off
+ the stack. Its use causes more portability trouble than is
+ worth the minor benefit of not having to free the storage.
+ Instead, use `malloc' and `free'.
+
+ NOTE: If I have to reformat your code to follow the coding
+ style used in `gawk', I may not bother to integrate your
+ changes at all.
+
+ 5. Be prepared to sign the appropriate paperwork. In order for the
+ FSF to distribute your changes, you must either place those
+ changes in the public domain and submit a signed statement to that
+ effect, or assign the copyright in your changes to the FSF. Both
+ of these actions are easy to do and _many_ people have done so
+ already. If you have questions, please contact me (*note Bugs::),
+ or <gnu@gnu.org>.
+
+ 6. Update the documentation. Along with your new code, please supply
+ new sections and/or chapters for this Info file. If at all
+ possible, please use real Texinfo, instead of just supplying
+ unformatted ASCII text (although even that is better than no
+ documentation at all). Conventions to be followed in `GAWK:
+ Effective AWK Programming' are provided after the `@bye' at the
+ end of the Texinfo source file. If possible, please update the
+ `man' page as well.
+
+ You will also have to sign paperwork for your documentation
+ changes.
+
+ 7. Submit changes as context diffs or unified diffs. Use `diff -c -r
+ -N' or `diff -u -r -N' to compare the original `gawk' source tree
+ with your version. (I find context diffs to be more readable but
+ unified diffs are more compact.) I recommend using the GNU
+ version of `diff'. Send the output produced by either run of
+ `diff' to me when you submit your changes. (*Note Bugs::, for the
+ electronic mail information.)
+
+ Using this format makes it easy for me to apply your changes to the
+ master version of the `gawk' source code (using `patch'). If I
+ have to apply the changes manually, using a text editor, I may not
+ do so, particularly if there are lots of changes.
+
+ 8. Include an entry for the `ChangeLog' file with your submission.
+ This helps further minimize the amount of work I have to do,
+ making it easier for me to accept patches.
+
+Although this sounds like a lot of work, please remember that while you
+may write the new code, I have to maintain it and support it. If it
+isn't possible for me to do that with a minimum of extra work, then I
+probably will not.
+
+\1f
+File: gawk.info, Node: New Ports, Prev: Adding Code, Up: Additions
+
+C.2.2 Porting `gawk' to a New Operating System
+----------------------------------------------
+
+If you want to port `gawk' to a new operating system, there are several
+steps:
+
+ 1. Follow the guidelines in *Note Adding Code::, concerning coding
+ style, submission of diffs, and so on.
+
+ 2. When doing a port, bear in mind that your code must coexist
+ peacefully with the rest of `gawk' and the other ports. Avoid
+ gratuitous changes to the system-independent parts of the code. If
+ at all possible, avoid sprinkling `#ifdef's just for your port
+ throughout the code.
+
+ If the changes needed for a particular system affect too much of
+ the code, I probably will not accept them. In such a case, you
+ can, of course, distribute your changes on your own, as long as
+ you comply with the GPL (*note Copying::).
+
+ 3. A number of the files that come with `gawk' are maintained by other
+ people at the Free Software Foundation. Thus, you should not
+ change them unless it is for a very good reason; i.e., changes are
+ not out of the question, but changes to these files are
+ scrutinized extra carefully. The files are `getopt.h', `getopt.c',
+ `getopt1.c', `regex.h', `regex.c', `dfa.h', `dfa.c', `install-sh',
+ and `mkinstalldirs'.
+
+ 4. Be willing to continue to maintain the port. Non-Unix operating
+ systems are supported by volunteers who maintain the code needed
+ to compile and run `gawk' on their systems. If noone volunteers to
+ maintain a port, it becomes unsupported and it may be necessary to
+ remove it from the distribution.
+
+ 5. Supply an appropriate `gawkmisc.???' file. Each port has its own
+ `gawkmisc.???' that implements certain operating system specific
+ functions. This is cleaner than a plethora of `#ifdef's scattered
+ throughout the code. The `gawkmisc.c' in the main source
+ directory includes the appropriate `gawkmisc.???' file from each
+ subdirectory. Be sure to update it as well.
+
+ Each port's `gawkmisc.???' file has a suffix reminiscent of the
+ machine or operating system for the port--for example,
+ `pc/gawkmisc.pc' and `vms/gawkmisc.vms'. The use of separate
+ suffixes, instead of plain `gawkmisc.c', makes it possible to move
+ files from a port's subdirectory into the main subdirectory,
+ without accidentally destroying the real `gawkmisc.c' file.
+ (Currently, this is only an issue for the PC operating system
+ ports.)
+
+ 6. Supply a `Makefile' as well as any other C source and header files
+ that are necessary for your operating system. All your code
+ should be in a separate subdirectory, with a name that is the same
+ as, or reminiscent of, either your operating system or the
+ computer system. If possible, try to structure things so that it
+ is not necessary to move files out of the subdirectory into the
+ main source directory. If that is not possible, then be sure to
+ avoid using names for your files that duplicate the names of files
+ in the main source directory.
+
+ 7. Update the documentation. Please write a section (or sections)
+ for this Info file describing the installation and compilation
+ steps needed to compile and/or install `gawk' for your system.
+
+ 8. Be prepared to sign the appropriate paperwork. In order for the
+ FSF to distribute your code, you must either place your code in
+ the public domain and submit a signed statement to that effect, or
+ assign the copyright in your code to the FSF. Both of these
+ actions are easy to do and _many_ people have done so already. If
+ you have questions, please contact me, or <gnu@gnu.org>.
+
+Following these steps makes it much easier to integrate your changes
+into `gawk' and have them coexist happily with other operating systems'
+code that is already there.
+
+In the code that you supply and maintain, feel free to use a coding
+style and brace layout that suits your taste.
+
+\1f
+File: gawk.info, Node: Dynamic Extensions, Next: Future Extensions, Prev: Additions, Up: Notes
+
+C.3 Adding New Built-in Functions to `gawk'
+===========================================
+
+ Danger Will Robinson! Danger!!
+ Warning! Warning!
+ The Robot
+
+Beginning with `gawk' 3.1, it is possible to add new built-in functions
+to `gawk' using dynamically loaded libraries. This facility is
+available on systems (such as GNU/Linux) that support the `dlopen' and
+`dlsym' functions. This minor node describes how to write and use
+dynamically loaded extensions for `gawk'. Experience with programming
+in C or C++ is necessary when reading this minor node.
+
+*Caution:* The facilities described in this minor node are very much
+subject to change in a future `gawk' release. Be aware that you may
+have to re-do everything, perhaps from scratch, at some future time.
+
+*Caution:* If you have written your own dynamic extensions, be sure to
+recompile them for each new `gawk' release. There is no guarantee of
+binary compatibility between different releases, no will there ever be
+such a guarantee.
+
+* Menu:
+
+* Internals:: A brief look at some `gawk' internals.
+* Sample Library:: A example of new functions.
+
+\1f
+File: gawk.info, Node: Internals, Next: Sample Library, Up: Dynamic Extensions
+
+C.3.1 A Minimal Introduction to `gawk' Internals
+------------------------------------------------
+
+The truth is that `gawk' was not designed for simple extensibility.
+The facilities for adding functions using shared libraries work, but
+are something of a "bag on the side." Thus, this tour is brief and
+simplistic; would-be `gawk' hackers are encouraged to spend some time
+reading the source code before trying to write extensions based on the
+material presented here. Of particular note are the files `awk.h',
+`builtin.c', and `eval.c'. Reading `awkgram.y' in order to see how the
+parse tree is built would also be of use.
+
+With the disclaimers out of the way, the following types, structure
+members, functions, and macros are declared in `awk.h' and are of use
+when writing extensions. The next minor node shows how they are used:
+
+`AWKNUM'
+ An `AWKNUM' is the internal type of `awk' floating-point numbers.
+ Typically, it is a C `double'.
+
+`NODE'
+ Just about everything is done using objects of type `NODE'. These
+ contain both strings and numbers, as well as variables and arrays.
+
+`AWKNUM force_number(NODE *n)'
+ This macro forces a value to be numeric. It returns the actual
+ numeric value contained in the node. It may end up calling an
+ internal `gawk' function.
+
+`void force_string(NODE *n)'
+ This macro guarantees that a `NODE''s string value is current. It
+ may end up calling an internal `gawk' function. It also
+ guarantees that the string is zero-terminated.
+
+`size_t get_curfunc_arg_count(void)'
+ This function returns the actual number of parameters passed to
+ the current function. Inside the code of an extension this can be
+ used to determine the maximum index which is safe to use with
+ `stack_ptr'. If this value is greater than `tree->param_cnt', the
+ function was called incorrectly from the `awk' program.
+
+ *Caution:* This function is new as of `gawk' 3.1.4.
+
+`n->param_cnt'
+ Inside an extension function, this is the maximum number of
+ expected parameters, as set by the `make_builtin' function.
+
+`n->stptr'
+`n->stlen'
+ The data and length of a `NODE''s string value, respectively. The
+ string is _not_ guaranteed to be zero-terminated. If you need to
+ pass the string value to a C library function, save the value in
+ `n->stptr[n->stlen]', assign `'\0'' to it, call the routine, and
+ then restore the value.
+
+`n->type'
+ The type of the `NODE'. This is a C `enum'. Values should be
+ either `Node_var' or `Node_var_array' for function parameters.
+
+`n->vname'
+ The "variable name" of a node. This is not of much use inside
+ externally written extensions.
+
+`void assoc_clear(NODE *n)'
+ Clears the associative array pointed to by `n'. Make sure that
+ `n->type == Node_var_array' first.
+
+`NODE **assoc_lookup(NODE *symbol, NODE *subs, int reference)'
+ Finds, and installs if necessary, array elements. `symbol' is the
+ array, `subs' is the subscript. This is usually a value created
+ with `tmp_string' (see below). `reference' should be `TRUE' if it
+ is an error to use the value before it is created. Typically,
+ `FALSE' is the correct value to use from extension functions.
+
+`NODE *make_string(char *s, size_t len)'
+ Take a C string and turn it into a pointer to a `NODE' that can be
+ stored appropriately. This is permanent storage; understanding of
+ `gawk' memory management is helpful.
+
+`NODE *make_number(AWKNUM val)'
+ Take an `AWKNUM' and turn it into a pointer to a `NODE' that can
+ be stored appropriately. This is permanent storage; understanding
+ of `gawk' memory management is helpful.
+
+`NODE *tmp_string(char *s, size_t len);'
+ Take a C string and turn it into a pointer to a `NODE' that can be
+ stored appropriately. This is temporary storage; understanding of
+ `gawk' memory management is helpful.
+
+`NODE *tmp_number(AWKNUM val)'
+ Take an `AWKNUM' and turn it into a pointer to a `NODE' that can
+ be stored appropriately. This is temporary storage; understanding
+ of `gawk' memory management is helpful.
+
+`NODE *dupnode(NODE *n)'
+ Duplicate a node. In most cases, this increments an internal
+ reference count instead of actually duplicating the entire `NODE';
+ understanding of `gawk' memory management is helpful.
+
+`void free_temp(NODE *n)'
+ This macro releases the memory associated with a `NODE' allocated
+ with `tmp_string' or `tmp_number'. Understanding of `gawk' memory
+ management is helpful.
+
+`void make_builtin(char *name, NODE *(*func)(NODE *), int count)'
+ Register a C function pointed to by `func' as new built-in
+ function `name'. `name' is a regular C string. `count' is the
+ maximum number of arguments that the function takes. The function
+ should be written in the following manner:
+
+ /* do_xxx --- do xxx function for gawk */
+
+ NODE *
+ do_xxx(NODE *tree)
+ {
+ ...
+ }
+
+`NODE *get_argument(NODE *tree, int i)'
+ This function is called from within a C extension function to get
+ the `i'-th argument from the function call. The first argument is
+ argument zero.
+
+`NODE *get_actual_argument(NODE *tree, unsigned int i,'
+` int optional, int wantarray);'
+ This function retrieves a particular argument `i'. `wantarray' is
+ `TRUE' if the argument should be an array, `FALSE' otherwise. If
+ `optional' is `TRUE', the argument need not have been supplied.
+ If it wasn't, the return value is `NULL'. It is a fatal error if
+ `optional' is `TRUE' but the argument was not provided.
+
+ *Caution:* This function is new as of `gawk' 3.1.4.
+
+`get_scalar_argument(t, i, opt)'
+ This is a convenience macro that calls `get_actual_argument'.
+
+ *Caution:* This macro is new as of `gawk' 3.1.4.
+
+`get_array_argument(t, i, opt)'
+ This is a convenience macro that calls `get_actual_argument'.
+
+ *Caution:* This macro is new as of `gawk' 3.1.4.
+
+`void set_value(NODE *tree)'
+ This function is called from within a C extension function to set
+ the return value from the extension function. This value is what
+ the `awk' program sees as the return value from the new `awk'
+ function.
+
+`void update_ERRNO(void)'
+ This function is called from within a C extension function to set
+ the value of `gawk''s `ERRNO' variable, based on the current value
+ of the C `errno' variable. It is provided as a convenience.
+
+`void update_ERRNO_saved(int errno_saved)'
+ This function is called from within a C extension function to set
+ the value of `gawk''s `ERRNO' variable, based on the saved value
+ of the C `errno' variable provided as the argument. It is
+ provided as a convenience.
+
+ *Caution:* This function is new as of `gawk' 3.1.5.
+
+`void register_deferred_variable(const char *name, NODE *(*load_func)(void))'
+ This function is called to register a function to be called when a
+ reference to an undefined variable with the given name is
+ encountered. The callback function will never be called if the
+ variable exists already, so, unless the calling code is running at
+ program startup, it should first check whether a variable of the
+ given name already exists. The argument function must return a
+ pointer to a NODE containing the newly created variable. This
+ function is used to implement the builtin `ENVIRON' and `PROCINFO'
+ variables, so you can refer to them for examples.
+
+ *Caution:* This function is new as of `gawk' 3.1.5.
+
+`void register_open_hook(void *(*open_func)(IOBUF *))'
+ This function is called to register a function to be called
+ whenever a new data file is opened, leading to the creation of an
+ `IOBUF' structure in `iop_alloc'. After creating the new `IOBUF',
+ `iop_alloc' will call (in reverse order of registration, so the
+ last function registered is called first) each open hook until one
+ returns non-NULL. If any hook returns a non-NULL value, that
+ value is assigned to the `IOBUF''s `opaque' field (which will
+ presumably point to a structure containing additional state
+ associated with the input processing), and no further open hooks
+ are called.
+
+ The function called will most likely want to set the `IOBUF'
+ `get_record' method to indicate that future input records should
+ be retrieved by calling that method instead of using the standard
+ `gawk' input processing.
+
+ And the function will also probably want to set the `IOBUF'
+ `close_func' method to be called when the file is closed to clean
+ up any state associated with the input.
+
+ Finally, hook functions should be prepared to receive an `IOBUF'
+ structure where the `fd' field is set to `INVALID_HANDLE', meaning
+ that `gawk' was not able to open the file itself. In this case,
+ the hook function must be able to successfully open the file and
+ place a valid file descriptor there.
+
+ Currently, for example, the hook function facility is used to
+ implement the XML parser shared library extension. For more info,
+ please look in `awk.h' and in `io.c'.
+
+ *Caution:* This function is new as of `gawk' 3.1.5.
+
+An argument that is supposed to be an array needs to be handled with
+some extra code, in case the array being passed in is actually from a
+function parameter.
+
+In versions of `gawk' up to and including 3.1.2, the following
+boilerplate code shows how to do this:
+
+ NODE *the_arg;
+
+ the_arg = get_argument(tree, 2); /* assume need 3rd arg, 0-based */
+
+ /* if a parameter, get it off the stack */
+ if (the_arg->type == Node_param_list)
+ the_arg = stack_ptr[the_arg->param_cnt];
+
+ /* parameter referenced an array, get it */
+ if (the_arg->type == Node_array_ref)
+ the_arg = the_arg->orig_array;
+
+ /* check type */
+ if (the_arg->type != Node_var && the_arg->type != Node_var_array)
+ fatal("newfunc: third argument is not an array");
+
+ /* force it to be an array, if necessary, clear it */
+ the_arg->type = Node_var_array;
+ assoc_clear(the_arg);
+
+For versions 3.1.3 and later, the internals changed. In particular,
+the interface was actually _simplified_ drastically. The following
+boilerplate code now suffices:
+
+ NODE *the_arg;
+
+ the_arg = get_argument(tree, 2); /* assume need 3rd arg, 0-based */
+
+ /* force it to be an array: */
+ the_arg = get_array(the_arg);
+
+ /* if necessary, clear it: */
+ assoc_clear(the_arg);
+
+As of version 3.1.4, the internals improved again, and became even
+simpler:
+
+ NODE *the_arg;
+
+ the_arg = get_array_argument(tree, 2, FALSE); /* assume need 3rd arg, 0-based */
+
+Again, you should spend time studying the `gawk' internals; don't just
+blindly copy this code.
+
+\1f
+File: gawk.info, Node: Sample Library, Prev: Internals, Up: Dynamic Extensions
+
+C.3.2 Directory and File Operation Built-ins
+--------------------------------------------
+
+Two useful functions that are not in `awk' are `chdir' (so that an
+`awk' program can change its directory) and `stat' (so that an `awk'
+program can gather information about a file). This minor node
+implements these functions for `gawk' in an external extension library.
+
+* Menu:
+
+* Internal File Description:: What the new functions will do.
+* Internal File Ops:: The code for internal file operations.
+* Using Internal File Ops:: How to use an external extension.
+
+\1f
+File: gawk.info, Node: Internal File Description, Next: Internal File Ops, Up: Sample Library
+
+C.3.2.1 Using `chdir' and `stat'
+................................
+
+This minor node shows how to use the new functions at the `awk' level
+once they've been integrated into the running `gawk' interpreter.
+Using `chdir' is very straightforward. It takes one argument, the new
+directory to change to:
+
+ ...
+ newdir = "/home/arnold/funstuff"
+ ret = chdir(newdir)
+ if (ret < 0) {
+ printf("could not change to %s: %s\n",
+ newdir, ERRNO) > "/dev/stderr"
+ exit 1
+ }
+ ...
+
+The return value is negative if the `chdir' failed, and `ERRNO' (*note
+Built-in Variables::) is set to a string indicating the error.
+
+Using `stat' is a bit more complicated. The C `stat' function fills in
+a structure that has a fair amount of information. The right way to
+model this in `awk' is to fill in an associative array with the
+appropriate information:
+
+ file = "/home/arnold/.profile"
+ fdata[1] = "x" # force `fdata' to be an array
+ ret = stat(file, fdata)
+ if (ret < 0) {
+ printf("could not stat %s: %s\n",
+ file, ERRNO) > "/dev/stderr"
+ exit 1
+ }
+ printf("size of %s is %d bytes\n", file, fdata["size"])
+
+The `stat' function always clears the data array, even if the `stat'
+fails. It fills in the following elements:
+
+`"name"'
+ The name of the file that was `stat''ed.
+
+`"dev"'
+`"ino"'
+ The file's device and inode numbers, respectively.
+
+`"mode"'
+ The file's mode, as a numeric value. This includes both the file's
+ type and its permissions.
+
+`"nlink"'
+ The number of hard links (directory entries) the file has.
+
+`"uid"'
+`"gid"'
+ The numeric user and group ID numbers of the file's owner.
+
+`"size"'
+ The size in bytes of the file.
+
+`"blocks"'
+ The number of disk blocks the file actually occupies. This may not
+ be a function of the file's size if the file has holes.
+
+`"atime"'
+`"mtime"'
+`"ctime"'
+ The file's last access, modification, and inode update times,
+ respectively. These are numeric timestamps, suitable for
+ formatting with `strftime' (*note Built-in::).
+
+`"pmode"'
+ The file's "printable mode." This is a string representation of
+ the file's type and permissions, such as what is produced by `ls
+ -l'--for example, `"drwxr-xr-x"'.
+
+`"type"'
+ A printable string representation of the file's type. The value
+ is one of the following:
+
+ `"blockdev"'
+ `"chardev"'
+ The file is a block or character device ("special file").
+
+ `"directory"'
+ The file is a directory.
+
+ `"fifo"'
+ The file is a named-pipe (also known as a FIFO).
+
+ `"file"'
+ The file is just a regular file.
+
+ `"socket"'
+ The file is an `AF_UNIX' ("Unix domain") socket in the
+ filesystem.
+
+ `"symlink"'
+ The file is a symbolic link.
+
+Several additional elements may be present depending upon the operating
+system and the type of the file. You can test for them in your `awk'
+program by using the `in' operator (*note Reference to Elements::):
+
+`"blksize"'
+ The preferred block size for I/O to the file. This field is not
+ present on all POSIX-like systems in the C `stat' structure.
+
+`"linkval"'
+ If the file is a symbolic link, this element is the name of the
+ file the link points to (i.e., the value of the link).
+
+`"rdev"'
+`"major"'
+`"minor"'
+ If the file is a block or character device file, then these values
+ represent the numeric device number and the major and minor
+ components of that number, respectively.
+
+\1f
+File: gawk.info, Node: Internal File Ops, Next: Using Internal File Ops, Prev: Internal File Description, Up: Sample Library
+
+C.3.2.2 C Code for `chdir' and `stat'
+.....................................
+
+Here is the C code for these extensions. They were written for
+GNU/Linux. The code needs some more work for complete portability to
+other POSIX-compliant systems:(1)
+
+ #include "awk.h"
+
+ #include <sys/sysmacros.h>
+
+ /* do_chdir --- provide dynamically loaded
+ chdir() builtin for gawk */
+
+ static NODE *
+ do_chdir(tree)
+ NODE *tree;
+ {
+ NODE *newdir;
+ int ret = -1;
+
+ if (do_lint && get_curfunc_arg_count() != 1)
+ lintwarn("chdir: called with incorrect number of arguments");
+
+ newdir = get_scalar_argument(tree, 0);
+
+The file includes the `"awk.h"' header file for definitions for the
+`gawk' internals. It includes `<sys/sysmacros.h>' for access to the
+`major' and `minor' macros.
+
+By convention, for an `awk' function `foo', the function that
+implements it is called `do_foo'. The function should take a `NODE *'
+argument, usually called `tree', that represents the argument list to
+the function. The `newdir' variable represents the new directory to
+change to, retrieved with `get_argument'. Note that the first argument
+is numbered zero.
+
+This code actually accomplishes the `chdir'. It first forces the
+argument to be a string and passes the string value to the `chdir'
+system call. If the `chdir' fails, `ERRNO' is updated. The result of
+`force_string' has to be freed with `free_temp':
+
+ (void) force_string(newdir);
+ ret = chdir(newdir->stptr);
+ if (ret < 0)
+ update_ERRNO();
+ free_temp(newdir);
+
+Finally, the function returns the return value to the `awk' level,
+using `set_value'. Then it must return a value from the call to the new
+built-in (this value ignored by the interpreter):
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+ }
+
+The `stat' built-in is more involved. First comes a function that
+turns a numeric mode into a printable representation (e.g., 644 becomes
+`-rw-r--r--'). This is omitted here for brevity:
+
+ /* format_mode --- turn a stat mode field
+ into something readable */
+
+ static char *
+ format_mode(fmode)
+ unsigned long fmode;
+ {
+ ...
+ }
+
+Next comes the actual `do_stat' function itself. First come the
+variable declarations and argument checking:
+
+ /* do_stat --- provide a stat() function for gawk */
+
+ static NODE *
+ do_stat(tree)
+ NODE *tree;
+ {
+ NODE *file, *array;
+ struct stat sbuf;
+ int ret;
+ NODE **aptr;
+ char *pmode; /* printable mode */
+ char *type = "unknown";
+
+
+ if (do_lint && get_curfunc_arg_count() > 2)
+ lintwarn("stat: called with too many arguments");
+
+Then comes the actual work. First, we get the arguments. Then, we
+always clear the array. To get the file information, we use `lstat',
+in case the file is a symbolic link. If there's an error, we set
+`ERRNO' and return:
+
+ /* directory is first arg, array to hold results is second */
+ file = get_scalar_argument(tree, 0, FALSE);
+ array = get_array_argument(tree, 1, FALSE);
+
+ /* empty out the array */
+ assoc_clear(array);
+
+ /* lstat the file, if error, set ERRNO and return */
+ (void) force_string(file);
+ ret = lstat(file->stptr, & sbuf);
+ if (ret < 0) {
+ update_ERRNO();
+
+ set_value(tmp_number((AWKNUM) ret));
+
+ free_temp(file);
+ return tmp_number((AWKNUM) 0);
+ }
+
+Now comes the tedious part: filling in the array. Only a few of the
+calls are shown here, since they all follow the same pattern:
+
+ /* fill in the array */
+ aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
+ *aptr = dupnode(file);
+
+ aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mode);
+
+ aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
+ pmode = format_mode(sbuf.st_mode);
+ *aptr = make_string(pmode, strlen(pmode));
+
+When done, we free the temporary value containing the file name, set
+the return value, and return:
+
+ free_temp(file);
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+ }
+
+Finally, it's necessary to provide the "glue" that loads the new
+function(s) into `gawk'. By convention, each library has a routine
+named `dlload' that does the job:
+
+ /* dlload --- load new builtins in this library */
+
+ NODE *
+ dlload(tree, dl)
+ NODE *tree;
+ void *dl;
+ {
+ make_builtin("chdir", do_chdir, 1);
+ make_builtin("stat", do_stat, 2);
+ return tmp_number((AWKNUM) 0);
+ }
+
+And that's it! As an exercise, consider adding functions to implement
+system calls such as `chown', `chmod', and `umask'.
+
+---------- Footnotes ----------
+
+(1) This version is edited slightly for presentation. The complete
+version can be found in `extension/filefuncs.c' in the `gawk'
+distribution.
+
+\1f
+File: gawk.info, Node: Using Internal File Ops, Prev: Internal File Ops, Up: Sample Library
+
+C.3.2.3 Integrating the Extensions
+..................................
+
+Now that the code is written, it must be possible to add it at runtime
+to the running `gawk' interpreter. First, the code must be compiled.
+Assuming that the functions are in a file named `filefuncs.c', and IDIR
+is the location of the `gawk' include files, the following steps create
+a GNU/Linux shared library:
+
+ $ gcc -shared -DHAVE_CONFIG_H -c -O -g -IIDIR filefuncs.c
+ $ ld -o filefuncs.so -shared filefuncs.o
+
+Once the library exists, it is loaded by calling the `extension'
+built-in function. This function takes two arguments: the name of the
+library to load and the name of a function to call when the library is
+first loaded. This function adds the new functions to `gawk'. It
+returns the value returned by the initialization function within the
+shared library:
+
+ # file testff.awk
+ BEGIN {
+ extension("./filefuncs.so", "dlload")
+
+ chdir(".") # no-op
+
+ data[1] = 1 # force `data' to be an array
+ print "Info for 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"])
+ }
+
+Here are the results of running the program:
+
+ $ gawk -f testff.awk
+ -| Info for testff.awk
+ -| ret = 0
+ -| data["blksize"] = 4096
+ -| data["mtime"] = 932361936
+ -| data["mode"] = 33188
+ -| data["type"] = file
+ -| data["dev"] = 2065
+ -| data["gid"] = 10
+ -| data["ino"] = 878597
+ -| data["ctime"] = 971431797
+ -| data["blocks"] = 2
+ -| data["nlink"] = 1
+ -| data["name"] = testff.awk
+ -| data["atime"] = 971608519
+ -| data["pmode"] = -rw-r--r--
+ -| data["size"] = 607
+ -| data["uid"] = 2076
+ -| testff.awk modified: 07 19 99 08:25:36
+
+\1f
+File: gawk.info, Node: Future Extensions, Prev: Dynamic Extensions, Up: Notes
+
+C.4 Probable Future Extensions
+==============================
+
+ AWK is a language similar to PERL, only considerably more elegant.
+ Arnold Robbins
+
+ Hey!
+ Larry Wall
+
+This minor node briefly lists extensions and possible improvements that
+indicate the directions we are currently considering for `gawk'. The
+file `FUTURES' in the `gawk' distribution lists these extensions as
+well.
+
+Following is a list of probable future changes visible at the `awk'
+language level:
+
+Loadable module interface
+ It is not clear that the `awk'-level interface to the modules
+ facility is as good as it should be. The interface needs to be
+ redesigned, particularly taking namespace issues into account, as
+ well as possibly including issues such as library search path order
+ and versioning.
+
+`RECLEN' variable for fixed-length records
+ Along with `FIELDWIDTHS', this would speed up the processing of
+ fixed-length records. `PROCINFO["RS"]' would be `"RS"' or
+ `"RECLEN"', depending upon which kind of record processing is in
+ effect.
+
+Additional `printf' specifiers
+ The 1999 ISO C standard added a number of additional `printf'
+ format specifiers. These should be evaluated for possible
+ inclusion in `gawk'.
+
+Databases
+ It may be possible to map a GDBM/NDBM/SDBM file into an `awk'
+ array.
+
+More `lint' warnings
+ There are more things that could be checked for portability.
+
+Following is a list of probable improvements that will make `gawk''s
+source code easier to work with:
+
+Loadable module mechanics
+ The current extension mechanism works (*note Dynamic Extensions::),
+ but is rather primitive. It requires a fair amount of manual work
+ to create and integrate a loadable module. Nor is the current
+ mechanism as portable as might be desired. The GNU `libtool'
+ package provides a number of features that would make using
+ loadable modules much easier. `gawk' should be changed to use
+ `libtool'.
+
+Loadable module internals
+ The API to its internals that `gawk' "exports" should be revised.
+ Too many things are needlessly exposed. A new API should be
+ designed and implemented to make module writing easier.
+
+Better array subscript management
+ `gawk''s management of array subscript storage could use revamping,
+ so that using the same value to index multiple arrays only stores
+ one copy of the index value.
+
+Integrating the DBUG library
+ Integrating Fred Fish's DBUG library would be helpful during
+ development, but it's a lot of work to do.
+
+Following is a list of probable improvements that will make `gawk'
+perform better:
+
+Compilation of `awk' programs
+ `gawk' uses a Bison (YACC-like) parser to convert the script given
+ it into a syntax tree; the syntax tree is then executed by a
+ simple recursive evaluator. This method incurs a lot of overhead,
+ since the recursive evaluator performs many procedure calls to do
+ even the simplest things.
+
+ It should be possible for `gawk' to convert the script's parse tree
+ into a C program which the user would then compile, using the
+ normal C compiler and a special `gawk' library to provide all the
+ needed functions (regexps, fields, associative arrays, type
+ coercion, and so on).
+
+ An easier possibility might be for an intermediate phase of `gawk'
+ to convert the parse tree into a linear byte code form like the
+ one used in GNU Emacs Lisp. The recursive evaluator would then be
+ replaced by a straight line byte code interpreter that would be
+ intermediate in speed between running a compiled program and doing
+ what `gawk' does now.
+
+Finally, the programs in the test suite could use documenting in this
+Info file.
+
+*Note Additions::, if you are interested in tackling any of these
+projects.
+
+\1f
+File: gawk.info, Node: Basic Concepts, Next: Glossary, Prev: Notes, Up: Top
+
+Appendix D Basic Programming Concepts
+*************************************
+
+This major node attempts to define some of the basic concepts and terms
+that are used throughout the rest of this Info file. As this Info file
+is specifically about `awk', and not about computer programming in
+general, the coverage here is by necessity fairly cursory and
+simplistic. (If you need more background, there are many other
+introductory texts that you should refer to instead.)
+
+* Menu:
+
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+* Floating Point Issues:: Stuff to know about floating-point numbers.
+
+\1f
+File: gawk.info, Node: Basic High Level, Next: Basic Data Typing, Up: Basic Concepts
+
+D.1 What a Program Does
+=======================
+
+At the most basic level, the job of a program is to process some input
+data and produce results.
+
+ _______
+ +------+ / \ +---------+
+ | Data | -----> < Program > -----> | Results |
+ +------+ \_______/ +---------+
+
+The "program" in the figure can be either a compiled program(1) (such
+as `ls'), or it may be "interpreted". In the latter case, a
+machine-executable program such as `awk' reads your program, and then
+uses the instructions in your program to process the data.
+
+When you write a program, it usually consists of the following, very
+basic set of steps:
+
+ ______
+ +----------------+ / More \ No +----------+
+ | Initialization | -------> < Data > -------> | Clean Up |
+ +----------------+ ^ \ ? / +----------+
+ | +--+-+
+ | | Yes
+ | |
+ | V
+ | +---------+
+ +-----+ Process |
+ +---------+
+
+Initialization
+ These are the things you do before actually starting to process
+ data, such as checking arguments, initializing any data you need
+ to work with, and so on. This step corresponds to `awk''s `BEGIN'
+ rule (*note BEGIN/END::).
+
+ If you were baking a cake, this might consist of laying out all the
+ mixing bowls and the baking pan, and making sure you have all the
+ ingredients that you need.
+
+Processing
+ This is where the actual work is done. Your program reads data,
+ one logical chunk at a time, and processes it as appropriate.
+
+ In most programming languages, you have to manually manage the
+ reading of data, checking to see if there is more each time you
+ read a chunk. `awk''s pattern-action paradigm (*note Getting
+ Started::) handles the mechanics of this for you.
+
+ In baking a cake, the processing corresponds to the actual labor:
+ breaking eggs, mixing the flour, water, and other ingredients, and
+ then putting the cake into the oven.
+
+Clean Up
+ Once you've processed all the data, you may have things you need to
+ do before exiting. This step corresponds to `awk''s `END' rule
+ (*note BEGIN/END::).
+
+ After the cake comes out of the oven, you still have to wrap it in
+ plastic wrap to keep anyone from tasting it, as well as wash the
+ mixing bowls and utensils.
+
+An "algorithm" is a detailed set of instructions necessary to accomplish
+a task, or process data. It is much the same as a recipe for baking a
+cake. Programs implement algorithms. Often, it is up to you to design
+the algorithm and implement it, simultaneously.
+
+The "logical chunks" we talked about previously are called "records",
+similar to the records a company keeps on employees, a school keeps for
+students, or a doctor keeps for patients. Each record has many
+component parts, such as first and last names, date of birth, address,
+and so on. The component parts are referred to as the "fields" of the
+record.
+
+The act of reading data is termed "input", and that of generating
+results, not too surprisingly, is termed "output". They are often
+referred to together as "input/output," and even more often, as "I/O"
+for short. (You will also see "input" and "output" used as verbs.)
+
+`awk' manages the reading of data for you, as well as the breaking it
+up into records and fields. Your program's job is to tell `awk' what
+to with the data. You do this by describing "patterns" in the data to
+look for, and "actions" to execute when those patterns are seen. This
+"data-driven" nature of `awk' programs usually makes them both easier
+to write and easier to read.
+
+---------- Footnotes ----------
+
+(1) Compiled programs are typically written in lower-level languages
+such as C, C++, Fortran, or Ada, and then translated, or "compiled",
+into a form that the computer can execute directly.
+
+\1f
+File: gawk.info, Node: Basic Data Typing, Next: Floating Point Issues, Prev: Basic High Level, Up: Basic Concepts
+
+D.2 Data Values in a Computer
+=============================
+
+In a program, you keep track of information and values in things called
+"variables". A variable is just a name for a given value, such as
+`first_name', `last_name', `address', and so on. `awk' has several
+predefined variables, and it has special names to refer to the current
+input record and the fields of the record. You may also group multiple
+associated values under one name, as an array.
+
+Data, particularly in `awk', consists of either numeric values, such as
+42 or 3.1415927, or string values. String values are essentially
+anything that's not a number, such as a name. Strings are sometimes
+referred to as "character data", since they store the individual
+characters that comprise them. Individual variables, as well as
+numeric and string variables, are referred to as "scalar" values.
+Groups of values, such as arrays, are not scalars.
+
+Within computers, there are two kinds of numeric values: "integers" and
+"floating-point". In school, integer values were referred to as
+"whole" numbers--that is, numbers without any fractional part, such as
+1, 42, or -17. The advantage to integer numbers is that they represent
+values exactly. The disadvantage is that their range is limited. On
+most modern systems, this range is -2,147,483,648 to 2,147,483,647.
+
+Integer values come in two flavors: "signed" and "unsigned". Signed
+values may be negative or positive, with the range of values just
+described. Unsigned values are always positive. On most modern
+systems, the range is from 0 to 4,294,967,295.
+
+Floating-point numbers represent what are called "real" numbers; i.e.,
+those that do have a fractional part, such as 3.1415927. The advantage
+to floating-point numbers is that they can represent a much larger
+range of values. The disadvantage is that there are numbers that they
+cannot represent exactly. `awk' uses "double-precision" floating-point
+numbers, which can hold more digits than "single-precision"
+floating-point numbers. Floating-point issues are discussed more fully
+in *Note Floating Point Issues::.
+
+At the very lowest level, computers store values as groups of binary
+digits, or "bits". Modern computers group bits into groups of eight,
+called "bytes". Advanced applications sometimes have to manipulate
+bits directly, and `gawk' provides functions for doing so.
+
+While you are probably used to the idea of a number without a value
+(i.e., zero), it takes a bit more getting used to the idea of
+zero-length character data. Nevertheless, such a thing exists. It is
+called the "null string". The null string is character data that has
+no value. In other words, it is empty. It is written in `awk' programs
+like this: `""'.
+
+Humans are used to working in decimal; i.e., base 10. In base 10,
+numbers go from 0 to 9, and then "roll over" into the next column.
+(Remember grade school? 42 is 4 times 10 plus 2.)
+
+There are other number bases though. Computers commonly use base 2 or
+"binary", base 8 or "octal", and base 16 or "hexadecimal". In binary,
+each column represents two times the value in the column to its right.
+Each column may contain either a 0 or a 1. Thus, binary 1010
+represents 1 times 8, plus 0 times 4, plus 1 times 2, plus 0 times 1,
+or decimal 10. Octal and hexadecimal are discussed more in *Note
+Nondecimal-numbers::.
+
+Programs are written in programming languages. Hundreds, if not
+thousands, of programming languages exist. One of the most popular is
+the C programming language. The C language had a very strong influence
+on the design of the `awk' language.
+
+There have been several versions of C. The first is often referred to
+as "K&R" C, after the initials of Brian Kernighan and Dennis Ritchie,
+the authors of the first book on C. (Dennis Ritchie created the
+language, and Brian Kernighan was one of the creators of `awk'.)
+
+In the mid-1980s, an effort began to produce an international standard
+for C. This work culminated in 1989, with the production of the ANSI
+standard for C. This standard became an ISO standard in 1990. Where
+it makes sense, POSIX `awk' is compatible with 1990 ISO C.
+
+In 1999, a revised ISO C standard was approved and released. Future
+versions of `gawk' will be as compatible as possible with this standard.
+
+\1f
+File: gawk.info, Node: Floating Point Issues, Prev: Basic Data Typing, Up: Basic Concepts
+
+D.3 Floating-Point Number Caveats
+=================================
+
+As mentioned earlier, floating-point numbers represent what are called
+"real" numbers, i.e., those that have a fractional part. `awk' uses
+double-precision floating-point numbers to represent all numeric
+values. This minor node describes some of the issues involved in using
+floating-point numbers.
+
+There is a very nice paper on floating-point arithmetic by David
+Goldberg, "What Every Computer Scientist Should Know About
+Floating-point Arithmetic," `ACM Computing Surveys' *23*, 1 (1991-03),
+5-48.(1) This is worth reading if you are interested in the details,
+but it does require a background in computer science.
+
+Internally, `awk' keeps both the numeric value (double-precision
+floating-point) and the string value for a variable. Separately, `awk'
+keeps track of what type the variable has (*note Typing and
+Comparison::), which plays a role in how variables are used in
+comparisons.
+
+It is important to note that the string value for a number may not
+reflect the full value (all the digits) that the numeric value actually
+contains. The following program (`values.awk') illustrates this:
+
+ {
+ $1 = $2 + $3
+ # see it for what it is
+ printf("$1 = %.12g\n", $1)
+ # use CONVFMT
+ a = "<" $1 ">"
+ print "a =", a
+ # use OFMT
+ print "$1 =", $1
+ }
+
+This program shows the full value of the sum of `$2' and `$3' using
+`printf', and then prints the string values obtained from both
+automatic conversion (via `CONVFMT') and from printing (via `OFMT').
+
+Here is what happens when the program is run:
+
+ $ echo 2 3.654321 1.2345678 | awk -f values.awk
+ -| $1 = 4.8888888
+ -| a = <4.88889>
+ -| $1 = 4.88889
+
+This makes it clear that the full numeric value is different from what
+the default string representations show.
+
+`CONVFMT''s default value is `"%.6g"', which yields a value with at
+least six significant digits. For some applications, you might want to
+change it to specify more precision. On most modern machines, most of
+the time, 17 digits is enough to capture a floating-point number's
+value exactly.(2)
+
+Unlike numbers in the abstract sense (such as what you studied in high
+school or college math), numbers stored in computers are limited in
+certain ways. They cannot represent an infinite number of digits, nor
+can they always represent things exactly. In particular,
+floating-point numbers cannot always represent values exactly. Here is
+an example:
+
+ $ awk '{ printf("%010d\n", $1 * 100) }'
+ 515.79
+ -| 0000051579
+ 515.80
+ -| 0000051579
+ 515.81
+ -| 0000051580
+ 515.82
+ -| 0000051582
+ Ctrl-d
+
+This shows that some values can be represented exactly, whereas others
+are only approximated. This is not a "bug" in `awk', but simply an
+artifact of how computers represent numbers.
+
+Another peculiarity of floating-point numbers on modern systems is that
+they often have more than one representation for the number zero! In
+particular, it is possible to represent "minus zero" as well as
+regular, or "positive" zero.
+
+This example shows that negative and positive zero are distinct values
+when stored internally, but that they are in fact equal to each other,
+as well as to "regular" zero:
+
+ $ gawk 'BEGIN { mz = -0 ; pz = 0
+ > printf "-0 = %g, +0 = %g, (-0 == +0) -> %d\n", mz, pz, mz == pz
+ > printf "mz == 0 -> %d, pz == 0 -> %d\n", mz == 0, pz == 0
+ > }'
+ -| -0 = -0, +0 = 0, (-0 == +0) -> 1
+ -| mz == 0 -> 1, pz == 0 -> 1
+
+It helps to keep this in mind should you process numeric data that
+contains negative zero values; the fact that the zero is negative is
+noted and can affect comparisons.
+
+---------- Footnotes ----------
+
+(1) `http://www.validlab.com/goldberg/paper.ps'.
+
+(2) Pathological cases can require up to 752 digits (!), but we doubt
+that you need to worry about this.
+
+\1f
+File: gawk.info, Node: Glossary, Next: Copying, Prev: Basic Concepts, Up: Top
+
+Glossary
+********
+
+Action
+ A series of `awk' statements attached to a rule. If the rule's
+ pattern matches an input record, `awk' executes the rule's action.
+ Actions are always enclosed in curly braces. (*Note Action
+ Overview::.)
+
+Amazing `awk' Assembler
+ Henry Spencer at the University of Toronto wrote a retargetable
+ assembler completely as `sed' and `awk' scripts. It is thousands
+ of lines long, including machine descriptions for several eight-bit
+ microcomputers. It is a good example of a program that would have
+ been better written in another language. You can get it from
+ `ftp://ftp.freefriends.org/arnold/Awkstuff/aaa.tgz'.
+
+Amazingly Workable Formatter (`awf')
+ Henry Spencer at the University of Toronto wrote a formatter that
+ accepts a large subset of the `nroff -ms' and `nroff -man'
+ formatting commands, using `awk' and `sh'. It is available over
+ the Internet from
+ `ftp://ftp.freefriends.org/arnold/Awkstuff/awf.tgz'.
+
+Anchor
+ The regexp metacharacters `^' and `$', which force the match to
+ the beginning or end of the string, respectively.
+
+ANSI
+ The American National Standards Institute. This organization
+ produces many standards, among them the standards for the C and
+ C++ programming languages. These standards often become
+ international standards as well. See also "ISO."
+
+Array
+ A grouping of multiple values under the same name. Most languages
+ just provide sequential arrays. `awk' provides associative arrays.
+
+Assertion
+ A statement in a program that a condition is true at this point in
+ the program. Useful for reasoning about how a program is supposed
+ to behave.
+
+Assignment
+ An `awk' expression that changes the value of some `awk' variable
+ or data object. An object that you can assign to is called an
+ "lvalue". The assigned values are called "rvalues". *Note
+ Assignment Ops::.
+
+Associative Array
+ Arrays in which the indices may be numbers or strings, not just
+ sequential integers in a fixed range.
+
+`awk' Language
+ The language in which `awk' programs are written.
+
+`awk' Program
+ An `awk' program consists of a series of "patterns" and "actions",
+ collectively known as "rules". For each input record given to the
+ program, the program's rules are all processed in turn. `awk'
+ programs may also contain function definitions.
+
+`awk' Script
+ Another name for an `awk' program.
+
+Bash
+ The GNU version of the standard shell (the Bourne-Again SHell).
+ See also "Bourne Shell."
+
+BBS
+ See "Bulletin Board System."
+
+Bit
+ Short for "Binary Digit." All values in computer memory
+ ultimately reduce to binary digits: values that are either zero or
+ one. Groups of bits may be interpreted differently--as integers,
+ floating-point numbers, character data, addresses of other memory
+ objects, or other data. `awk' lets you work with floating-point
+ numbers and strings. `gawk' lets you manipulate bit values with
+ the built-in functions described in *Note Bitwise Functions::.
+
+ Computers are often defined by how many bits they use to represent
+ integer values. Typical systems are 32-bit systems, but 64-bit
+ systems are becoming increasingly popular, and 16-bit systems are
+ waning in popularity.
+
+Boolean Expression
+ Named after the English mathematician Boole. See also "Logical
+ Expression."
+
+Bourne Shell
+ The standard shell (`/bin/sh') on Unix and Unix-like systems,
+ originally written by Steven R. Bourne. Many shells (`bash',
+ `ksh', `pdksh', `zsh') are generally upwardly compatible with the
+ Bourne shell.
+
+Built-in Function
+ The `awk' language provides built-in functions that perform various
+ numerical, I/O-related, and string computations. Examples are
+ `sqrt' (for the square root of a number) and `substr' (for a
+ substring of a string). `gawk' provides functions for timestamp
+ management, bit manipulation, and runtime string translation.
+ (*Note Built-in::.)
+
+Built-in Variable
+ `ARGC', `ARGV', `CONVFMT', `ENVIRON', `FILENAME', `FNR', `FS',
+ `NF', `NR', `OFMT', `OFS', `ORS', `RLENGTH', `RSTART', `RS', and
+ `SUBSEP' are the variables that have special meaning to `awk'. In
+ addition, `ARGIND', `BINMODE', `ERRNO', `FIELDWIDTHS',
+ `IGNORECASE', `LINT', `PROCINFO', `RT', and `TEXTDOMAIN' are the
+ variables that have special meaning to `gawk'. Changing some of
+ them affects `awk''s running environment. (*Note Built-in
+ Variables::.)
+
+Braces
+ See "Curly Braces."
+
+Bulletin Board System
+ A computer system allowing users to log in and read and/or leave
+ messages for other users of the system, much like leaving paper
+ notes on a bulletin board.
+
+C
+ The system programming language that most GNU software is written
+ in. The `awk' programming language has C-like syntax, and this
+ Info file points out similarities between `awk' and C when
+ appropriate.
+
+ In general, `gawk' attempts to be as similar to the 1990 version
+ of ISO C as makes sense. Future versions of `gawk' may adopt
+ features from the newer 1999 standard, as appropriate.
+
+C++
+ A popular object-oriented programming language derived from C.
+
+Character Set
+ The set of numeric codes used by a computer system to represent the
+ characters (letters, numbers, punctuation, etc.) of a particular
+ country or place. The most common character set in use today is
+ ASCII (American Standard Code for Information Interchange). Many
+ European countries use an extension of ASCII known as ISO-8859-1
+ (ISO Latin-1).
+
+CHEM
+ A preprocessor for `pic' that reads descriptions of molecules and
+ produces `pic' input for drawing them. It was written in `awk' by
+ Brian Kernighan and Jon Bentley, and is available from
+ `http://cm.bell-labs.com/netlib/typesetting/chem.gz'.
+
+Coprocess
+ A subordinate program with which two-way communications is
+ possible.
+
+Compiler
+ A program that translates human-readable source code into
+ machine-executable object code. The object code is then executed
+ directly by the computer. See also "Interpreter."
+
+Compound Statement
+ A series of `awk' statements, enclosed in curly braces. Compound
+ statements may be nested. (*Note Statements::.)
+
+Concatenation
+ Concatenating two strings means sticking them together, one after
+ another, producing a new string. For example, the string `foo'
+ concatenated with the string `bar' gives the string `foobar'.
+ (*Note Concatenation::.)
+
+Conditional Expression
+ An expression using the `?:' ternary operator, such as `EXPR1 ?
+ EXPR2 : EXPR3'. The expression EXPR1 is evaluated; if the result
+ is true, the value of the whole expression is the value of EXPR2;
+ otherwise the value is EXPR3. In either case, only one of EXPR2
+ and EXPR3 is evaluated. (*Note Conditional Exp::.)
+
+Comparison Expression
+ A relation that is either true or false, such as `(a < b)'.
+ Comparison expressions are used in `if', `while', `do', and `for'
+ statements, and in patterns to select which input records to
+ process. (*Note Typing and Comparison::.)
+
+Curly Braces
+ The characters `{' and `}'. Curly braces are used in `awk' for
+ delimiting actions, compound statements, and function bodies.
+
+Dark Corner
+ An area in the language where specifications often were (or still
+ are) not clear, leading to unexpected or undesirable behavior.
+ Such areas are marked in this Info file with "(d.c.)" in the text
+ and are indexed under the heading "dark corner."
+
+Data Driven
+ A description of `awk' programs, where you specify the data you
+ are interested in processing, and what to do when that data is
+ seen.
+
+Data Objects
+ These are numbers and strings of characters. Numbers are
+ converted into strings and vice versa, as needed. (*Note
+ Conversion::.)
+
+Deadlock
+ The situation in which two communicating processes are each waiting
+ for the other to perform an action.
+
+Double-Precision
+ An internal representation of numbers that can have fractional
+ parts. Double-precision numbers keep track of more digits than do
+ single-precision numbers, but operations on them are sometimes
+ more expensive. This is the way `awk' stores numeric values. It
+ is the C type `double'.
+
+Dynamic Regular Expression
+ A dynamic regular expression is a regular expression written as an
+ ordinary expression. It could be a string constant, such as
+ `"foo"', but it may also be an expression whose value can vary.
+ (*Note Computed Regexps::.)
+
+Environment
+ A collection of strings, of the form NAME`='VAL, that each program
+ has available to it. Users generally place values into the
+ environment in order to provide information to various programs.
+ Typical examples are the environment variables `HOME' and `PATH'.
+
+Empty String
+ See "Null String."
+
+Epoch
+ The date used as the "beginning of time" for timestamps. Time
+ values in Unix systems are represented as seconds since the epoch,
+ with library functions available for converting these values into
+ standard date and time formats.
+
+ The epoch on Unix and POSIX systems is 1970-01-01 00:00:00 UTC.
+ See also "GMT" and "UTC."
+
+Escape Sequences
+ A special sequence of characters used for describing nonprinting
+ characters, such as `\n' for newline or `\033' for the ASCII ESC
+ (Escape) character. (*Note Escape Sequences::.)
+
+FDL
+ See "Free Documentation License."
+
+Field
+ When `awk' reads an input record, it splits the record into pieces
+ separated by whitespace (or by a separator regexp that you can
+ change by setting the built-in variable `FS'). Such pieces are
+ called fields. If the pieces are of fixed length, you can use the
+ built-in variable `FIELDWIDTHS' to describe their lengths. (*Note
+ Field Separators::, and *Note Constant Size::.)
+
+Flag
+ A variable whose truth value indicates the existence or
+ nonexistence of some condition.
+
+Floating-Point Number
+ Often referred to in mathematical terms as a "rational" or real
+ number, this is just a number that can have a fractional part.
+ See also "Double-Precision" and "Single-Precision."
+
+Format
+ Format strings are used to control the appearance of output in the
+ `strftime' and `sprintf' functions, and are used in the `printf'
+ statement as well. Also, data conversions from numbers to strings
+ are controlled by the format string contained in the built-in
+ variable `CONVFMT'. (*Note Control Letters::.)
+
+Free Documentation License
+ This document describes the terms under which this Info file is
+ published and may be copied. (*Note GNU Free Documentation
+ License::.)
+
+Function
+ A specialized group of statements used to encapsulate general or
+ program-specific tasks. `awk' has a number of built-in functions,
+ and also allows you to define your own. (*Note Functions::.)
+
+FSF
+ See "Free Software Foundation."
+
+Free Software Foundation
+ A nonprofit organization dedicated to the production and
+ distribution of freely distributable software. It was founded by
+ Richard M. Stallman, the author of the original Emacs editor. GNU
+ Emacs is the most widely used version of Emacs today.
+
+`gawk'
+ The GNU implementation of `awk'.
+
+General Public License
+ This document describes the terms under which `gawk' and its source
+ code may be distributed. (*Note Copying::.)
+
+GMT
+ "Greenwich Mean Time." This is the old term for UTC. It is the
+ time of day used as the epoch for Unix and POSIX systems. See
+ also "Epoch" and "UTC."
+
+GNU
+ "GNU's not Unix". An on-going project of the Free Software
+ Foundation to create a complete, freely distributable,
+ POSIX-compliant computing environment.
+
+GNU/Linux
+ A variant of the GNU system using the Linux kernel, instead of the
+ Free Software Foundation's Hurd kernel. Linux is a stable,
+ efficient, full-featured clone of Unix that has been ported to a
+ variety of architectures. It is most popular on PC-class systems,
+ but runs well on a variety of other systems too. The Linux kernel
+ source code is available under the terms of the GNU General Public
+ License, which is perhaps its most important aspect.
+
+GPL
+ See "General Public License."
+
+Hexadecimal
+ Base 16 notation, where the digits are `0'-`9' and `A'-`F', with
+ `A' representing 10, `B' representing 11, and so on, up to `F' for
+ 15. Hexadecimal numbers are written in C using a leading `0x', to
+ indicate their base. Thus, `0x12' is 18 (1 times 16 plus 2).
+
+I/O
+ Abbreviation for "Input/Output," the act of moving data into and/or
+ out of a running program.
+
+Input Record
+ A single chunk of data that is read in by `awk'. Usually, an
+ `awk' input record consists of one line of text. (*Note
+ Records::.)
+
+Integer
+ A whole number, i.e., a number that does not have a fractional
+ part.
+
+Internationalization
+ The process of writing or modifying a program so that it can use
+ multiple languages without requiring further source code changes.
+
+Interpreter
+ A program that reads human-readable source code directly, and uses
+ the instructions in it to process data and produce results. `awk'
+ is typically (but not always) implemented as an interpreter. See
+ also "Compiler."
+
+Interval Expression
+ A component of a regular expression that lets you specify repeated
+ matches of some part of the regexp. Interval expressions were not
+ traditionally available in `awk' programs.
+
+ISO
+ The International Standards Organization. This organization
+ produces international standards for many things, including
+ programming languages, such as C and C++. In the computer arena,
+ important standards like those for C, C++, and POSIX become both
+ American national and ISO international standards simultaneously.
+ This Info file refers to Standard C as "ISO C" throughout.
+
+Keyword
+ In the `awk' language, a keyword is a word that has special
+ meaning. Keywords are reserved and may not be used as variable
+ names.
+
+ `gawk''s keywords are: `BEGIN', `END', `if', `else', `while',
+ `do...while', `for', `for...in', `break', `continue', `delete',
+ `next', `nextfile', `function', `func', and `exit'.
+
+Lesser General Public License
+ This document describes the terms under which binary library
+ archives or shared objects, and their source code may be
+ distributed.
+
+Linux
+ See "GNU/Linux."
+
+LGPL
+ See "Lesser General Public License."
+
+Localization
+ The process of providing the data necessary for an
+ internationalized program to work in a particular language.
+
+Logical Expression
+ An expression using the operators for logic, AND, OR, and NOT,
+ written `&&', `||', and `!' in `awk'. Often called Boolean
+ expressions, after the mathematician who pioneered this kind of
+ mathematical logic.
+
+Lvalue
+ An expression that can appear on the left side of an assignment
+ operator. In most languages, lvalues can be variables or array
+ elements. In `awk', a field designator can also be used as an
+ lvalue.
+
+Matching
+ The act of testing a string against a regular expression. If the
+ regexp describes the contents of the string, it is said to "match"
+ it.
+
+Metacharacters
+ Characters used within a regexp that do not stand for themselves.
+ Instead, they denote regular expression operations, such as
+ repetition, grouping, or alternation.
+
+Null String
+ A string with no characters in it. It is represented explicitly in
+ `awk' programs by placing two double quote characters next to each
+ other (`""'). It can appear in input data by having two successive
+ occurrences of the field separator appear next to each other.
+
+Number
+ A numeric-valued data object. Modern `awk' implementations use
+ double-precision floating-point to represent numbers. Very old
+ `awk' implementations use single-precision floating-point.
+
+Octal
+ Base-eight notation, where the digits are `0'-`7'. Octal numbers
+ are written in C using a leading `0', to indicate their base.
+ Thus, `013' is 11 (one times 8 plus 3).
+
+P1003.2
+ See "POSIX."
+
+Pattern
+ Patterns tell `awk' which input records are interesting to which
+ rules.
+
+ A pattern is an arbitrary conditional expression against which
+ input is tested. If the condition is satisfied, the pattern is
+ said to "match" the input record. A typical pattern might compare
+ the input record against a regular expression. (*Note Pattern
+ Overview::.)
+
+POSIX
+ The name for a series of standards that specify a Portable
+ Operating System interface. The "IX" denotes the Unix heritage of
+ these standards. The main standard of interest for `awk' users is
+ `IEEE Standard for Information Technology, Standard 1003.2-1992,
+ Portable Operating System Interface (POSIX) Part 2: Shell and
+ Utilities'. Informally, this standard is often referred to as
+ simply "P1003.2."
+
+Precedence
+ The order in which operations are performed when operators are used
+ without explicit parentheses.
+
+Private
+ Variables and/or functions that are meant for use exclusively by
+ library functions and not for the main `awk' program. Special care
+ must be taken when naming such variables and functions. (*Note
+ Library Names::.)
+
+Range (of input lines)
+ A sequence of consecutive lines from the input file(s). A pattern
+ can specify ranges of input lines for `awk' to process or it can
+ specify single lines. (*Note Pattern Overview::.)
+
+Recursion
+ When a function calls itself, either directly or indirectly. If
+ this isn't clear, refer to the entry for "recursion."
+
+Redirection
+ Redirection means performing input from something other than the
+ standard input stream, or performing output to something other
+ than the standard output stream.
+
+ You can redirect the output of the `print' and `printf' statements
+ to a file or a system command, using the `>', `>>', `|', and `|&'
+ operators. You can redirect input to the `getline' statement using
+ the `<', `|', and `|&' operators. (*Note Redirection::, and *Note
+ Getline::.)
+
+Regexp
+ Short for "regular expression". A regexp is a pattern that
+ denotes a set of strings, possibly an infinite set. For example,
+ the regexp `R.*xp' matches any string starting with the letter `R'
+ and ending with the letters `xp'. In `awk', regexps are used in
+ patterns and in conditional expressions. Regexps may contain
+ escape sequences. (*Note Regexp::.)
+
+Regular Expression
+ See "regexp."
+
+Regular Expression Constant
+ A regular expression constant is a regular expression written
+ within slashes, such as `/foo/'. This regular expression is chosen
+ when you write the `awk' program and cannot be changed during its
+ execution. (*Note Regexp Usage::.)
+
+Rule
+ A segment of an `awk' program that specifies how to process single
+ input records. A rule consists of a "pattern" and an "action".
+ `awk' reads an input record; then, for each rule, if the input
+ record satisfies the rule's pattern, `awk' executes the rule's
+ action. Otherwise, the rule does nothing for that input record.
+
+Rvalue
+ A value that can appear on the right side of an assignment
+ operator. In `awk', essentially every expression has a value.
+ These values are rvalues.
+
+Scalar
+ A single value, be it a number or a string. Regular variables are
+ scalars; arrays and functions are not.
+
+Search Path
+ In `gawk', a list of directories to search for `awk' program
+ source files. In the shell, a list of directories to search for
+ executable programs.
+
+Seed
+ The initial value, or starting point, for a sequence of random
+ numbers.
+
+`sed'
+ See "Stream Editor."
+
+Shell
+ The command interpreter for Unix and POSIX-compliant systems. The
+ shell works both interactively, and as a programming language for
+ batch files, or shell scripts.
+
+Short-Circuit
+ The nature of the `awk' logical operators `&&' and `||'. If the
+ value of the entire expression is determinable from evaluating just
+ the lefthand side of these operators, the righthand side is not
+ evaluated. (*Note Boolean Ops::.)
+
+Side Effect
+ A side effect occurs when an expression has an effect aside from
+ merely producing a value. Assignment expressions, increment and
+ decrement expressions, and function calls have side effects.
+ (*Note Assignment Ops::.)
+
+Single-Precision
+ An internal representation of numbers that can have fractional
+ parts. Single-precision numbers keep track of fewer digits than
+ do double-precision numbers, but operations on them are sometimes
+ less expensive in terms of CPU time. This is the type used by
+ some very old versions of `awk' to store numeric values. It is
+ the C type `float'.
+
+Space
+ The character generated by hitting the space bar on the keyboard.
+
+Special File
+ A file name interpreted internally by `gawk', instead of being
+ handed directly to the underlying operating system--for example,
+ `/dev/stderr'. (*Note Special Files::.)
+
+Stream Editor
+ A program that reads records from an input stream and processes
+ them one or more at a time. This is in contrast with batch
+ programs, which may expect to read their input files in entirety
+ before starting to do anything, as well as with interactive
+ programs which require input from the user.
+
+String
+ A datum consisting of a sequence of characters, such as `I am a
+ string'. Constant strings are written with double quotes in the
+ `awk' language and may contain escape sequences. (*Note Escape
+ Sequences::.)
+
+Tab
+ The character generated by hitting the `TAB' key on the keyboard.
+ It usually expands to up to eight spaces upon output.
+
+Text Domain
+ A unique name that identifies an application. Used for grouping
+ messages that are translated at runtime into the local language.
+
+Timestamp
+ A value in the "seconds since the epoch" format used by Unix and
+ POSIX systems. Used for the `gawk' functions `mktime',
+ `strftime', and `systime'. See also "Epoch" and "UTC."
+
+Unix
+ A computer operating system originally developed in the early
+ 1970's at AT&T Bell Laboratories. It initially became popular in
+ universities around the world and later moved into commercial
+ environments as a software development system and network server
+ system. There are many commercial versions of Unix, as well as
+ several work-alike systems whose source code is freely available
+ (such as GNU/Linux, NetBSD, FreeBSD, and OpenBSD).
+
+UTC
+ The accepted abbreviation for "Universal Coordinated Time." This
+ is standard time in Greenwich, England, which is used as a
+ reference time for day and date calculations. See also "Epoch"
+ and "GMT."
+
+Whitespace
+ A sequence of space, TAB, or newline characters occurring inside
+ an input record or a string.
+
+\1f
+File: gawk.info, Node: Copying, Next: GNU Free Documentation License, Prev: Glossary, Up: Top
+
+GNU General Public License
+**************************
+
+ Version 2, June 1991
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom
+to share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.
+Our General Public Licenses are designed to make sure that you have
+the freedom to distribute copies of free software (and charge for this
+service if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone
+to deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis
+or for a fee, you must give the recipients all the rights that you
+have. You must make sure that they, too, receive or can get the source
+code. And you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.
+We wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program
+proprietary. To prevent this, we have made it clear that any patent
+must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program",
+ below, refers to any such program or work, and a "work based on
+ the Program" means either the Program or any derivative work under
+ copyright law: that is to say, a work containing the Program or a
+ portion of it, either verbatim or with modifications and/or
+ translated into another language. (Hereinafter, translation is
+ included without limitation in the term "modification".) Each
+ licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are
+ not covered by this License; they are outside its scope. The act
+ of running the Program is not restricted, and the output from the
+ Program is covered only if its contents constitute a work based on
+ the Program (independent of having been made by running the
+ Program). Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+ source code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any
+ warranty; and give any other recipients of the Program a copy of
+ this License along with the Program.
+
+ You may charge a fee for the physical act of transferring a copy,
+ and you may at your option offer warranty protection in exchange
+ for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+ of it, thus forming a work based on the Program, and copy and
+ distribute such modifications or work under the terms of Section 1
+ above, provided that you also meet all of these conditions:
+
+ a. You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b. You must cause any work that you distribute or publish, that
+ in whole or in part contains or is derived from the Program
+ or any part thereof, to be licensed as a whole at no charge
+ to all third parties under the terms of this License.
+
+ c. If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display
+ an announcement including an appropriate copyright notice and
+ a notice that there is no warranty (or else, saying that you
+ provide a warranty) and that users may redistribute the
+ program under these conditions, and telling the user how to
+ view a copy of this License. (Exception: if the Program
+ itself is interactive but does not normally print such an
+ announcement, your work based on the Program is not required
+ to print an announcement.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the
+ Program, and can be reasonably considered independent and separate
+ works in themselves, then this License, and its terms, do not
+ apply to those sections when you distribute them as separate
+ works. But when you distribute the same sections as part of a
+ whole which is a work based on the Program, the distribution of
+ the whole must be on the terms of this License, whose permissions
+ for other licensees extend to the entire whole, and thus to each
+ and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or
+ contest your rights to work written entirely by you; rather, the
+ intent is to exercise the right to control the distribution of
+ derivative or collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on
+ a volume of a storage or distribution medium does not bring the
+ other work under the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms
+ of Sections 1 and 2 above provided that you also do one of the
+ following:
+
+ a. Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,
+
+ b. Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange; or,
+
+ c. Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with
+ such an offer, in accord with Subsection b above.)
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete
+ source code means all the source code for all modules it contains,
+ plus any associated interface definition files, plus the scripts
+ used to control compilation and installation of the executable.
+ However, as a special exception, the source code distributed need
+ not include anything that is normally distributed (in either
+ source or binary form) with the major components (compiler,
+ kernel, and so on) of the operating system on which the executable
+ runs, unless that component itself accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify
+ or distribute the Program or its derivative works. These actions
+ are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Program (or any work
+ based on the Program), you indicate your acceptance of this
+ License to do so, and all its terms and conditions for copying,
+ distributing or modifying the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program
+ subject to these terms and conditions. You may not impose any
+ further restrictions on the recipients' exercise of the rights
+ granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent
+ issues), conditions are imposed on you (whether by court order,
+ agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this
+ License. If you cannot distribute so as to satisfy simultaneously
+ your obligations under this License and any other pertinent
+ obligations, then as a consequence you may not distribute the
+ Program at all. For example, if a patent license would not permit
+ royalty-free redistribution of the Program by all those who
+ receive copies directly or indirectly through you, then the only
+ way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable
+ under any particular circumstance, the balance of the section is
+ intended to apply and the section as a whole is intended to apply
+ in other circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of
+ any such claims; this section has the sole purpose of protecting
+ the integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is
+ willing to distribute software through any other system and a
+ licensee cannot impose that choice.
+
+ This section is intended to make thoroughly clear what is believed
+ to be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces,
+ the original copyright holder who places the Program under this
+ License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only
+ in or among countries not thus excluded. In such case, this
+ License incorporates the limitation as if written in the body of
+ this License.
+
+ 9. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such
+ new versions will be similar in spirit to the present version, but
+ may differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+ Program specifies a version number of this License which applies
+ to it and "any later version", you have the option of following
+ the terms and conditions either of that version or of any later
+ version published by the Free Software Foundation. If the Program
+ does not specify a version number of this License, you may choose
+ any version ever published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted
+ by the Free Software Foundation, write to the Free Software
+ Foundation; we sometimes make exceptions for this. Our decision
+ will be guided by the two goals of preserving the free status of
+ all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+ LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
+ QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
+ SERVICING, REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+ MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
+ OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
+ OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
+ Copyright (C) YEAR NAME OF AUTHOR
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) YEAR NAME OF AUTHOR
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+ type `show w'. This is free software, and you are welcome
+ to redistribute it under certain conditions; type `show c'
+ for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright
+ interest in the program `Gnomovision'
+ (which makes passes at compilers) written
+ by James Hacker.
+
+ SIGNATURE OF TY COON, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library,
+you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Lesser General Public License instead of this License.
+
+\1f
+File: gawk.info, Node: GNU Free Documentation License, Next: Index, Prev: Copying, Up: Top
+
+GNU Free Documentation License
+******************************
+
+ Version 1.2, November 2002
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warrany Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+\1f
+File: gawk.info, Node: Index, Prev: GNU Free Documentation License, Up: Top
+
+Index
+*****
+
+* Menu:
+
+* ! (exclamation point), ! operator: Boolean Ops. (line 6524)
+* ! (exclamation point), ! operator <1>: Egrep Program. (line 14679)
+* ! (exclamation point), ! operator: Precedence. (line 6698)
+* ! (exclamation point), != operator <1>: Precedence. (line 6711)
+* ! (exclamation point), != operator: Typing and Comparison.
+ (line 6342)
+* ! (exclamation point), !~ operator <1>: Expression Patterns.
+ (line 6851)
+* ! (exclamation point), !~ operator <2>: Precedence. (line 6727)
+* ! (exclamation point), !~ operator <3>: Typing and Comparison.
+ (line 6342)
+* ! (exclamation point), !~ operator <4>: Regexp Constants. (line 5532)
+* ! (exclamation point), !~ operator <5>: Computed Regexps. (line 2656)
+* ! (exclamation point), !~ operator <6>: Case-sensitivity. (line 2569)
+* ! (exclamation point), !~ operator: Regexp Usage. (line 1989)
+* ! operator <1>: Egrep Program. (line 14687)
+* ! operator: Ranges. (line 6955)
+* " (double quote) <1>: Quoting. (line 1376)
+* " (double quote): Read Terminal. (line 1165)
+* " (double quote), regexp constants: Computed Regexps. (line 2677)
+* # (number sign), #! (executable scripts): Executable Scripts.
+ (line 1233)
+* # (number sign), #! (executable scripts), portability issues with: Executable Scripts.
+ (line 1233)
+* # (number sign), commenting: Comments. (line 1296)
+* $ (dollar sign): Regexp Operators. (line 2210)
+* $ (dollar sign), $ field operator <1>: Precedence. (line 6689)
+* $ (dollar sign), $ field operator: Fields. (line 3027)
+* $ (dollar sign), incrementing fields and arrays: Increment Ops.
+ (line 6184)
+* $ field operator: Fields. (line 3027)
+* % (percent sign), % operator: Precedence. (line 6701)
+* % (percent sign), %= operator <1>: Precedence. (line 6742)
+* % (percent sign), %= operator: Assignment Ops. (line 6111)
+* & (ampersand), && operator <1>: Precedence. (line 6733)
+* & (ampersand), && operator: Boolean Ops. (line 6514)
+* & (ampersand), gsub/gensub/sub functions and: Gory Details.
+ (line 9642)
+* ' (single quote) <1>: Quoting. (line 1370)
+* ' (single quote) <2>: Long. (line 1223)
+* ' (single quote): One-shot. (line 1126)
+* ' (single quote), vs. apostrophe: Comments. (line 1317)
+* ' (single quote), with double quotes: Quoting. (line 1392)
+* () (parentheses): Regexp Operators. (line 2253)
+* () (parentheses), pgawk program: Profiling. (line 11877)
+* * (asterisk), * operator, as multiplication operator: Precedence.
+ (line 6701)
+* * (asterisk), * operator, as regexp operator: Regexp Operators.
+ (line 2261)
+* * (asterisk), * operator, null strings, matching: Gory Details.
+ (line 9796)
+* * (asterisk), ** operator <1>: Options. (line 12191)
+* * (asterisk), ** operator <2>: Precedence. (line 6695)
+* * (asterisk), ** operator: Arithmetic Ops. (line 5898)
+* * (asterisk), **= operator <1>: Options. (line 12191)
+* * (asterisk), **= operator <2>: Precedence. (line 6742)
+* * (asterisk), **= operator: Assignment Ops. (line 6111)
+* * (asterisk), *= operator <1>: Precedence. (line 6742)
+* * (asterisk), *= operator: Assignment Ops. (line 6111)
+* + (plus sign): Regexp Operators. (line 2276)
+* + (plus sign), + operator: Precedence. (line 6698)
+* + (plus sign), ++ operator <1>: Precedence. (line 6692)
+* + (plus sign), ++ operator: Increment Ops. (line 6194)
+* + (plus sign), += operator <1>: Precedence. (line 6742)
+* + (plus sign), += operator: Assignment Ops. (line 6064)
+* + (plus sign), decrement/increment operators: Increment Ops.
+ (line 6165)
+* , (comma), in range patterns: Ranges. (line 6913)
+* - (hyphen), - operator: Precedence. (line 6698)
+* - (hyphen), -- (decrement/increment) operator: Precedence.
+ (line 6692)
+* - (hyphen), -- operator: Increment Ops. (line 6202)
+* - (hyphen), -= operator <1>: Precedence. (line 6742)
+* - (hyphen), -= operator: Assignment Ops. (line 6111)
+* - (hyphen), filenames beginning with: Options. (line 12073)
+* - (hyphen), in character lists: Character Lists. (line 2364)
+* --assign option: Options. (line 12036)
+* --compat option: Options. (line 12085)
+* --copyleft option: Options. (line 12098)
+* --copyright option: Options. (line 12093)
+* --disable-lint configuration option: Additional Configuration Options.
+ (line 17477)
+* --disable-nls configuration option: Additional Configuration Options.
+ (line 17492)
+* --dump-variables option <1>: Library Names. (line 12580)
+* --dump-variables option: Options. (line 12101)
+* --enable-portals configuration option <1>: Additional Configuration Options.
+ (line 17469)
+* --enable-portals configuration option: Portal Files. (line 11725)
+* --enable-switch configuration option: Additional Configuration Options.
+ (line 17473)
+* --exec option: Options. (line 12117)
+* --field-separator option: Options. (line 12027)
+* --file option: Options. (line 12031)
+* --gen-po option <1>: Options. (line 12136)
+* --gen-po option: String Extraction. (line 11177)
+* --help option: Options. (line 12145)
+* --lint option <1>: Options. (line 12150)
+* --lint option: Command Line. (line 12002)
+* --lint-old option: Options. (line 12162)
+* --non-decimal-data option <1>: Options. (line 12167)
+* --non-decimal-data option: Nondecimal Data. (line 11480)
+* --non-decimal-data option, strtonum function and: Nondecimal Data.
+ (line 11510)
+* --posix option: Options. (line 12175)
+* --posix option, --traditional option and: Options. (line 12202)
+* --profile option <1>: Options. (line 12208)
+* --profile option: Profiling. (line 11749)
+* --re-interval option: Options. (line 12220)
+* --source option: Options. (line 12227)
+* --traditional option: Options. (line 12085)
+* --traditional option, --posix option and: Options. (line 12202)
+* --usage option: Options. (line 12145)
+* --version option: Options. (line 12235)
+* -f option: Options. (line 12031)
+* -F option <1>: Options. (line 12027)
+* -F option: Command Line Field Separator.
+ (line 3427)
+* -f option: Long. (line 1202)
+* -F option, -Ft sets FS to TAB: Options. (line 12243)
+* -f option, on command line: Options. (line 12248)
+* -F option, troubleshooting: Known Bugs. (line 12454)
+* -mf/-mr options: Options. (line 12051)
+* -v option: Options. (line 12036)
+* -v option, variables, assigning: Assignment Options.
+ (line 5677)
+* -W option: Options. (line 12061)
+* . (period): Regexp Operators. (line 2218)
+* .mo files: Explaining gettext.
+ (line 10954)
+* .mo files, converting from .po: I18N Example. (line 11400)
+* .mo files, specifying directory of <1>: Programmer i18n. (line 11090)
+* .mo files, specifying directory of: Explaining gettext.
+ (line 10966)
+* .po files <1>: Translator i18n. (line 11156)
+* .po files: Explaining gettext.
+ (line 10951)
+* .po files, converting to .mo: I18N Example. (line 11400)
+* / (forward slash): Regexp. (line 1949)
+* / (forward slash), / operator: Precedence. (line 6701)
+* / (forward slash), /= operator <1>: Precedence. (line 6742)
+* / (forward slash), /= operator: Assignment Ops. (line 6111)
+* / (forward slash), /= operator, vs. /=.../ regexp constant: Assignment Ops.
+ (line 6137)
+* / (forward slash), patterns and: Expression Patterns.
+ (line 6851)
+* /= operator vs. /=.../ regexp constant: Assignment Ops. (line 6137)
+* /dev/... special files (gawk): Special FD. (line 5054)
+* /inet/ files (gawk): TCP/IP Networking. (line 11658)
+* /p files (gawk): Portal Files. (line 11725)
+* ; (semicolon): Statements/Lines. (line 1853)
+* ; (semicolon), AWKPATH variable and: PC Using. (line 17858)
+* ; (semicolon), separating statements in actions <1>: Statements.
+ (line 7228)
+* ; (semicolon), separating statements in actions: Action Overview.
+ (line 7178)
+* < (left angle bracket), < operator <1>: Precedence. (line 6711)
+* < (left angle bracket), < operator: Typing and Comparison.
+ (line 6342)
+* < (left angle bracket), < operator (I/O): Getline/File. (line 3979)
+* < (left angle bracket), <= operator <1>: Precedence. (line 6711)
+* < (left angle bracket), <= operator: Typing and Comparison.
+ (line 6342)
+* = (equals sign), = operator: Assignment Ops. (line 5989)
+* = (equals sign), == operator <1>: Precedence. (line 6711)
+* = (equals sign), == operator: Typing and Comparison.
+ (line 6342)
+* > (right angle bracket), > operator <1>: Precedence. (line 6711)
+* > (right angle bracket), > operator: Typing and Comparison.
+ (line 6342)
+* > (right angle bracket), > operator (I/O): Redirection. (line 4864)
+* > (right angle bracket), >= operator <1>: Precedence. (line 6711)
+* > (right angle bracket), >= operator: Typing and Comparison.
+ (line 6342)
+* > (right angle bracket), >> operator (I/O) <1>: Precedence.
+ (line 6711)
+* > (right angle bracket), >> operator (I/O): Redirection. (line 4892)
+* ? (question mark) <1>: GNU Regexp Operators.
+ (line 2506)
+* ? (question mark): Regexp Operators. (line 2285)
+* ? (question mark), ?: operator: Precedence. (line 6739)
+* [] (square brackets): Regexp Operators. (line 2230)
+* \ (backslash) <1>: Regexp Operators. (line 2193)
+* \ (backslash) <2>: Quoting. (line 1370)
+* \ (backslash) <3>: Comments. (line 1339)
+* \ (backslash): Read Terminal. (line 1165)
+* \ (backslash), \" escape sequence: Escape Sequences. (line 2108)
+* \ (backslash), \' operator (gawk): GNU Regexp Operators.
+ (line 2503)
+* \ (backslash), \/ escape sequence: Escape Sequences. (line 2101)
+* \ (backslash), \< operator (gawk): GNU Regexp Operators.
+ (line 2477)
+* \ (backslash), \> operator (gawk): GNU Regexp Operators.
+ (line 2481)
+* \ (backslash), \` operator (gawk): GNU Regexp Operators.
+ (line 2501)
+* \ (backslash), \a escape sequence: Escape Sequences. (line 2066)
+* \ (backslash), \b escape sequence: Escape Sequences. (line 2070)
+* \ (backslash), \B operator (gawk): GNU Regexp Operators.
+ (line 2490)
+* \ (backslash), \f escape sequence: Escape Sequences. (line 2073)
+* \ (backslash), \n escape sequence: Escape Sequences. (line 2076)
+* \ (backslash), \NNN escape sequence: Escape Sequences. (line 2088)
+* \ (backslash), \r escape sequence: Escape Sequences. (line 2079)
+* \ (backslash), \t escape sequence: Escape Sequences. (line 2082)
+* \ (backslash), \v escape sequence: Escape Sequences. (line 2085)
+* \ (backslash), \W operator (gawk): GNU Regexp Operators.
+ (line 2473)
+* \ (backslash), \w operator (gawk): GNU Regexp Operators.
+ (line 2468)
+* \ (backslash), \x escape sequence: Escape Sequences. (line 2093)
+* \ (backslash), \y operator (gawk): GNU Regexp Operators.
+ (line 2485)
+* \ (backslash), as field separators: Command Line Field Separator.
+ (line 3448)
+* \ (backslash), continuing lines and <1>: Egrep Program. (line 14737)
+* \ (backslash), continuing lines and: Statements/Lines. (line 1783)
+* \ (backslash), continuing lines and, comments and: Statements/Lines.
+ (line 1838)
+* \ (backslash), continuing lines and, in csh <1>: Statements/Lines.
+ (line 1807)
+* \ (backslash), continuing lines and, in csh: More Complex.
+ (line 1708)
+* \ (backslash), gsub/gensub/sub functions and: Gory Details.
+ (line 9642)
+* \ (backslash), in character lists: Character Lists. (line 2364)
+* \ (backslash), in escape sequences: Escape Sequences. (line 2038)
+* \ (backslash), in escape sequences, POSIX and: Escape Sequences.
+ (line 2145)
+* \ (backslash), regexp constants: Computed Regexps. (line 2677)
+* ^ (caret) <1>: GNU Regexp Operators.
+ (line 2506)
+* ^ (caret): Regexp Operators. (line 2197)
+* ^ (caret), ^ operator <1>: Options. (line 12191)
+* ^ (caret), ^ operator: Precedence. (line 6695)
+* ^ (caret), ^= operator <1>: Options. (line 12191)
+* ^ (caret), ^= operator <2>: Precedence. (line 6742)
+* ^ (caret), ^= operator: Assignment Ops. (line 6111)
+* ^ (caret), in character lists: Character Lists. (line 2364)
+* _ (underscore), _ C macro: Explaining gettext.
+ (line 10983)
+* _ (underscore), in names of private variables: Library Names.
+ (line 12564)
+* _ (underscore), translatable string: Programmer i18n. (line 11112)
+* _gr_init user-defined function: Group Functions. (line 14042)
+* _pw_init user-defined function: Passwd Functions. (line 13828)
+* accessing fields: Fields. (line 3014)
+* account information <1>: Group Functions. (line 13968)
+* account information: Passwd Functions. (line 13753)
+* actions: Action Overview. (line 7165)
+* actions, control statements in: Statements. (line 7224)
+* actions, default: Very Simple. (line 1559)
+* actions, empty: Very Simple. (line 1564)
+* adding, features to gawk: Adding Code. (line 18547)
+* adding, fields: Changing Fields. (line 3177)
+* adding, functions to gawk: Dynamic Extensions.
+ (line 18765)
+* advanced features, buffering: I/O Functions. (line 9904)
+* advanced features, close function: Close Files And Pipes.
+ (line 5323)
+* advanced features, constants, values of: Nondecimal-numbers.
+ (line 5518)
+* advanced features, data files as single record: Records. (line 2979)
+* advanced features, fixed-width data: Constant Size. (line 3605)
+* advanced features, FNR/NR variables: Auto-set. (line 8148)
+* advanced features, gawk: Advanced Features. (line 11449)
+* advanced features, gawk, BSD portals: Portal Files. (line 11725)
+* advanced features, gawk, network programming: TCP/IP Networking.
+ (line 11658)
+* advanced features, gawk, nondecimal input data: Nondecimal Data.
+ (line 11480)
+* advanced features, gawk, processes, communicating with: Two-way I/O.
+ (line 11539)
+* advanced features, network connections, See Also networks, connections: Advanced Features.
+ (line 11449)
+* advanced features, null strings, matching: Gory Details. (line 9796)
+* advanced features, operators, precedence: Increment Ops. (line 6215)
+* advanced features, piping into sh: Redirection. (line 4981)
+* advanced features, regexp constants: Assignment Ops. (line 6137)
+* Aho, Alfred <1>: Contributors. (line 17062)
+* Aho, Alfred: History. (line 640)
+* alarm clock example program: Alarm Program. (line 15480)
+* alarm.awk program: Alarm Program. (line 15498)
+* algorithms: Basic High Level. (line 19603)
+* Alpha (DEC): Manual History. (line 886)
+* amazing awk assembler (aaa): Glossary. (line 19837)
+* amazingly workable formatter (awf): Glossary. (line 19845)
+* ambiguity, syntactic: /= operator vs. /=.../ regexp constant: Assignment Ops.
+ (line 6137)
+* amiga: Amiga Installation.
+ (line 17569)
+* ampersand (&), && operator: Boolean Ops. (line 6514)
+* ampersand (&), &&operator: Precedence. (line 6733)
+* ampersand (&), gsub/gensub/sub functions and: Gory Details.
+ (line 9642)
+* AND bitwise operation: Bitwise Functions. (line 10314)
+* and Boolean-logic operator: Boolean Ops. (line 6463)
+* and function (gawk): Bitwise Functions. (line 10347)
+* ANSI: Glossary. (line 19856)
+* archeologists: Bugs. (line 18314)
+* ARGC/ARGV variables <1>: ARGC and ARGV. (line 8180)
+* ARGC/ARGV variables: Auto-set. (line 7972)
+* ARGC/ARGV variables, command-line arguments: Other Arguments.
+ (line 12311)
+* ARGC/ARGV variables, portability and: Executable Scripts.
+ (line 1270)
+* ARGIND variable: Auto-set. (line 8001)
+* ARGIND variable, command-line arguments: Other Arguments. (line 12311)
+* arguments, command-line <1>: Other Arguments. (line 12305)
+* arguments, command-line <2>: ARGC and ARGV. (line 8180)
+* arguments, command-line: Auto-set. (line 7972)
+* arguments, command-line, invoking awk: Command Line. (line 11988)
+* arguments, in function calls: Function Calls. (line 6603)
+* arguments, processing: Getopt Function. (line 13460)
+* arguments, retrieving: Internals. (line 18907)
+* arithmetic operators: Arithmetic Ops. (line 5823)
+* arrays: Arrays. (line 8276)
+* arrays, as parameters to functions: Function Caveats. (line 10716)
+* arrays, associative: Array Intro. (line 8356)
+* arrays, associative, clearing: Internals. (line 18852)
+* arrays, associative, library functions and: Library Names.
+ (line 12592)
+* arrays, deleting entire contents: Delete. (line 8618)
+* arrays, elements, assigning: Assigning Elements.
+ (line 8460)
+* arrays, elements, deleting: Delete. (line 8585)
+* arrays, elements, installing: Internals. (line 18856)
+* arrays, elements, order of: Scanning an Array. (line 8571)
+* arrays, elements, referencing: Reference to Elements.
+ (line 8413)
+* arrays, elements, retrieving number of: String Functions. (line 9176)
+* arrays, for statement and: Scanning an Array. (line 8544)
+* arrays, IGNORECASE variable and: Array Intro. (line 8398)
+* arrays, indexing: Array Intro. (line 8356)
+* arrays, merging into strings: Join Function. (line 13067)
+* arrays, multidimensional: Multi-dimensional. (line 8754)
+* arrays, multidimensional, scanning: Multi-scanning. (line 8840)
+* arrays, names of: Arrays. (line 8287)
+* arrays, scanning: Scanning an Array. (line 8530)
+* arrays, sorting: Array Sorting. (line 8875)
+* arrays, sorting, IGNORECASE variable and: Array Sorting. (line 8953)
+* arrays, sparse: Array Intro. (line 8377)
+* arrays, subscripts: Numeric Array Subscripts.
+ (line 8656)
+* arrays, subscripts, uninitialized variables as: Uninitialized Subscripts.
+ (line 8707)
+* artificial intelligence, gawk and: Distribution contents.
+ (line 17294)
+* ASCII: Ordinal Functions. (line 13014)
+* asort function (gawk) <1>: String Functions. (line 9176)
+* asort function (gawk): Array Sorting. (line 8875)
+* asort function (gawk), arrays, sorting: Array Sorting. (line 8875)
+* asorti function (gawk): String Functions. (line 9205)
+* assert function (C library): Assert Function. (line 12815)
+* assert user-defined function: Assert Function. (line 12837)
+* assertions: Assert Function. (line 12815)
+* assignment operators: Assignment Ops. (line 5989)
+* assignment operators, evaluation order: Assignment Ops. (line 6093)
+* assignment operators, lvalues/rvalues: Assignment Ops. (line 6014)
+* assignments as filenames: Ignoring Assigns. (line 13418)
+* assoc_clear internal function: Internals. (line 18852)
+* assoc_lookup internal function: Internals. (line 18856)
+* associative arrays: Array Intro. (line 8356)
+* asterisk (*), * operator, as multiplication operator: Precedence.
+ (line 6701)
+* asterisk (*), * operator, as regexp operator: Regexp Operators.
+ (line 2261)
+* asterisk (*), * operator, null strings, matching: Gory Details.
+ (line 9796)
+* asterisk (*), ** operator <1>: Options. (line 12191)
+* asterisk (*), ** operator <2>: Precedence. (line 6695)
+* asterisk (*), ** operator: Arithmetic Ops. (line 5898)
+* asterisk (*), **= operator <1>: Options. (line 12191)
+* asterisk (*), **= operator <2>: Precedence. (line 6742)
+* asterisk (*), **= operator: Assignment Ops. (line 6111)
+* asterisk (*), *= operator <1>: Precedence. (line 6742)
+* asterisk (*), *= operator: Assignment Ops. (line 6111)
+* atan2 function: Numeric Functions. (line 9082)
+* atari: Atari Installation.
+ (line 18161)
+* awf (amazingly workable formatter) program: Glossary. (line 19845)
+* awk language, POSIX version: Assignment Ops. (line 6122)
+* awk programs <1>: Two Rules. (line 1647)
+* awk programs <2>: Executable Scripts.
+ (line 1233)
+* awk programs: Getting Started. (line 1038)
+* awk programs, complex: When. (line 1923)
+* awk programs, documenting <1>: Library Names. (line 12541)
+* awk programs, documenting: Comments. (line 1296)
+* awk programs, examples of: Sample Programs. (line 14200)
+* awk programs, execution of: Next Statement. (line 7645)
+* awk programs, internationalizing <1>: Programmer i18n. (line 11051)
+* awk programs, internationalizing: I18N Functions. (line 10436)
+* awk programs, lengthy: Long. (line 1196)
+* awk programs, lengthy, assertions: Assert Function. (line 12815)
+* awk programs, location of: Options. (line 12031)
+* awk programs, one-line examples: Very Simple. (line 1570)
+* awk programs, profiling: Profiling. (line 11740)
+* awk programs, profiling, enabling: Options. (line 12208)
+* awk programs, running <1>: Long. (line 1196)
+* awk programs, running: Running gawk. (line 1084)
+* awk programs, running, from shell scripts: One-shot. (line 1133)
+* awk programs, running, without input files: Read Terminal.
+ (line 1157)
+* awk programs, shell variables in: Using Shell Variables.
+ (line 7114)
+* awk, function of: Getting Started. (line 1032)
+* awk, gawk and <1>: This Manual. (line 718)
+* awk, gawk and: Preface. (line 569)
+* awk, history of: History. (line 640)
+* awk, implementation issues, pipes: Redirection. (line 4973)
+* awk, implementations: Other Versions. (line 18383)
+* awk, implementations, limits: Getline Notes. (line 4193)
+* awk, invoking: Command Line. (line 11988)
+* awk, new vs. old: Names. (line 677)
+* awk, new vs. old, OFMT variable: Conversion. (line 5767)
+* awk, POSIX and: Preface. (line 569)
+* awk, POSIX and, See Also POSIX awk: Preface. (line 569)
+* awk, regexp constants and: Typing and Comparison.
+ (line 6442)
+* awk, See Also gawk: Preface. (line 582)
+* awk, terms describing: This Manual. (line 711)
+* awk, uses for <1>: When. (line 1899)
+* awk, uses for <2>: Getting Started. (line 1038)
+* awk, uses for: Preface. (line 569)
+* awk, versions of <1>: V7/SVR3.1. (line 16665)
+* awk, versions of: Names. (line 681)
+* awk, versions of, changes between SVR3.1 and SVR4: SVR4. (line 16724)
+* awk, versions of, changes between SVR4 and POSIX awk: POSIX.
+ (line 16765)
+* awk, versions of, changes between V7 and SVR3.1: V7/SVR3.1.
+ (line 16665)
+* awk, versions of, See Also Bell Laboratories awk: BTL. (line 16809)
+* awk.h file (internal): Internals. (line 18801)
+* awka compiler for awk: Other Versions. (line 18453)
+* AWKNUM internal type: Internals. (line 18805)
+* AWKPATH environment variable <1>: PC Using. (line 17858)
+* AWKPATH environment variable: AWKPATH Variable. (line 12361)
+* awkprof.out file: Profiling. (line 11744)
+* awksed.awk program: Simple Sed. (line 16189)
+* awkvars.out file: Options. (line 12101)
+* backslash (\) <1>: Regexp Operators. (line 2193)
+* backslash (\) <2>: Quoting. (line 1370)
+* backslash (\) <3>: Comments. (line 1339)
+* backslash (\): Read Terminal. (line 1165)
+* backslash (\), \" escape sequence: Escape Sequences. (line 2108)
+* backslash (\), \' operator (gawk): GNU Regexp Operators.
+ (line 2503)
+* backslash (\), \/ escape sequence: Escape Sequences. (line 2101)
+* backslash (\), \< operator (gawk): GNU Regexp Operators.
+ (line 2477)
+* backslash (\), \> operator (gawk): GNU Regexp Operators.
+ (line 2481)
+* backslash (\), \` operator (gawk): GNU Regexp Operators.
+ (line 2501)
+* backslash (\), \a escape sequence: Escape Sequences. (line 2066)
+* backslash (\), \b escape sequence: Escape Sequences. (line 2070)
+* backslash (\), \B operator (gawk): GNU Regexp Operators.
+ (line 2490)
+* backslash (\), \f escape sequence: Escape Sequences. (line 2073)
+* backslash (\), \n escape sequence: Escape Sequences. (line 2076)
+* backslash (\), \NNN escape sequence: Escape Sequences. (line 2088)
+* backslash (\), \r escape sequence: Escape Sequences. (line 2079)
+* backslash (\), \t escape sequence: Escape Sequences. (line 2082)
+* backslash (\), \v escape sequence: Escape Sequences. (line 2085)
+* backslash (\), \W operator (gawk): GNU Regexp Operators.
+ (line 2473)
+* backslash (\), \w operator (gawk): GNU Regexp Operators.
+ (line 2468)
+* backslash (\), \x escape sequence: Escape Sequences. (line 2093)
+* backslash (\), \y operator (gawk): GNU Regexp Operators.
+ (line 2485)
+* backslash (\), as field separators: Command Line Field Separator.
+ (line 3448)
+* backslash (\), continuing lines and <1>: Egrep Program. (line 14737)
+* backslash (\), continuing lines and: Statements/Lines. (line 1783)
+* backslash (\), continuing lines and, comments and: Statements/Lines.
+ (line 1838)
+* backslash (\), continuing lines and, in csh <1>: Statements/Lines.
+ (line 1807)
+* backslash (\), continuing lines and, in csh: More Complex.
+ (line 1708)
+* backslash (\), gsub/gensub/sub functions and: Gory Details.
+ (line 9642)
+* backslash (\), in character lists: Character Lists. (line 2364)
+* backslash (\), in escape sequences: Escape Sequences. (line 2038)
+* backslash (\), in escape sequences, POSIX and: Escape Sequences.
+ (line 2145)
+* backslash (\), regexp constants: Computed Regexps. (line 2677)
+* BBS-list file: Sample Data Files. (line 1461)
+* Beebe, Nelson: Acknowledgments. (line 995)
+* Beebe, Nelson H.F.: Other Versions. (line 18465)
+* BEGIN pattern <1>: BEGIN/END. (line 6980)
+* BEGIN pattern <2>: Field Separators. (line 3300)
+* BEGIN pattern: Records. (line 2839)
+* BEGIN pattern, assert user-defined function and: Assert Function.
+ (line 12891)
+* BEGIN pattern, Boolean patterns and: Expression Patterns.
+ (line 6900)
+* BEGIN pattern, exit statement and: Exit Statement. (line 7743)
+* BEGIN pattern, getline and: Getline Notes. (line 4198)
+* BEGIN pattern, headings, adding: Print Examples. (line 4350)
+* BEGIN pattern, next/nextfile statements and <1>: Next Statement.
+ (line 7668)
+* BEGIN pattern, next/nextfile statements and: I/O And BEGIN/END.
+ (line 7088)
+* BEGIN pattern, OFS/ORS variables, assigning values to: Output Separators.
+ (line 4407)
+* BEGIN pattern, operators and: Using BEGIN/END. (line 7010)
+* BEGIN pattern, pgawk program: Profiling. (line 11802)
+* BEGIN pattern, print statement and: I/O And BEGIN/END. (line 7068)
+* BEGIN pattern, pwcat program: Passwd Functions. (line 13862)
+* BEGIN pattern, running awk programs and: Cut Program. (line 14331)
+* BEGIN pattern, TEXTDOMAIN variable and: Programmer i18n. (line 11103)
+* beginfile user-defined function: Filetrans Function.
+ (line 13265)
+* Bell Laboratories awk extensions: BTL. (line 16809)
+* Benzinger, Michael: Contributors. (line 17135)
+* BeOS: BeOS Installation. (line 17602)
+* Berry, Karl: Acknowledgments. (line 972)
+* binary input/output: User-modified. (line 7817)
+* bindtextdomain function (C library): Explaining gettext.
+ (line 10962)
+* bindtextdomain function (gawk) <1>: Programmer i18n. (line 11090)
+* bindtextdomain function (gawk): I18N Functions. (line 10456)
+* bindtextdomain function (gawk), portability and: I18N Portability.
+ (line 11306)
+* BINMODE variable <1>: PC Using. (line 17887)
+* BINMODE variable: User-modified. (line 7817)
+* bits2str user-defined function: Bitwise Functions. (line 10368)
+* bitwise, complement: Bitwise Functions. (line 10333)
+* bitwise, operations: Bitwise Functions. (line 10314)
+* bitwise, shift: Bitwise Functions. (line 10340)
+* body, in actions: Statements. (line 7228)
+* body, in loops: While Statement. (line 7307)
+* Boolean expressions: Boolean Ops. (line 6463)
+* Boolean expressions, as patterns: Expression Patterns.
+ (line 6868)
+* Boolean operators, See Boolean expressions: Boolean Ops. (line 6463)
+* Bourne shell, quoting rules for: Quoting. (line 1357)
+* braces ({}), actions and: Action Overview. (line 7178)
+* braces ({}), pgawk program: Profiling. (line 11873)
+* braces ({}), statements, grouping: Statements. (line 7228)
+* bracket expressions, See character lists: Regexp Operators.
+ (line 2230)
+* break statement: Break Statement. (line 7525)
+* Brennan, Michael <1>: Other Versions. (line 18383)
+* Brennan, Michael <2>: Simple Sed. (line 16189)
+* Brennan, Michael <3>: Two-way I/O. (line 11522)
+* Brennan, Michael: Delete. (line 8630)
+* Broder, Alan J.: Contributors. (line 17126)
+* Brown, Martin <1>: Bugs. (line 18364)
+* Brown, Martin <2>: Contributors. (line 17121)
+* Brown, Martin: Acknowledgments. (line 995)
+* BSD portals: Portal Files. (line 11725)
+* BSD-based operating systems: Glossary. (line 20404)
+* Buening, Andreas <1>: Contributors. (line 17130)
+* Buening, Andreas: Acknowledgments. (line 995)
+* buffering, input/output <1>: Two-way I/O. (line 11587)
+* buffering, input/output: I/O Functions. (line 9936)
+* buffering, interactive vs. noninteractive: I/O Functions. (line 9904)
+* buffers, flushing: I/O Functions. (line 9838)
+* buffers, operators for: GNU Regexp Operators.
+ (line 2495)
+* bug reports, email address, bug-gawk@gnu.org: Bugs. (line 18335)
+* bug-gawk@gnu.org bug reporting address: Bugs. (line 18335)
+* built-in functions: Functions. (line 8964)
+* built-in functions, evaluation order: Calling Built-in. (line 9031)
+* built-in variables: Built-in Variables.
+ (line 7787)
+* built-in variables, -v option, setting with: Options. (line 12044)
+* built-in variables, conveying information: Auto-set. (line 7967)
+* built-in variables, user-modifiable: User-modified. (line 7813)
+* call by reference: Function Caveats. (line 10716)
+* call by value: Function Caveats. (line 10687)
+* caret (^) <1>: GNU Regexp Operators.
+ (line 2506)
+* caret (^): Regexp Operators. (line 2197)
+* caret (^), ^ operator <1>: Options. (line 12191)
+* caret (^), ^ operator: Precedence. (line 6695)
+* caret (^), ^= operator <1>: Options. (line 12191)
+* caret (^), ^= operator <2>: Precedence. (line 6742)
+* caret (^), ^= operator: Assignment Ops. (line 6111)
+* caret (^), in character lists: Character Lists. (line 2364)
+* case keyword: Switch Statement. (line 7464)
+* case sensitivity, array indices and: Array Intro. (line 8398)
+* case sensitivity, converting case: String Functions. (line 9611)
+* case sensitivity, example programs: Library Functions. (line 12506)
+* case sensitivity, gawk: Case-sensitivity. (line 2569)
+* case sensitivity, regexps and <1>: User-modified. (line 7875)
+* case sensitivity, regexps and: Case-sensitivity. (line 2549)
+* case sensitivity, string comparisons and: User-modified. (line 7875)
+* CGI, awk scripts for: Options. (line 12117)
+* character encodings: Ordinal Functions. (line 13014)
+* character lists <1>: Character Lists. (line 2353)
+* character lists: Regexp Operators. (line 2230)
+* character lists, character classes: Character Lists. (line 2377)
+* character lists, collating elements: Character Lists. (line 2430)
+* character lists, collating symbols: Character Lists. (line 2437)
+* character lists, complemented: Regexp Operators. (line 2237)
+* character lists, equivalence classes: Character Lists. (line 2443)
+* character lists, non-ASCII: Character Lists. (line 2430)
+* character lists, range expressions: Character Lists. (line 2353)
+* character sets: Ordinal Functions. (line 13014)
+* character sets (machine character encodings): Glossary. (line 19963)
+* character sets, See Also character lists: Regexp Operators.
+ (line 2230)
+* characters, counting: Wc Program. (line 15264)
+* characters, transliterating: Translate Program. (line 15601)
+* characters, values of as numbers: Ordinal Functions. (line 12976)
+* Chassell, Robert J.: Acknowledgments. (line 972)
+* chdir function, implementing in gawk: Sample Library. (line 19054)
+* chem utility: Glossary. (line 19971)
+* chr user-defined function: Ordinal Functions. (line 12986)
+* Cliff random numbers: Cliff Random Function.
+ (line 12945)
+* cliff_rand user-defined function: Cliff Random Function.
+ (line 12950)
+* close function <1>: I/O Functions. (line 9819)
+* close function <2>: Close Files And Pipes.
+ (line 5211)
+* close function <3>: Getline/Pipe. (line 4069)
+* close function: Getline/Variable/File.
+ (line 4036)
+* close function, return values: Close Files And Pipes.
+ (line 5323)
+* close function, two-way pipes and: Two-way I/O. (line 11594)
+* Close, Diane <1>: Contributors. (line 17071)
+* Close, Diane: Manual History. (line 898)
+* close_func input method: Internals. (line 18964)
+* collating elements: Character Lists. (line 2430)
+* collating symbols: Character Lists. (line 2437)
+* columns, aligning: Print Examples. (line 4377)
+* columns, cutting: Cut Program. (line 14271)
+* comma (,), in range patterns: Ranges. (line 6913)
+* command line, arguments <1>: Other Arguments. (line 12305)
+* command line, arguments <2>: ARGC and ARGV. (line 8180)
+* command line, arguments: Auto-set. (line 7972)
+* command line, formats: Running gawk. (line 1090)
+* command line, FS on, setting: Command Line Field Separator.
+ (line 3427)
+* command line, invoking awk from: Command Line. (line 11988)
+* command line, options <1>: Options. (line 12012)
+* command line, options <2>: Command Line Field Separator.
+ (line 3427)
+* command line, options: Long. (line 1202)
+* command line, options, end of: Options. (line 12068)
+* command line, variables, assigning on: Assignment Options.
+ (line 5671)
+* command-line options, processing: Getopt Function. (line 13460)
+* command-line options, string extraction: String Extraction.
+ (line 11177)
+* commenting: Comments. (line 1296)
+* commenting, backslash continuation and: Statements/Lines. (line 1838)
+* comp.lang.awk newsgroup: Bugs. (line 18344)
+* comparison expressions: Typing and Comparison.
+ (line 6277)
+* comparison expressions, as patterns: Expression Patterns.
+ (line 6841)
+* comparison expressions, string vs. regexp: Typing and Comparison.
+ (line 6419)
+* compatibility mode (gawk), extensions: POSIX/GNU. (line 16852)
+* compatibility mode (gawk), file names: Special Caveats. (line 5167)
+* compatibility mode (gawk), hexadecimal numbers: Nondecimal-numbers.
+ (line 5511)
+* compatibility mode (gawk), octal numbers: Nondecimal-numbers.
+ (line 5511)
+* compatibility mode (gawk), specifying: Options. (line 12085)
+* compiled programs <1>: Glossary. (line 19981)
+* compiled programs: Basic High Level. (line 19551)
+* compl function (gawk): Bitwise Functions. (line 10351)
+* complement, bitwise: Bitwise Functions. (line 10333)
+* compound statements, control statements and: Statements. (line 7228)
+* concatenating: Concatenation. (line 5911)
+* conditional expressions: Conditional Exp. (line 6553)
+* configuration option, --disable-lint: Additional Configuration Options.
+ (line 17477)
+* configuration option, --disable-nls: Additional Configuration Options.
+ (line 17492)
+* configuration option, --enable-portals: Additional Configuration Options.
+ (line 17469)
+* configuration option, --enable-switch: Additional Configuration Options.
+ (line 17473)
+* configuration options, gawk: Additional Configuration Options.
+ (line 17466)
+* constants, nondecimal: Nondecimal Data. (line 11480)
+* constants, types of: Constants. (line 5405)
+* continue statement: Continue Statement.
+ (line 7582)
+* control statements: Statements. (line 7224)
+* converting, case: String Functions. (line 9611)
+* converting, dates to timestamps: Time Functions. (line 10050)
+* converting, during subscripting: Numeric Array Subscripts.
+ (line 8681)
+* converting, numbers: Conversion. (line 5719)
+* converting, numbers, to strings: Bitwise Functions. (line 10407)
+* converting, strings to numbers: Conversion. (line 5719)
+* CONVFMT variable <1>: User-modified. (line 7833)
+* CONVFMT variable: Conversion. (line 5742)
+* CONVFMT variable, array subscripts and: Numeric Array Subscripts.
+ (line 8656)
+* coprocesses <1>: Two-way I/O. (line 11560)
+* coprocesses: Redirection. (line 4944)
+* coprocesses, closing: Close Files And Pipes.
+ (line 5199)
+* coprocesses, getline from: Getline/Coprocess. (line 4137)
+* cos function: Numeric Functions. (line 9079)
+* counting: Wc Program. (line 15264)
+* csh utility: Statements/Lines. (line 1807)
+* csh utility, backslash continuation and: More Complex. (line 1708)
+* csh utility, POSIXLY_CORRECT environment variable: Options.
+ (line 12286)
+* csh utility, |& operator, comparison with: Two-way I/O. (line 11560)
+* ctime user-defined function: Function Example. (line 10649)
+* currency symbols, localization: Explaining gettext.
+ (line 11014)
+* custom.h file: Configuration Philosophy.
+ (line 17530)
+* cut utility: Cut Program. (line 14271)
+* cut.awk program: Cut Program. (line 14309)
+* d.c., See dark corner: Conventions. (line 850)
+* dark corner <1>: Glossary. (line 20013)
+* dark corner <2>: Truth Values. (line 6264)
+* dark corner <3>: Assignment Ops. (line 6137)
+* dark corner <4>: Format Modifiers. (line 4667)
+* dark corner: Conventions. (line 850)
+* dark corner, array subscripts: Uninitialized Subscripts.
+ (line 8743)
+* dark corner, break statement: Break Statement. (line 7566)
+* dark corner, close function: Close Files And Pipes.
+ (line 5323)
+* dark corner, command-line arguments: Assignment Options.
+ (line 5708)
+* dark corner, continue statement: Continue Statement.
+ (line 7619)
+* dark corner, CONVFMT variable: Conversion. (line 5753)
+* dark corner, escape sequences: Other Arguments. (line 12330)
+* dark corner, escape sequences, for metacharacters: Escape Sequences.
+ (line 2168)
+* dark corner, exit statement: Exit Statement. (line 7760)
+* dark corner, field separators: Field Splitting Summary.
+ (line 3555)
+* dark corner, FILENAME variable <1>: Auto-set. (line 8049)
+* dark corner, FILENAME variable: Getline Notes. (line 4198)
+* dark corner, FNR/NR variables: Auto-set. (line 8148)
+* dark corner, format-control characters: Control Letters. (line 4601)
+* dark corner, FS as null string: Single Character Fields.
+ (line 3415)
+* dark corner, input files: Records. (line 2908)
+* dark corner, invoking awk: Command Line. (line 11998)
+* dark corner, multiline records: Multiple Line. (line 3734)
+* dark corner, NF variable, decrementing: Changing Fields. (line 3231)
+* dark corner, OFMT variable: OFMT. (line 4455)
+* dark corner, regexp constants: Using Constant Regexps.
+ (line 5544)
+* dark corner, regexp constants, /= operator and: Assignment Ops.
+ (line 6137)
+* dark corner, regexp constants, as arguments to user-defined functions: Using Constant Regexps.
+ (line 5582)
+* dark corner, split function: String Functions. (line 9378)
+* dark corner, strings, storing: Records. (line 2995)
+* data, fixed-width: Constant Size. (line 3605)
+* data-driven languages: Basic High Level. (line 19620)
+* database, group, reading: Group Functions. (line 13968)
+* database, users, reading: Passwd Functions. (line 13743)
+* date utility, GNU: Time Functions. (line 9998)
+* date utility, POSIX: Time Functions. (line 10245)
+* dates, converting to timestamps: Time Functions. (line 10050)
+* dates, information related to, localization: Explaining gettext.
+ (line 11026)
+* Davies, Stephen <1>: Bugs. (line 18369)
+* Davies, Stephen: Contributors. (line 17118)
+* dcgettext function (gawk) <1>: Programmer i18n. (line 11064)
+* dcgettext function (gawk): I18N Functions. (line 10442)
+* dcgettext function (gawk), portability and: I18N Portability.
+ (line 11306)
+* dcngettext function (gawk) <1>: Programmer i18n. (line 11080)
+* dcngettext function (gawk): I18N Functions. (line 10448)
+* dcngettext function (gawk), portability and: I18N Portability.
+ (line 11306)
+* deadlocks: Two-way I/O. (line 11587)
+* debugging gawk: Known Bugs. (line 12454)
+* debugging gawk, bug reports: Bugs. (line 18317)
+* decrement operators: Increment Ops. (line 6189)
+* default keyword: Switch Statement. (line 7464)
+* Deifik, Scott <1>: Bugs. (line 18365)
+* Deifik, Scott <2>: Contributors. (line 17102)
+* Deifik, Scott: Acknowledgments. (line 995)
+* delete statement: Delete. (line 8585)
+* deleting elements in arrays: Delete. (line 8585)
+* deleting entire arrays: Delete. (line 8618)
+* differences between gawk and awk: String Functions. (line 9246)
+* differences in awk and gawk, ARGC/ARGV variables: ARGC and ARGV.
+ (line 8259)
+* differences in awk and gawk, ARGIND variable: Auto-set. (line 8001)
+* differences in awk and gawk, array elements, deleting: Delete.
+ (line 8618)
+* differences in awk and gawk, AWKPATH environment variable: AWKPATH Variable.
+ (line 12361)
+* differences in awk and gawk, BEGIN/END patterns: I/O And BEGIN/END.
+ (line 7068)
+* differences in awk and gawk, BINMODE variable <1>: PC Using.
+ (line 17887)
+* differences in awk and gawk, BINMODE variable: User-modified.
+ (line 7828)
+* differences in awk and gawk, close function: Close Files And Pipes.
+ (line 5274)
+* differences in awk and gawk, ERRNO variable: Auto-set. (line 8033)
+* differences in awk and gawk, error messages: Special FD. (line 5028)
+* differences in awk and gawk, FIELDWIDTHS variable: User-modified.
+ (line 7840)
+* differences in awk and gawk, function arguments (gawk): Calling Built-in.
+ (line 9017)
+* differences in awk and gawk, getline command: Getline. (line 3856)
+* differences in awk and gawk, IGNORECASE variable: User-modified.
+ (line 7875)
+* differences in awk and gawk, implementation limitations <1>: Redirection.
+ (line 4973)
+* differences in awk and gawk, implementation limitations: Getline Notes.
+ (line 4193)
+* differences in awk and gawk, input/output operators <1>: Redirection.
+ (line 4944)
+* differences in awk and gawk, input/output operators: Getline/Coprocess.
+ (line 4137)
+* differences in awk and gawk, line continuations: Conditional Exp.
+ (line 6581)
+* differences in awk and gawk, LINT variable: User-modified.
+ (line 7890)
+* differences in awk and gawk, match function: String Functions.
+ (line 9309)
+* differences in awk and gawk, next/nextfile statements: Nextfile Statement.
+ (line 7684)
+* differences in awk and gawk, print/printf statements: Format Modifiers.
+ (line 4621)
+* differences in awk and gawk, PROCINFO array: Auto-set. (line 8080)
+* differences in awk and gawk, record separators: Records. (line 2921)
+* differences in awk and gawk, regexp constants: Using Constant Regexps.
+ (line 5582)
+* differences in awk and gawk, regular expressions: Case-sensitivity.
+ (line 2569)
+* differences in awk and gawk, RS/RT variables: Records. (line 2971)
+* differences in awk and gawk, RT variable: Auto-set. (line 8137)
+* differences in awk and gawk, single-character fields: Single Character Fields.
+ (line 3401)
+* differences in awk and gawk, split function: String Functions.
+ (line 9367)
+* differences in awk and gawk, strings: Scalar Constants. (line 5439)
+* differences in awk and gawk, strings, storing: Records. (line 2991)
+* differences in awk and gawk, strtonum function (gawk): String Functions.
+ (line 9405)
+* differences in awk and gawk, TEXTDOMAIN variable: User-modified.
+ (line 7945)
+* differences in awk and gawk, trunc-mod operation: Arithmetic Ops.
+ (line 5883)
+* directories, changing: Sample Library. (line 19054)
+* directories, searching <1>: Igawk Program. (line 16601)
+* directories, searching: AWKPATH Variable. (line 12361)
+* division: Arithmetic Ops. (line 5861)
+* do-while statement <1>: Do Statement. (line 7346)
+* do-while statement: Regexp Usage. (line 1989)
+* documentation, of awk programs: Library Names. (line 12541)
+* documentation, online: Manual History. (line 870)
+* documents, searching: Dupword Program. (line 15429)
+* dollar sign ($): Regexp Operators. (line 2210)
+* dollar sign ($), $ field operator <1>: Precedence. (line 6689)
+* dollar sign ($), $ field operator: Fields. (line 3027)
+* dollar sign ($), incrementing fields and arrays: Increment Ops.
+ (line 6184)
+* double quote (") <1>: Quoting. (line 1376)
+* double quote ("): Read Terminal. (line 1165)
+* double quote ("), regexp constants: Computed Regexps. (line 2677)
+* double-precision floating-point: Basic Data Typing. (line 19666)
+* Drepper, Ulrich: Acknowledgments. (line 991)
+* dupnode internal function: Internals. (line 18883)
+* dupword.awk program: Dupword Program. (line 15454)
+* EBCDIC: Ordinal Functions. (line 13014)
+* egrep utility <1>: Egrep Program. (line 14525)
+* egrep utility: Character Lists. (line 2371)
+* egrep.awk program: Egrep Program. (line 14573)
+* elements in arrays: Reference to Elements.
+ (line 8413)
+* elements in arrays, assigning: Assigning Elements.
+ (line 8460)
+* elements in arrays, deleting: Delete. (line 8585)
+* elements in arrays, order of: Scanning an Array. (line 8571)
+* elements in arrays, scanning: Scanning an Array. (line 8530)
+* email address for bug reports, bug-gawk@gnu.org: Bugs. (line 18335)
+* EMISTERED: TCP/IP Networking. (line 11658)
+* empty pattern: Empty. (line 7101)
+* empty strings, See null strings: Regexp Field Splitting.
+ (line 3379)
+* END pattern: BEGIN/END. (line 6980)
+* END pattern, assert user-defined function and: Assert Function.
+ (line 12883)
+* END pattern, backslash continuation and: Egrep Program. (line 14737)
+* END pattern, Boolean patterns and: Expression Patterns.
+ (line 6900)
+* END pattern, exit statement and: Exit Statement. (line 7743)
+* END pattern, next/nextfile statements and <1>: Next Statement.
+ (line 7668)
+* END pattern, next/nextfile statements and: I/O And BEGIN/END.
+ (line 7088)
+* END pattern, operators and: Using BEGIN/END. (line 7010)
+* END pattern, pgawk program: Profiling. (line 11802)
+* END pattern, print statement and: I/O And BEGIN/END. (line 7068)
+* endfile user-defined function: Filetrans Function.
+ (line 13265)
+* endgrent function (C library): Group Functions. (line 14175)
+* endgrent user-defined function: Group Functions. (line 14178)
+* endpwent function (C library): Passwd Functions. (line 13929)
+* endpwent user-defined function: Passwd Functions. (line 13932)
+* ENVIRON variable <1>: Internals. (line 18951)
+* ENVIRON variable: Auto-set. (line 8021)
+* environment variables: Auto-set. (line 8021)
+* epoch, definition of: Glossary. (line 20055)
+* equals sign (=), = operator: Assignment Ops. (line 5989)
+* equals sign (=), == operator <1>: Precedence. (line 6711)
+* equals sign (=), == operator: Typing and Comparison.
+ (line 6342)
+* EREs (Extended Regular Expressions): Character Lists. (line 2371)
+* ERRNO variable <1>: Internals. (line 18938)
+* ERRNO variable <2>: Auto-set. (line 8033)
+* ERRNO variable: Getline. (line 3856)
+* error handling: Special FD. (line 5028)
+* error handling, ERRNO variable and: Auto-set. (line 8033)
+* error output: Special FD. (line 5019)
+* escape processing, gsub/gensub/sub functions: Gory Details.
+ (line 9642)
+* escape sequences: Escape Sequences. (line 2038)
+* escape sequences, unrecognized: Options. (line 12179)
+* evaluation order: Increment Ops. (line 6215)
+* evaluation order, concatenation: Concatenation. (line 5943)
+* evaluation order, functions: Calling Built-in. (line 9031)
+* examining fields: Fields. (line 3014)
+* exclamation point (!), ! operator <1>: Egrep Program. (line 14679)
+* exclamation point (!), ! operator <2>: Precedence. (line 6698)
+* exclamation point (!), ! operator: Boolean Ops. (line 6524)
+* exclamation point (!), != operator <1>: Precedence. (line 6711)
+* exclamation point (!), != operator: Typing and Comparison.
+ (line 6342)
+* exclamation point (!), !~ operator <1>: Expression Patterns.
+ (line 6851)
+* exclamation point (!), !~ operator <2>: Precedence. (line 6727)
+* exclamation point (!), !~ operator <3>: Typing and Comparison.
+ (line 6342)
+* exclamation point (!), !~ operator <4>: Regexp Constants. (line 5532)
+* exclamation point (!), !~ operator <5>: Computed Regexps. (line 2656)
+* exclamation point (!), !~ operator <6>: Case-sensitivity. (line 2569)
+* exclamation point (!), !~ operator: Regexp Usage. (line 1989)
+* exit statement: Exit Statement. (line 7737)
+* exp function: Numeric Functions. (line 9067)
+* expand utility: Very Simple. (line 1594)
+* expressions: Expressions. (line 5362)
+* expressions, as patterns: Expression Patterns.
+ (line 6833)
+* expressions, assignment: Assignment Ops. (line 5989)
+* expressions, Boolean: Boolean Ops. (line 6463)
+* expressions, comparison: Typing and Comparison.
+ (line 6277)
+* expressions, conditional: Conditional Exp. (line 6553)
+* expressions, matching, See comparison expressions: Typing and Comparison.
+ (line 6277)
+* expressions, selecting: Conditional Exp. (line 6553)
+* Extended Regular Expressions (EREs): Character Lists. (line 2371)
+* extension function (gawk): Using Internal File Ops.
+ (line 19373)
+* extensions, Bell Laboratories awk: BTL. (line 16809)
+* extensions, in gawk, not in POSIX awk: POSIX/GNU. (line 16852)
+* extensions, mawk: Other Versions. (line 18423)
+* extract.awk program: Extract Program. (line 16050)
+* extraction, of marked strings (internationalization): String Extraction.
+ (line 11177)
+* false, logical: Truth Values. (line 6246)
+* FDL (Free Documentation License): GNU Free Documentation License.
+ (line 20789)
+* features, adding to gawk: Adding Code. (line 18547)
+* features, advanced, See advanced features: Obsolete. (line 12421)
+* features, deprecated: Obsolete. (line 12421)
+* features, undocumented: Undocumented. (line 12443)
+* Fenlason, Jay <1>: Contributors. (line 17069)
+* Fenlason, Jay: History. (line 653)
+* fflush function: I/O Functions. (line 9834)
+* fflush function, unsupported: Options. (line 12199)
+* field numbers: Nonconstant Fields.
+ (line 3085)
+* field operator $: Fields. (line 3027)
+* field operators, dollar sign as: Fields. (line 3027)
+* field separators <1>: User-modified. (line 7850)
+* field separators: Field Separators. (line 3271)
+* field separators, choice of: Field Separators. (line 3306)
+* field separators, FIELDWIDTHS variable and: User-modified.
+ (line 7840)
+* field separators, in multiline records: Multiple Line. (line 3740)
+* field separators, on command line: Command Line Field Separator.
+ (line 3427)
+* field separators, POSIX and <1>: Field Splitting Summary.
+ (line 3549)
+* field separators, POSIX and: Fields. (line 3014)
+* field separators, regular expressions as <1>: Regexp Field Splitting.
+ (line 3343)
+* field separators, regular expressions as: Field Separators.
+ (line 3306)
+* field separators, See Also OFS: Changing Fields. (line 3188)
+* field separators, spaces as: Cut Program. (line 14371)
+* fields <1>: Basic High Level. (line 19608)
+* fields <2>: Fields. (line 3014)
+* fields: Reading Files. (line 2788)
+* fields, adding: Changing Fields. (line 3177)
+* fields, changing contents of: Changing Fields. (line 3130)
+* fields, cutting: Cut Program. (line 14271)
+* fields, examining: Fields. (line 3014)
+* fields, number of: Fields. (line 3041)
+* fields, numbers: Nonconstant Fields.
+ (line 3085)
+* fields, printing: Print Examples. (line 4329)
+* fields, separating: Field Separators. (line 3271)
+* fields, single-character: Single Character Fields.
+ (line 3401)
+* FIELDWIDTHS variable <1>: User-modified. (line 7840)
+* FIELDWIDTHS variable: Constant Size. (line 3618)
+* file descriptors: Special FD. (line 5019)
+* file names, distinguishing: Auto-set. (line 8013)
+* file names, in compatibility mode: Special Caveats. (line 5167)
+* file names, standard streams in gawk: Special FD. (line 5054)
+* FILENAME variable <1>: Auto-set. (line 8049)
+* FILENAME variable: Reading Files. (line 2780)
+* FILENAME variable, getline, setting with: Getline Notes. (line 4198)
+* filenames, assignments as: Ignoring Assigns. (line 13418)
+* files, .mo: Explaining gettext.
+ (line 10954)
+* files, .mo, converting from .po: I18N Example. (line 11400)
+* files, .mo, specifying directory of <1>: Programmer i18n. (line 11090)
+* files, .mo, specifying directory of: Explaining gettext.
+ (line 10966)
+* files, .po <1>: Translator i18n. (line 11156)
+* files, .po: Explaining gettext.
+ (line 10951)
+* files, .po, converting to .mo: I18N Example. (line 11400)
+* files, /dev/... special files: Special FD. (line 5054)
+* files, /inet/ (gawk): TCP/IP Networking. (line 11658)
+* files, /p (gawk): Portal Files. (line 11725)
+* files, as single records: Records. (line 3000)
+* files, awk programs in: Long. (line 1196)
+* files, awkprof.out: Profiling. (line 11744)
+* files, awkvars.out: Options. (line 12101)
+* files, closing: I/O Functions. (line 9819)
+* files, descriptors, See file descriptors: Special FD. (line 5019)
+* files, for process information: Special Process. (line 5086)
+* files, group: Group Functions. (line 13968)
+* files, information about, retrieving: Sample Library. (line 19054)
+* files, initialization and cleanup: Filetrans Function.
+ (line 13211)
+* files, input, See input files: Read Terminal. (line 1157)
+* files, log, timestamps in: Time Functions. (line 9987)
+* files, managing: Data File Management.
+ (line 13194)
+* files, managing, data file boundaries: Filetrans Function.
+ (line 13211)
+* files, message object: Explaining gettext.
+ (line 10954)
+* files, message object, converting from portable object files: I18N Example.
+ (line 11400)
+* files, message object, specifying directory of <1>: Programmer i18n.
+ (line 11090)
+* files, message object, specifying directory of: Explaining gettext.
+ (line 10966)
+* files, multiple passes over: Other Arguments. (line 12348)
+* files, multiple, duplicating output into: Tee Program. (line 14964)
+* files, output, See output files: Close Files And Pipes.
+ (line 5199)
+* files, password: Passwd Functions. (line 13753)
+* files, portable object <1>: Translator i18n. (line 11156)
+* files, portable object: Explaining gettext.
+ (line 10951)
+* files, portable object, converting to message object files: I18N Example.
+ (line 11400)
+* files, portable object, generating: Options. (line 12136)
+* files, portal: Portal Files. (line 11725)
+* files, processing, ARGIND variable and: Auto-set. (line 8008)
+* files, reading: Rewind Function. (line 13292)
+* files, reading, multiline records: Multiple Line. (line 3705)
+* files, searching for regular expressions: Egrep Program. (line 14525)
+* files, skipping: File Checking. (line 13334)
+* files, source, search path for: Igawk Program. (line 16601)
+* files, splitting: Split Program. (line 14862)
+* files, Texinfo, extracting programs from: Extract Program.
+ (line 15979)
+* Fish, Fred <1>: Bugs. (line 18364)
+* Fish, Fred: Contributors. (line 17100)
+* fixed-width data: Constant Size. (line 3605)
+* flag variables <1>: Tee Program. (line 14978)
+* flag variables: Boolean Ops. (line 6524)
+* floating-point: Floating Point Issues.
+ (line 19776)
+* floating-point, numbers: Basic Data Typing. (line 19654)
+* floating-point, numbers, AWKNUM internal type: Internals. (line 18805)
+* FNR variable <1>: Auto-set. (line 8059)
+* FNR variable: Records. (line 2817)
+* FNR variable, changing: Auto-set. (line 8148)
+* for statement: For Statement. (line 7382)
+* for statement, in arrays: Scanning an Array. (line 8544)
+* force_number internal function: Internals. (line 18813)
+* force_string internal function: Internals. (line 18818)
+* format specifiers, mixing regular with positional specifiers: Printf Ordering.
+ (line 11254)
+* format specifiers, printf statement: Control Letters. (line 4527)
+* format specifiers, strftime function (gawk): Time Functions.
+ (line 10063)
+* format strings: Basic Printf. (line 4495)
+* formats, numeric output: OFMT. (line 4434)
+* formatting output: Printf. (line 4465)
+* forward slash (/): Regexp. (line 1949)
+* forward slash (/), / operator: Precedence. (line 6701)
+* forward slash (/), /= operator <1>: Precedence. (line 6742)
+* forward slash (/), /= operator: Assignment Ops. (line 6111)
+* forward slash (/), /= operator, vs. /=.../ regexp constant: Assignment Ops.
+ (line 6137)
+* forward slash (/), patterns and: Expression Patterns.
+ (line 6851)
+* Free Documentation License (FDL): GNU Free Documentation License.
+ (line 20789)
+* Free Software Foundation (FSF) <1>: Glossary. (line 20109)
+* Free Software Foundation (FSF) <2>: Getting. (line 17193)
+* Free Software Foundation (FSF): Manual History. (line 865)
+* free_temp internal macro: Internals. (line 18888)
+* FreeBSD: Glossary. (line 20404)
+* FS variable <1>: User-modified. (line 7850)
+* FS variable: Field Separators. (line 3271)
+* FS variable, --field-separator option and: Options. (line 12027)
+* FS variable, as null string: Single Character Fields.
+ (line 3415)
+* FS variable, as TAB character: Options. (line 12195)
+* FS variable, changing value of <1>: Known Bugs. (line 12454)
+* FS variable, changing value of: Field Separators. (line 3290)
+* FS variable, running awk programs and: Cut Program. (line 14331)
+* FS variable, setting from command line: Command Line Field Separator.
+ (line 3427)
+* FSF (Free Software Foundation) <1>: Glossary. (line 20109)
+* FSF (Free Software Foundation) <2>: Getting. (line 17193)
+* FSF (Free Software Foundation): Manual History. (line 865)
+* function calls: Function Calls. (line 6593)
+* functions, arrays as parameters to: Function Caveats. (line 10716)
+* functions, built-in <1>: Functions. (line 8964)
+* functions, built-in: Function Calls. (line 6597)
+* functions, built-in, adding to gawk: Dynamic Extensions.
+ (line 18765)
+* functions, built-in, evaluation order: Calling Built-in. (line 9031)
+* functions, defining: Definition Syntax. (line 10492)
+* functions, library: Library Functions. (line 12469)
+* functions, library, assertions: Assert Function. (line 12815)
+* functions, library, associative arrays and: Library Names.
+ (line 12592)
+* functions, library, C library: Getopt Function. (line 13460)
+* functions, library, character values as numbers: Ordinal Functions.
+ (line 12976)
+* functions, library, Cliff random numbers: Cliff Random Function.
+ (line 12945)
+* functions, library, command-line options: Getopt Function.
+ (line 13460)
+* functions, library, example program for using: Igawk Program.
+ (line 16250)
+* functions, library, group database, reading: Group Functions.
+ (line 13968)
+* functions, library, managing data files: Data File Management.
+ (line 13194)
+* functions, library, managing time: Gettimeofday Function.
+ (line 13112)
+* functions, library, merging arrays into strings: Join Function.
+ (line 13067)
+* functions, library, nextfile statement: Nextfile Function.
+ (line 12645)
+* functions, library, rounding numbers: Round Function. (line 12900)
+* functions, library, user database, reading: Passwd Functions.
+ (line 13743)
+* functions, names of <1>: Definition Syntax. (line 10506)
+* functions, names of: Arrays. (line 8287)
+* functions, recursive: Definition Syntax. (line 10554)
+* functions, return values, setting: Internals. (line 18932)
+* functions, string-translation: I18N Functions. (line 10436)
+* functions, undefined: Function Caveats. (line 10740)
+* functions, user-defined: User-defined. (line 10472)
+* functions, user-defined, calling: Function Caveats. (line 10667)
+* functions, user-defined, counts: Profiling. (line 11868)
+* functions, user-defined, library of: Library Functions. (line 12469)
+* functions, user-defined, next/nextfile statements and <1>: Nextfile Statement.
+ (line 7717)
+* functions, user-defined, next/nextfile statements and: Next Statement.
+ (line 7668)
+* G-d: Acknowledgments. (line 1012)
+* Garfinkle, Scott: Contributors. (line 17087)
+* gawk, awk and <1>: This Manual. (line 718)
+* gawk, awk and: Preface. (line 569)
+* gawk, bitwise operations in: Bitwise Functions. (line 10347)
+* gawk, break statement in: Break Statement. (line 7566)
+* gawk, built-in variables and: Built-in Variables.
+ (line 7795)
+* gawk, character classes and: Character Lists. (line 2451)
+* gawk, coding style in: Adding Code. (line 18573)
+* gawk, command-line options: GNU Regexp Operators.
+ (line 2517)
+* gawk, comparison operators and: Typing and Comparison.
+ (line 6390)
+* gawk, configuring: Configuration Philosophy.
+ (line 17507)
+* gawk, configuring, options: Additional Configuration Options.
+ (line 17466)
+* gawk, continue statement in: Continue Statement.
+ (line 7619)
+* gawk, debugging: Known Bugs. (line 12454)
+* gawk, distribution: Distribution contents.
+ (line 17253)
+* gawk, escape sequences: Escape Sequences. (line 2157)
+* gawk, extensions, disabling: Options. (line 12175)
+* gawk, features, adding: Adding Code. (line 18547)
+* gawk, features, advanced: Advanced Features. (line 11449)
+* gawk, fflush function in: I/O Functions. (line 9854)
+* gawk, field separators and: User-modified. (line 7870)
+* gawk, FIELDWIDTHS variable in: User-modified. (line 7846)
+* gawk, file names in: Special Files. (line 5002)
+* gawk, format-control characters: Control Letters. (line 4601)
+* gawk, function arguments and: Calling Built-in. (line 9017)
+* gawk, functions, adding: Dynamic Extensions.
+ (line 18765)
+* gawk, hexadecimal numbers and: Nondecimal-numbers.
+ (line 5493)
+* gawk, IGNORECASE variable in: User-modified. (line 7886)
+* gawk, implementation issues: Notes. (line 18484)
+* gawk, implementation issues, debugging: Compatibility Mode.
+ (line 18503)
+* gawk, implementation issues, downward compatibility: Compatibility Mode.
+ (line 18503)
+* gawk, implementation issues, limits: Getline Notes. (line 4193)
+* gawk, implementation issues, pipes: Redirection. (line 4973)
+* gawk, installing: Installation. (line 17151)
+* gawk, internals: Internals. (line 18792)
+* gawk, internationalization and, See internationalization: Internationalization.
+ (line 10883)
+* gawk, interpreter, adding code to <1>: Future Extensions. (line 19505)
+* gawk, interpreter, adding code to: Using Internal File Ops.
+ (line 19364)
+* gawk, interval expressions and: Regexp Operators. (line 2313)
+* gawk, line continuation in: Conditional Exp. (line 6581)
+* gawk, LINT variable in: User-modified. (line 7899)
+* gawk, list of contributors to: Contributors. (line 17056)
+* gawk, MS-DOS version of: PC Using. (line 17858)
+* gawk, newlines in: Statements/Lines. (line 1776)
+* gawk, next file statement in: Nextfile Statement.
+ (line 7724)
+* gawk, nextfile statement in <1>: Nextfile Function. (line 12645)
+* gawk, nextfile statement in: Nextfile Statement.
+ (line 7724)
+* gawk, octal numbers and: Nondecimal-numbers.
+ (line 5493)
+* gawk, OS/2 version of: PC Using. (line 17858)
+* gawk, regexp constants and: Using Constant Regexps.
+ (line 5566)
+* gawk, regular expressions, case sensitivity: Case-sensitivity.
+ (line 2569)
+* gawk, regular expressions, operators: GNU Regexp Operators.
+ (line 2461)
+* gawk, regular expressions, precedence: Regexp Operators. (line 2329)
+* gawk, See Also awk: Preface. (line 582)
+* gawk, source code, obtaining: Getting. (line 17189)
+* gawk, splitting fields and: Constant Size. (line 3682)
+* gawk, string-translation functions: I18N Functions. (line 10436)
+* gawk, timestamps: Time Functions. (line 9987)
+* gawk, uses for: Preface. (line 582)
+* gawk, versions of, information about, printing: Options. (line 12235)
+* gawk, word-boundary operator: GNU Regexp Operators.
+ (line 2510)
+* General Public License (GPL): Glossary. (line 20118)
+* General Public License, See GPL: Manual History. (line 870)
+* gensub function (gawk) <1>: String Functions. (line 9519)
+* gensub function (gawk): Using Constant Regexps.
+ (line 5582)
+* gensub function (gawk), escape processing: Gory Details. (line 9642)
+* get_actual_argument internal function: Internals. (line 18912)
+* get_argument internal function: Internals. (line 18907)
+* get_array_argument internal macro: Internals. (line 18927)
+* get_curfunc_arg_count internal function: Internals. (line 18823)
+* get_record input method: Internals. (line 18964)
+* get_scalar_argument internal macro: Internals. (line 18922)
+* getgrent function (C library): Group Functions. (line 13968)
+* getgrent user-defined function: Group Functions. (line 13968)
+* getgrgid function (C library): Group Functions. (line 14142)
+* getgrgid user-defined function: Group Functions. (line 14145)
+* getgrnam function (C library): Group Functions. (line 14130)
+* getgrnam user-defined function: Group Functions. (line 14134)
+* getgruser function (C library): Group Functions. (line 14153)
+* getgruser function, user-defined: Group Functions. (line 14156)
+* getline command: Reading Files. (line 2794)
+* getline command, _gr_init user-defined function: Group Functions.
+ (line 14042)
+* getline command, _pw_init function: Passwd Functions. (line 13873)
+* getline command, coprocesses, using from <1>: Close Files And Pipes.
+ (line 5199)
+* getline command, coprocesses, using from: Getline/Coprocess.
+ (line 4137)
+* getline command, deadlock and: Two-way I/O. (line 11587)
+* getline command, explicit input with: Getline. (line 3843)
+* getline command, FILENAME variable and: Getline Notes. (line 4198)
+* getline command, return values: Getline. (line 3856)
+* getline command, variants: Getline Summary. (line 4219)
+* getopt function (C library): Getopt Function. (line 13469)
+* getopt user-defined function: Getopt Function. (line 13559)
+* getpwent function (C library): Passwd Functions. (line 13753)
+* getpwent user-defined function: Passwd Functions. (line 13753)
+* getpwnam function (C library): Passwd Functions. (line 13893)
+* getpwnam user-defined function: Passwd Functions. (line 13897)
+* getpwuid function (C library): Passwd Functions. (line 13905)
+* getpwuid user-defined function: Passwd Functions. (line 13909)
+* getservbyname function (C library): TCP/IP Networking. (line 11686)
+* gettext function (C library): Explaining gettext.
+ (line 10975)
+* gettext library: Explaining gettext.
+ (line 10921)
+* gettext library, locale categories: Explaining gettext.
+ (line 10993)
+* gettimeofday user-defined function: Gettimeofday Function.
+ (line 13122)
+* GNITS mailing list: Acknowledgments. (line 991)
+* GNU awk, See gawk: Preface. (line 595)
+* GNU Free Documentation License: GNU Free Documentation License.
+ (line 20789)
+* GNU General Public License: Glossary. (line 20118)
+* GNU Lesser General Public License: Glossary. (line 20195)
+* GNU long options <1>: Options. (line 12012)
+* GNU long options: Command Line. (line 11995)
+* GNU long options, printing list of: Options. (line 12145)
+* GNU Project <1>: Glossary. (line 20127)
+* GNU Project: Manual History. (line 870)
+* GNU/Linux <1>: Glossary. (line 20404)
+* GNU/Linux <2>: Atari Compiling. (line 18198)
+* GNU/Linux <3>: I18N Example. (line 11393)
+* GNU/Linux: Manual History. (line 886)
+* GPL (General Public License) <1>: Glossary. (line 20118)
+* GPL (General Public License): Manual History. (line 870)
+* GPL (General Public License), printing: Options. (line 12093)
+* grcat program: Group Functions. (line 13977)
+* Grigera, Juan <1>: Bugs. (line 18366)
+* Grigera, Juan: Contributors. (line 17104)
+* group database, reading: Group Functions. (line 13968)
+* group file: Group Functions. (line 13968)
+* groups, information about: Group Functions. (line 13968)
+* gsub function <1>: String Functions. (line 9503)
+* gsub function: Using Constant Regexps.
+ (line 5582)
+* gsub function, arguments of: String Functions. (line 9483)
+* gsub function, escape processing: Gory Details. (line 9642)
+* Hankerson, Darrel <1>: Bugs. (line 18365)
+* Hankerson, Darrel <2>: Contributors. (line 17106)
+* Hankerson, Darrel: Acknowledgments. (line 995)
+* Hartholz, Elaine: Acknowledgments. (line 977)
+* Hartholz, Marshall: Acknowledgments. (line 977)
+* Hasegawa, Isamu <1>: Contributors. (line 17132)
+* Hasegawa, Isamu: Acknowledgments. (line 995)
+* hexadecimal numbers: Nondecimal-numbers.
+ (line 5457)
+* hexadecimal values, enabling interpretation of: Options. (line 12167)
+* histsort.awk program: History Sorting. (line 15953)
+* Hughes, Phil: Acknowledgments. (line 982)
+* HUP signal: Profiling. (line 11943)
+* hyphen (-), - operator: Precedence. (line 6698)
+* hyphen (-), -- (decrement/increment) operators: Precedence.
+ (line 6692)
+* hyphen (-), -- operator: Increment Ops. (line 6202)
+* hyphen (-), -= operator <1>: Precedence. (line 6742)
+* hyphen (-), -= operator: Assignment Ops. (line 6111)
+* hyphen (-), filenames beginning with: Options. (line 12073)
+* hyphen (-), in character lists: Character Lists. (line 2364)
+* id utility: Id Program. (line 14755)
+* id.awk program: Id Program. (line 14779)
+* if statement <1>: If Statement. (line 7260)
+* if statement: Regexp Usage. (line 1989)
+* if statement, actions, changing: Ranges. (line 6932)
+* igawk.sh program: Igawk Program. (line 16362)
+* IGNORECASE variable <1>: User-modified. (line 7875)
+* IGNORECASE variable: Case-sensitivity. (line 2569)
+* IGNORECASE variable, array sorting and: Array Sorting. (line 8953)
+* IGNORECASE variable, array subscripts and: Array Intro. (line 8398)
+* IGNORECASE variable, in example programs: Library Functions.
+ (line 12506)
+* implementation issues, gawk: Notes. (line 18484)
+* implementation issues, gawk, debugging: Compatibility Mode.
+ (line 18503)
+* implementation issues, gawk, limits <1>: Redirection. (line 4973)
+* implementation issues, gawk, limits: Getline Notes. (line 4193)
+* in operator <1>: Id Program. (line 14842)
+* in operator <2>: For Statement. (line 7449)
+* in operator <3>: Precedence. (line 6730)
+* in operator: Typing and Comparison.
+ (line 6342)
+* in operator, arrays and <1>: Scanning an Array. (line 8541)
+* in operator, arrays and: Reference to Elements.
+ (line 8432)
+* increment operators: Increment Ops. (line 6160)
+* index function: String Functions. (line 9218)
+* indexing arrays: Array Intro. (line 8356)
+* initialization, automatic: More Complex. (line 1731)
+* input files: Reading Files. (line 2780)
+* input files, closing: Close Files And Pipes.
+ (line 5199)
+* input files, counting elements in: Wc Program. (line 15264)
+* input files, examples: Sample Data Files. (line 1461)
+* input files, reading: Reading Files. (line 2780)
+* input files, running awk without: Read Terminal. (line 1146)
+* input files, skipping: Nextfile Function. (line 12645)
+* input files, variable assignments and: Other Arguments. (line 12318)
+* input pipeline: Getline/Pipe. (line 4051)
+* input redirection: Getline/File. (line 3979)
+* input, data, nondecimal: Nondecimal Data. (line 11480)
+* input, explicit: Getline. (line 3843)
+* input, files, See input files: Multiple Line. (line 3705)
+* input, multiline records: Multiple Line. (line 3705)
+* input, splitting into records: Records. (line 2817)
+* input, standard <1>: Special FD. (line 5019)
+* input, standard: Read Terminal. (line 1146)
+* input/output, binary: User-modified. (line 7817)
+* input/output, from BEGIN and END: I/O And BEGIN/END. (line 7058)
+* input/output, two-way: Two-way I/O. (line 11560)
+* insomnia, cure for: Alarm Program. (line 15477)
+* installation, amiga: Amiga Installation.
+ (line 17569)
+* installation, atari: Atari Installation.
+ (line 18161)
+* installation, beos: BeOS Installation. (line 17602)
+* installation, tandem: Tandem Installation.
+ (line 18278)
+* installation, vms: VMS Installation. (line 17981)
+* installing gawk: Installation. (line 17151)
+* int function: Numeric Functions. (line 9056)
+* INT signal (MS-DOS): Profiling. (line 11946)
+* integers: Basic Data Typing. (line 19654)
+* integers, unsigned: Basic Data Typing. (line 19661)
+* interacting with other programs: I/O Functions. (line 9872)
+* internationalization <1>: I18N and L10N. (line 10906)
+* internationalization: I18N Functions. (line 10436)
+* internationalization, localization <1>: Internationalization.
+ (line 10883)
+* internationalization, localization: User-modified. (line 7945)
+* internationalization, localization, character classes: Character Lists.
+ (line 2451)
+* internationalization, localization, gawk and: Internationalization.
+ (line 10883)
+* internationalization, localization, locale categories: Explaining gettext.
+ (line 10993)
+* internationalization, localization, marked strings: Programmer i18n.
+ (line 11059)
+* internationalization, localization, portability and: I18N Portability.
+ (line 11280)
+* internationalizing a program: Explaining gettext.
+ (line 10921)
+* interpreted programs <1>: Glossary. (line 20167)
+* interpreted programs: Basic High Level. (line 19551)
+* interval expressions: Regexp Operators. (line 2290)
+* inventory-shipped file: Sample Data Files. (line 1487)
+* IOBUF internal structure: Internals. (line 18964)
+* iop_alloc internal function: Internals. (line 18964)
+* ISO: Glossary. (line 20178)
+* ISO 8859-1: Glossary. (line 19963)
+* ISO Latin-1: Glossary. (line 19963)
+* Jacobs, Andrew: Passwd Functions. (line 13813)
+* Jaegermann, Michal <1>: Contributors. (line 17095)
+* Jaegermann, Michal: Acknowledgments. (line 995)
+* Jedi knights: Undocumented. (line 12443)
+* join user-defined function: Join Function. (line 13079)
+* Kahrs, Ju"rgen <1>: Contributors. (line 17114)
+* Kahrs, Ju"rgen: Acknowledgments. (line 995)
+* Kenobi, Obi-Wan: Undocumented. (line 12443)
+* Kernighan, Brian <1>: Basic Data Typing. (line 19704)
+* Kernighan, Brian <2>: Other Versions. (line 18390)
+* Kernighan, Brian <3>: Contributors. (line 17062)
+* Kernighan, Brian <4>: BTL. (line 16809)
+* Kernighan, Brian <5>: Concatenation. (line 5908)
+* Kernighan, Brian <6>: Acknowledgments. (line 1002)
+* Kernighan, Brian <7>: Conventions. (line 846)
+* Kernighan, Brian: History. (line 640)
+* kill command, dynamic profiling: Profiling. (line 11921)
+* Knights, jedi: Undocumented. (line 12443)
+* Kwok, Conrad: Contributors. (line 17087)
+* labels.awk program: Labels Program. (line 15765)
+* languages, data-driven: Basic High Level. (line 19620)
+* LC_ALL locale category: Explaining gettext.
+ (line 11031)
+* LC_COLLATE locale category: Explaining gettext.
+ (line 11004)
+* LC_CTYPE locale category: Explaining gettext.
+ (line 11008)
+* LC_MESSAGES locale category: Explaining gettext.
+ (line 10998)
+* LC_MESSAGES locale category, bindtextdomain function (gawk): Programmer i18n.
+ (line 11131)
+* LC_MONETARY locale category: Explaining gettext.
+ (line 11014)
+* LC_NUMERIC locale category: Explaining gettext.
+ (line 11018)
+* LC_RESPONSE locale category: Explaining gettext.
+ (line 11022)
+* LC_TIME locale category: Explaining gettext.
+ (line 11026)
+* left angle bracket (<), < operator <1>: Precedence. (line 6711)
+* left angle bracket (<), < operator: Typing and Comparison.
+ (line 6342)
+* left angle bracket (<), < operator (I/O): Getline/File. (line 3979)
+* left angle bracket (<), <= operator <1>: Precedence. (line 6711)
+* left angle bracket (<), <= operator: Typing and Comparison.
+ (line 6342)
+* left shift, bitwise: Bitwise Functions. (line 10340)
+* leftmost longest match: Multiple Line. (line 3725)
+* length function: String Functions. (line 9229)
+* Lesser General Public License (LGPL): Glossary. (line 20195)
+* LGPL (Lesser General Public License): Glossary. (line 20195)
+* libraries of awk functions: Library Functions. (line 12469)
+* libraries of awk functions, assertions: Assert Function. (line 12815)
+* libraries of awk functions, associative arrays and: Library Names.
+ (line 12592)
+* libraries of awk functions, character values as numbers: Ordinal Functions.
+ (line 12976)
+* libraries of awk functions, command-line options: Getopt Function.
+ (line 13460)
+* libraries of awk functions, example program for using: Igawk Program.
+ (line 16250)
+* libraries of awk functions, group database, reading: Group Functions.
+ (line 13968)
+* libraries of awk functions, managing, data files: Data File Management.
+ (line 13194)
+* libraries of awk functions, managing, time: Gettimeofday Function.
+ (line 13112)
+* libraries of awk functions, merging arrays into strings: Join Function.
+ (line 13067)
+* libraries of awk functions, nextfile statement: Nextfile Function.
+ (line 12645)
+* libraries of awk functions, rounding numbers: Round Function.
+ (line 12900)
+* libraries of awk functions, user database, reading: Passwd Functions.
+ (line 13743)
+* line breaks: Statements/Lines. (line 1770)
+* line continuations: Boolean Ops. (line 6519)
+* line continuations, gawk: Conditional Exp. (line 6581)
+* line continuations, in print statement: Print Examples. (line 4383)
+* line continuations, with C shell: More Complex. (line 1723)
+* lines, blank, printing: Print. (line 4300)
+* lines, counting: Wc Program. (line 15264)
+* lines, duplicate, removing: History Sorting. (line 15934)
+* lines, matching ranges of: Ranges. (line 6913)
+* lines, skipping between markers: Ranges. (line 6950)
+* lint checking: User-modified. (line 7890)
+* lint checking, array elements: Delete. (line 8613)
+* lint checking, array subscripts: Uninitialized Subscripts.
+ (line 8743)
+* lint checking, empty programs: Command Line. (line 11998)
+* lint checking, issuing warnings: Options. (line 12150)
+* lint checking, POSIXLY_CORRECT environment variable: Options.
+ (line 12273)
+* lint checking, undefined functions: Function Caveats. (line 10757)
+* LINT variable: User-modified. (line 7890)
+* Linux <1>: Glossary. (line 20404)
+* Linux <2>: Atari Compiling. (line 18198)
+* Linux <3>: I18N Example. (line 11393)
+* Linux: Manual History. (line 886)
+* locale categories: Explaining gettext.
+ (line 10993)
+* localization: I18N and L10N. (line 10906)
+* localization, See internationalization, localization: I18N and L10N.
+ (line 10906)
+* log files, timestamps in: Time Functions. (line 9987)
+* log function: Numeric Functions. (line 9072)
+* logical false/true: Truth Values. (line 6246)
+* logical operators, See Boolean expressions: Boolean Ops. (line 6463)
+* login information: Passwd Functions. (line 13753)
+* long options: Command Line. (line 11995)
+* loops: While Statement. (line 7299)
+* loops, continue statements and: For Statement. (line 7438)
+* loops, count for header: Profiling. (line 11862)
+* loops, exiting: Break Statement. (line 7525)
+* loops, See Also while statement: While Statement. (line 7299)
+* Lost In Space: Dynamic Extensions.
+ (line 18761)
+* ls utility: More Complex. (line 1708)
+* lshift function (gawk): Bitwise Functions. (line 10353)
+* lvalues/rvalues: Assignment Ops. (line 6014)
+* mailing labels, printing: Labels Program. (line 15723)
+* mailing list, GNITS: Acknowledgments. (line 991)
+* make_builtin internal function: Internals. (line 18893)
+* make_number internal function: Internals. (line 18868)
+* make_string internal function: Internals. (line 18863)
+* mark parity: Ordinal Functions. (line 13014)
+* marked string extraction (internationalization): String Extraction.
+ (line 11177)
+* marked strings, extracting: String Extraction. (line 11177)
+* Marx, Groucho: Increment Ops. (line 6215)
+* match function: String Functions. (line 9256)
+* match function, RSTART/RLENGTH variables: String Functions.
+ (line 9273)
+* matching, expressions, See comparison expressions: Typing and Comparison.
+ (line 6277)
+* matching, leftmost longest: Multiple Line. (line 3725)
+* matching, null strings: Gory Details. (line 9796)
+* mawk program: Other Versions. (line 18410)
+* McPhee, Patrick: Contributors. (line 17138)
+* memory, releasing: Internals. (line 18888)
+* memory, setting limits: Options. (line 12051)
+* message object files: Explaining gettext.
+ (line 10954)
+* message object files, converting from portable object files: I18N Example.
+ (line 11400)
+* message object files, specifying directory of <1>: Programmer i18n.
+ (line 11090)
+* message object files, specifying directory of: Explaining gettext.
+ (line 10966)
+* metacharacters, escape sequences for: Escape Sequences. (line 2164)
+* mktime function (gawk): Time Functions. (line 10011)
+* modifiers, in format specifiers: Format Modifiers. (line 4614)
+* monetary information, localization: Explaining gettext.
+ (line 11014)
+* msgfmt utility: I18N Example. (line 11400)
+* names, arrays/variables <1>: Library Names. (line 12541)
+* names, arrays/variables: Arrays. (line 8287)
+* names, functions <1>: Library Names. (line 12541)
+* names, functions: Definition Syntax. (line 10506)
+* namespace issues <1>: Library Names. (line 12541)
+* namespace issues: Arrays. (line 8287)
+* namespace issues, functions: Definition Syntax. (line 10506)
+* nawk utility: Names. (line 688)
+* negative zero: Floating Point Issues.
+ (line 19798)
+* NetBSD: Glossary. (line 20404)
+* networks, programming: TCP/IP Networking. (line 11658)
+* networks, support for: Special Network. (line 5145)
+* newlines <1>: Options. (line 12182)
+* newlines <2>: Boolean Ops. (line 6524)
+* newlines: Statements/Lines. (line 1770)
+* newlines, as field separators: Field Separators. (line 3320)
+* newlines, as record separators: Records. (line 2831)
+* newlines, in dynamic regexps: Computed Regexps. (line 2708)
+* newlines, in regexp constants: Computed Regexps. (line 2718)
+* newlines, printing: Print Examples. (line 4320)
+* newlines, separating statements in actions <1>: Statements.
+ (line 7228)
+* newlines, separating statements in actions: Action Overview.
+ (line 7178)
+* next file statement: POSIX/GNU. (line 17001)
+* next file statement, deprecated: Obsolete. (line 12426)
+* next file statement, in gawk: Nextfile Statement.
+ (line 7724)
+* next statement <1>: Next Statement. (line 7635)
+* next statement: Boolean Ops. (line 6541)
+* next statement, BEGIN/END patterns and: I/O And BEGIN/END.
+ (line 7088)
+* next statement, user-defined functions and: Next Statement.
+ (line 7668)
+* nextfile statement: Nextfile Statement.
+ (line 7684)
+* nextfile statement, BEGIN/END patterns and: I/O And BEGIN/END.
+ (line 7088)
+* nextfile statement, implementing: Nextfile Function. (line 12645)
+* nextfile statement, in gawk: Nextfile Statement.
+ (line 7724)
+* nextfile statement, next file statement and: Obsolete. (line 12426)
+* nextfile statement, user-defined functions and: Nextfile Statement.
+ (line 7717)
+* nextfile user-defined function: Nextfile Function. (line 12677)
+* NF variable <1>: Auto-set. (line 8064)
+* NF variable: Fields. (line 3041)
+* NF variable, decrementing: Changing Fields. (line 3231)
+* noassign.awk program: Ignoring Assigns. (line 13427)
+* NODE internal type: Internals. (line 18809)
+* nodes, duplicating: Internals. (line 18883)
+* not Boolean-logic operator: Boolean Ops. (line 6463)
+* NR variable <1>: Auto-set. (line 8075)
+* NR variable: Records. (line 2817)
+* NR variable, changing: Auto-set. (line 8148)
+* null strings <1>: Basic Data Typing. (line 19680)
+* null strings <2>: Truth Values. (line 6246)
+* null strings <3>: Regexp Field Splitting.
+ (line 3379)
+* null strings: Records. (line 2912)
+* null strings, array elements and: Delete. (line 8606)
+* null strings, as array subscripts: Uninitialized Subscripts.
+ (line 8743)
+* null strings, converting numbers to strings: Conversion. (line 5734)
+* null strings, matching: Gory Details. (line 9796)
+* null strings, quoting and: Quoting. (line 1401)
+* number sign (#), #! (executable scripts): Executable Scripts.
+ (line 1233)
+* number sign (#), #! (executable scripts), portability issues with: Executable Scripts.
+ (line 1233)
+* number sign (#), commenting: Comments. (line 1296)
+* numbers: Internals. (line 18868)
+* numbers, as array subscripts: Numeric Array Subscripts.
+ (line 8656)
+* numbers, as values of characters: Ordinal Functions. (line 12976)
+* numbers, Cliff random: Cliff Random Function.
+ (line 12945)
+* numbers, converting: Conversion. (line 5719)
+* numbers, converting, to strings <1>: Bitwise Functions. (line 10407)
+* numbers, converting, to strings: User-modified. (line 7833)
+* numbers, floating-point: Basic Data Typing. (line 19654)
+* numbers, floating-point, AWKNUM internal type: Internals. (line 18805)
+* numbers, hexadecimal: Nondecimal-numbers.
+ (line 5457)
+* numbers, NODE internal type: Internals. (line 18809)
+* numbers, octal: Nondecimal-numbers.
+ (line 5457)
+* numbers, random: Numeric Functions. (line 9115)
+* numbers, rounding: Round Function. (line 12900)
+* numeric, constants: Scalar Constants. (line 5425)
+* numeric, output format: OFMT. (line 4434)
+* numeric, strings: Typing and Comparison.
+ (line 6281)
+* numeric, values: Internals. (line 18813)
+* oawk utility: Names. (line 688)
+* obsolete features: Obsolete. (line 12421)
+* octal numbers: Nondecimal-numbers.
+ (line 5457)
+* octal values, enabling interpretation of: Options. (line 12167)
+* OFMT variable <1>: User-modified. (line 7907)
+* OFMT variable <2>: Conversion. (line 5767)
+* OFMT variable: OFMT. (line 4443)
+* OFMT variable, POSIX awk and: OFMT. (line 4455)
+* OFS variable <1>: User-modified. (line 7916)
+* OFS variable <2>: Output Separators. (line 4393)
+* OFS variable: Changing Fields. (line 3188)
+* OpenBSD: Glossary. (line 20404)
+* operating systems, BSD-based <1>: Portal Files. (line 11725)
+* operating systems, BSD-based: Manual History. (line 886)
+* operating systems, PC, gawk on: PC Using. (line 17853)
+* operating systems, PC, gawk on, installing: PC Installation.
+ (line 17634)
+* operating systems, porting gawk to: New Ports. (line 18680)
+* operating systems, See Also GNU/Linux, PC operating systems, Unix: Installation.
+ (line 17151)
+* operations, bitwise: Bitwise Functions. (line 10314)
+* operators, arithmetic: Arithmetic Ops. (line 5823)
+* operators, assignment: Assignment Ops. (line 5989)
+* operators, assignment, evaluation order: Assignment Ops. (line 6093)
+* operators, Boolean, See Boolean expressions: Boolean Ops. (line 6463)
+* operators, decrement/increment: Increment Ops. (line 6160)
+* operators, GNU-specific: GNU Regexp Operators.
+ (line 2461)
+* operators, input/output <1>: Precedence. (line 6711)
+* operators, input/output <2>: Redirection. (line 4864)
+* operators, input/output <3>: Getline/Coprocess. (line 4137)
+* operators, input/output <4>: Getline/Pipe. (line 4051)
+* operators, input/output: Getline/File. (line 3979)
+* operators, logical, See Boolean expressions: Boolean Ops. (line 6463)
+* operators, precedence <1>: Precedence. (line 6657)
+* operators, precedence: Increment Ops. (line 6215)
+* operators, relational, See operators, comparison: Typing and Comparison.
+ (line 6277)
+* operators, short-circuit: Boolean Ops. (line 6514)
+* operators, string: Concatenation. (line 5911)
+* operators, string-matching: Regexp Usage. (line 1989)
+* operators, string-matching, for buffers: GNU Regexp Operators.
+ (line 2495)
+* operators, word-boundary (gawk): GNU Regexp Operators.
+ (line 2510)
+* options, command-line <1>: Options. (line 12012)
+* options, command-line <2>: Command Line Field Separator.
+ (line 3427)
+* options, command-line: Long. (line 1202)
+* options, command-line, end of: Options. (line 12068)
+* options, command-line, invoking awk: Command Line. (line 11988)
+* options, command-line, processing: Getopt Function. (line 13460)
+* options, deprecated: Obsolete. (line 12421)
+* options, long <1>: Options. (line 12012)
+* options, long: Command Line. (line 11995)
+* options, printing list of: Options. (line 12145)
+* OR bitwise operation: Bitwise Functions. (line 10314)
+* or Boolean-logic operator: Boolean Ops. (line 6463)
+* or function (gawk): Bitwise Functions. (line 10347)
+* ord user-defined function: Ordinal Functions. (line 12986)
+* order of evaluation, concatenation: Concatenation. (line 5943)
+* ORS variable <1>: User-modified. (line 7921)
+* ORS variable: Output Separators. (line 4407)
+* output field separator, See OFS variable: Changing Fields.
+ (line 3188)
+* output record separator, See ORS variable: Output Separators.
+ (line 4407)
+* output redirection: Redirection. (line 4851)
+* output, buffering: I/O Functions. (line 9838)
+* output, duplicating into files: Tee Program. (line 14964)
+* output, files, closing: Close Files And Pipes.
+ (line 5199)
+* output, format specifier, OFMT: OFMT. (line 4443)
+* output, formatted: Printf. (line 4465)
+* output, pipes: Redirection. (line 4899)
+* output, printing, See printing: Printing. (line 4249)
+* output, records: Output Separators. (line 4407)
+* output, standard: Special FD. (line 5019)
+* P1003.2 POSIX standard: Glossary. (line 20248)
+* param_cnt internal variable: Internals. (line 18832)
+* parameters, number of: Internals. (line 18832)
+* parentheses (): Regexp Operators. (line 2253)
+* parentheses (), pgawk program: Profiling. (line 11877)
+* password file: Passwd Functions. (line 13753)
+* patterns: Patterns and Actions.
+ (line 6755)
+* patterns, comparison expressions as: Expression Patterns.
+ (line 6841)
+* patterns, counts: Profiling. (line 11849)
+* patterns, default: Very Simple. (line 1559)
+* patterns, empty: Empty. (line 7101)
+* patterns, expressions as: Regexp Patterns. (line 6819)
+* patterns, ranges in: Ranges. (line 6913)
+* patterns, regexp constants as: Expression Patterns.
+ (line 6863)
+* patterns, types of: Pattern Overview. (line 6788)
+* pawk profiling Bell Labs awk: Other Versions. (line 18465)
+* PC operating systems, gawk on: PC Using. (line 17853)
+* PC operating systems, gawk on, installing: PC Installation.
+ (line 17634)
+* percent sign (%), % operator: Precedence. (line 6701)
+* percent sign (%), %= operator <1>: Precedence. (line 6742)
+* percent sign (%), %= operator: Assignment Ops. (line 6111)
+* period (.): Regexp Operators. (line 2218)
+* PERL: Future Extensions. (line 19424)
+* Peters, Arno: Contributors. (line 17123)
+* Peterson, Hal: Contributors. (line 17090)
+* pgawk program: Profiling. (line 11740)
+* pgawk program, awkprof.out file: Profiling. (line 11744)
+* pgawk program, dynamic profiling: Profiling. (line 11913)
+* pipes, closing: Close Files And Pipes.
+ (line 5199)
+* pipes, input: Getline/Pipe. (line 4051)
+* pipes, output: Redirection. (line 4899)
+* plus sign (+): Regexp Operators. (line 2276)
+* plus sign (+), + operator: Precedence. (line 6698)
+* plus sign (+), ++ operator <1>: Precedence. (line 6692)
+* plus sign (+), ++ operator: Increment Ops. (line 6194)
+* plus sign (+), += operator <1>: Precedence. (line 6742)
+* plus sign (+), += operator: Assignment Ops. (line 6064)
+* plus sign (+), decrement/increment operators: Increment Ops.
+ (line 6165)
+* portability: Escape Sequences. (line 2126)
+* portability, #! (executable scripts): Executable Scripts.
+ (line 1261)
+* portability, ** operator and: Arithmetic Ops. (line 5898)
+* portability, **= operator and: Assignment Ops. (line 6131)
+* portability, ARGV variable: Executable Scripts.
+ (line 1270)
+* portability, backslash continuation and: Statements/Lines.
+ (line 1793)
+* portability, backslash in escape sequences: Escape Sequences.
+ (line 2145)
+* portability, close function and: Close Files And Pipes.
+ (line 5274)
+* portability, data files as single record: Records. (line 2979)
+* portability, deleting array elements: Delete. (line 8630)
+* portability, example programs: Library Functions. (line 12494)
+* portability, fflush function and: I/O Functions. (line 9838)
+* portability, functions, defining: Definition Syntax. (line 10574)
+* portability, gawk: New Ports. (line 18680)
+* portability, gettext library and: Explaining gettext.
+ (line 10925)
+* portability, internationalization and: I18N Portability. (line 11280)
+* portability, length function: String Functions. (line 9238)
+* portability, new awk vs. old awk: Conversion. (line 5767)
+* portability, next statement in user-defined functions: Function Caveats.
+ (line 10760)
+* portability, NF variable, decrementing: Changing Fields. (line 3239)
+* portability, operators: Increment Ops. (line 6215)
+* portability, operators, not in POSIX awk: Precedence. (line 6746)
+* portability, POSIXLY_CORRECT environment variable: Options.
+ (line 12291)
+* portability, substr function: String Functions. (line 9601)
+* portable object files <1>: Translator i18n. (line 11156)
+* portable object files: Explaining gettext.
+ (line 10951)
+* portable object files, converting to message object files: I18N Example.
+ (line 11400)
+* portable object files, generating: Options. (line 12136)
+* portal files: Portal Files. (line 11725)
+* porting gawk: New Ports. (line 18680)
+* positional specifiers, printf statement <1>: Printf Ordering.
+ (line 11203)
+* positional specifiers, printf statement: Format Modifiers.
+ (line 4621)
+* positional specifiers, printf statement, mixing with regular formats: Printf Ordering.
+ (line 11254)
+* positive zero: Floating Point Issues.
+ (line 19798)
+* POSIX awk <1>: Assignment Ops. (line 6122)
+* POSIX awk: This Manual. (line 718)
+* POSIX awk, **= operator and: Assignment Ops. (line 6131)
+* POSIX awk, < operator and: Getline/File. (line 3999)
+* POSIX awk, arithmetic operators and: Arithmetic Ops. (line 5853)
+* POSIX awk, backslashes in string constants: Escape Sequences.
+ (line 2145)
+* POSIX awk, BEGIN/END patterns: I/O And BEGIN/END. (line 7068)
+* POSIX awk, break statement and: Break Statement. (line 7566)
+* POSIX awk, changes in awk versions: POSIX. (line 16765)
+* POSIX awk, character lists and: Character Lists. (line 2371)
+* POSIX awk, character lists and, character classes: Character Lists.
+ (line 2377)
+* POSIX awk, continue statement and: Continue Statement.
+ (line 7619)
+* POSIX awk, CONVFMT variable and: User-modified. (line 7833)
+* POSIX awk, date utility and: Time Functions. (line 10245)
+* POSIX awk, field separators and <1>: Field Splitting Summary.
+ (line 3549)
+* POSIX awk, field separators and: Fields. (line 3014)
+* POSIX awk, FS variable and: User-modified. (line 7859)
+* POSIX awk, function keyword in: Definition Syntax. (line 10559)
+* POSIX awk, functions and, gsub/sub: Gory Details. (line 9689)
+* POSIX awk, functions and, length: String Functions. (line 9238)
+* POSIX awk, GNU long options and: Options. (line 12021)
+* POSIX awk, interval expressions in: Regexp Operators. (line 2309)
+* POSIX awk, next/nextfile statements and: Next Statement. (line 7668)
+* POSIX awk, numeric strings and: Typing and Comparison.
+ (line 6281)
+* POSIX awk, OFMT variable and <1>: Conversion. (line 5767)
+* POSIX awk, OFMT variable and: OFMT. (line 4455)
+* POSIX awk, period (.), using: Regexp Operators. (line 2225)
+* POSIX awk, printf format strings and: Format Modifiers. (line 4767)
+* POSIX awk, regular expressions and: Regexp Operators. (line 2329)
+* POSIX awk, timestamps and: Time Functions. (line 9987)
+* POSIX awk, | I/O operator and: Getline/Pipe. (line 4097)
+* POSIX mode: Options. (line 12175)
+* POSIX, awk and: Preface. (line 569)
+* POSIX, gawk extensions not included in: POSIX/GNU. (line 16852)
+* POSIX, programs, implementing in awk: Clones. (line 14243)
+* POSIXLY_CORRECT environment variable: Options. (line 12273)
+* precedence <1>: Precedence. (line 6657)
+* precedence: Increment Ops. (line 6215)
+* precedence, regexp operators: Regexp Operators. (line 2324)
+* print statement: Printing. (line 4259)
+* print statement, BEGIN/END patterns and: I/O And BEGIN/END.
+ (line 7068)
+* print statement, commas, omitting: Print Examples. (line 4338)
+* print statement, I/O operators in: Precedence. (line 6718)
+* print statement, line continuations and: Print Examples. (line 4383)
+* print statement, OFMT variable and: User-modified. (line 7916)
+* print statement, See Also redirection, of output: Redirection.
+ (line 4859)
+* print statement, sprintf function and: Round Function. (line 12900)
+* printf statement <1>: Printf. (line 4465)
+* printf statement: Printing. (line 4259)
+* printf statement, columns, aligning: Print Examples. (line 4377)
+* printf statement, format-control characters: Control Letters.
+ (line 4527)
+* printf statement, I/O operators in: Precedence. (line 6718)
+* printf statement, modifiers: Format Modifiers. (line 4614)
+* printf statement, positional specifiers <1>: Printf Ordering.
+ (line 11203)
+* printf statement, positional specifiers: Format Modifiers.
+ (line 4621)
+* printf statement, positional specifiers, mixing with regular formats: Printf Ordering.
+ (line 11254)
+* printf statement, See Also redirection, of output: Redirection.
+ (line 4859)
+* printf statement, sprintf function and: Round Function. (line 12900)
+* printf statement, syntax of: Basic Printf. (line 4486)
+* printing: Printing. (line 4249)
+* printing, list of options: Options. (line 12145)
+* printing, mailing labels: Labels Program. (line 15723)
+* printing, unduplicated lines of text: Uniq Program. (line 15048)
+* printing, user information: Id Program. (line 14755)
+* private variables: Library Names. (line 12546)
+* process information, files for: Special Process. (line 5086)
+* processes, two-way communications with: Two-way I/O. (line 11539)
+* processing data: Basic High Level. (line 19543)
+* PROCINFO array <1>: Group Functions. (line 13968)
+* PROCINFO array <2>: Passwd Functions. (line 13743)
+* PROCINFO array <3>: Auto-set. (line 8080)
+* PROCINFO array: Special Caveats. (line 5170)
+* PROCINFO variable: Internals. (line 18951)
+* profiling awk programs: Profiling. (line 11740)
+* profiling awk programs, dynamically: Profiling. (line 11913)
+* profiling gawk, See pgawk program: Profiling. (line 11740)
+* program, definition of: Getting Started. (line 1047)
+* programmers, attractiveness of: Two-way I/O. (line 11522)
+* programming conventions, --non-decimal-data option: Nondecimal Data.
+ (line 11510)
+* programming conventions, ARGC/ARGV variables: Auto-set. (line 7992)
+* programming conventions, exit statement: Exit Statement. (line 7767)
+* programming conventions, function parameters: Return Statement.
+ (line 10803)
+* programming conventions, functions, calling: Calling Built-in.
+ (line 9011)
+* programming conventions, functions, writing: Definition Syntax.
+ (line 10536)
+* programming conventions, gawk internals: Internal File Ops.
+ (line 19220)
+* programming conventions, nextfile statement: Nextfile Function.
+ (line 12659)
+* programming conventions, private variable names: Library Names.
+ (line 12558)
+* programming language, recipe for: History. (line 630)
+* programming languages, data-driven vs. procedural: Getting Started.
+ (line 1038)
+* programming, basic steps: Basic High Level. (line 19556)
+* programming, concepts: Basic Concepts. (line 19524)
+* pwcat program: Passwd Functions. (line 13760)
+* question mark (?) <1>: GNU Regexp Operators.
+ (line 2506)
+* question mark (?): Regexp Operators. (line 2285)
+* question mark (?), ?: operator: Precedence. (line 6739)
+* QUIT signal (MS-DOS): Profiling. (line 11946)
+* quoting <1>: Comments. (line 1317)
+* quoting <2>: Long. (line 1216)
+* quoting: Read Terminal. (line 1165)
+* quoting, rules for: Quoting. (line 1349)
+* quoting, tricks for: Quoting. (line 1410)
+* Rakitzis, Byron: History Sorting. (line 15953)
+* rand function: Numeric Functions. (line 9085)
+* random numbers, Cliff: Cliff Random Function.
+ (line 12945)
+* random numbers, rand/srand functions: Numeric Functions. (line 9085)
+* random numbers, seed of: Numeric Functions. (line 9115)
+* range expressions: Character Lists. (line 2353)
+* range patterns: Ranges. (line 6913)
+* Rankin, Pat <1>: Bugs. (line 18371)
+* Rankin, Pat <2>: Contributors. (line 17085)
+* Rankin, Pat <3>: Assignment Ops. (line 6082)
+* Rankin, Pat: Acknowledgments. (line 995)
+* raw sockets: TCP/IP Networking. (line 11682)
+* readable data files, checking: File Checking. (line 13334)
+* readable.awk program: File Checking. (line 13339)
+* recipe for a programming language: History. (line 630)
+* record separators <1>: User-modified. (line 7926)
+* record separators: Records. (line 2825)
+* record separators, changing: Records. (line 2891)
+* record separators, regular expressions as: Records. (line 2921)
+* record separators, with multiline records: Multiple Line. (line 3709)
+* records <1>: Basic High Level. (line 19608)
+* records: Reading Files. (line 2788)
+* records, multiline: Multiple Line. (line 3705)
+* records, printing: Print. (line 4300)
+* records, splitting input into: Records. (line 2817)
+* records, terminating: Records. (line 2921)
+* records, treating files as: Records. (line 3000)
+* recursive functions: Definition Syntax. (line 10554)
+* redirection of input: Getline/File. (line 3979)
+* redirection of output: Redirection. (line 4851)
+* reference counting, sorting arrays: Array Sorting. (line 8946)
+* regexp constants <1>: Typing and Comparison.
+ (line 6442)
+* regexp constants <2>: Regexp Constants. (line 5532)
+* regexp constants: Regexp Usage. (line 2028)
+* regexp constants, /=.../, /= operator and: Assignment Ops.
+ (line 6137)
+* regexp constants, as patterns: Expression Patterns.
+ (line 6863)
+* regexp constants, in gawk: Using Constant Regexps.
+ (line 5566)
+* regexp constants, slashes vs. quotes: Computed Regexps. (line 2677)
+* regexp constants, vs. string constants: Computed Regexps. (line 2687)
+* regexp, See regular expressions: Regexp. (line 1945)
+* register_deferred_variable internal function: Internals. (line 18951)
+* register_open_hook internal function: Internals. (line 18964)
+* regular expressions: Regexp. (line 1945)
+* regular expressions as field separators: Field Separators.
+ (line 3306)
+* regular expressions, anchors in: Regexp Operators. (line 2197)
+* regular expressions, as field separators: Regexp Field Splitting.
+ (line 3343)
+* regular expressions, as patterns <1>: Regexp Patterns. (line 6819)
+* regular expressions, as patterns: Regexp Usage. (line 1976)
+* regular expressions, as record separators: Records. (line 2921)
+* regular expressions, case sensitivity <1>: User-modified. (line 7875)
+* regular expressions, case sensitivity: Case-sensitivity. (line 2549)
+* regular expressions, computed: Computed Regexps. (line 2656)
+* regular expressions, constants, See regexp constants: Regexp Usage.
+ (line 2028)
+* regular expressions, dynamic: Computed Regexps. (line 2656)
+* regular expressions, dynamic, with embedded newlines: Computed Regexps.
+ (line 2708)
+* regular expressions, gawk, command-line options: GNU Regexp Operators.
+ (line 2517)
+* regular expressions, interval expressions and: Options. (line 12220)
+* regular expressions, leftmost longest match: Leftmost Longest.
+ (line 2626)
+* regular expressions, operators <1>: Regexp Operators. (line 2181)
+* regular expressions, operators: Regexp Usage. (line 1989)
+* regular expressions, operators, for buffers: GNU Regexp Operators.
+ (line 2495)
+* regular expressions, operators, for words: GNU Regexp Operators.
+ (line 2461)
+* regular expressions, operators, gawk: GNU Regexp Operators.
+ (line 2461)
+* regular expressions, operators, precedence of: Regexp Operators.
+ (line 2324)
+* regular expressions, searching for: Egrep Program. (line 14525)
+* relational operators, See comparison operators: Typing and Comparison.
+ (line 6277)
+* return statement, user-defined functions: Return Statement.
+ (line 10770)
+* return values, close function: Close Files And Pipes.
+ (line 5323)
+* rev user-defined function: Function Example. (line 10629)
+* rewind user-defined function: Rewind Function. (line 13302)
+* right angle bracket (>), > operator <1>: Precedence. (line 6711)
+* right angle bracket (>), > operator: Typing and Comparison.
+ (line 6342)
+* right angle bracket (>), > operator (I/O): Redirection. (line 4864)
+* right angle bracket (>), >= operator <1>: Precedence. (line 6711)
+* right angle bracket (>), >= operator: Typing and Comparison.
+ (line 6342)
+* right angle bracket (>), >> operator (I/O) <1>: Precedence.
+ (line 6711)
+* right angle bracket (>), >> operator (I/O): Redirection. (line 4892)
+* right shift, bitwise: Bitwise Functions. (line 10340)
+* Ritchie, Dennis: Basic Data Typing. (line 19704)
+* RLENGTH variable: Auto-set. (line 8124)
+* RLENGTH variable, match function and: String Functions. (line 9273)
+* Robbins, Arnold <1>: Future Extensions. (line 19424)
+* Robbins, Arnold <2>: Bugs. (line 18337)
+* Robbins, Arnold <3>: Contributors. (line 17141)
+* Robbins, Arnold <4>: Alarm Program. (line 15477)
+* Robbins, Arnold <5>: Passwd Functions. (line 13813)
+* Robbins, Arnold <6>: Getline/Pipe. (line 4081)
+* Robbins, Arnold: Command Line Field Separator.
+ (line 3501)
+* Robbins, Bill: Getline/Pipe. (line 4081)
+* Robbins, Harry: Acknowledgments. (line 1012)
+* Robbins, Jean: Acknowledgments. (line 1012)
+* Robbins, Miriam <1>: Passwd Functions. (line 13813)
+* Robbins, Miriam <2>: Getline/Pipe. (line 4081)
+* Robbins, Miriam: Acknowledgments. (line 1012)
+* Robinson, Will: Dynamic Extensions.
+ (line 18761)
+* robot, the: Dynamic Extensions.
+ (line 18761)
+* Rommel, Kai Uwe <1>: Contributors. (line 17092)
+* Rommel, Kai Uwe: Acknowledgments. (line 995)
+* round user-defined function: Round Function. (line 12910)
+* rounding: Round Function. (line 12900)
+* rounding numbers: Round Function. (line 12900)
+* RS variable <1>: User-modified. (line 7926)
+* RS variable: Records. (line 2831)
+* RS variable, multiline records and: Multiple Line. (line 3716)
+* rshift function (gawk): Bitwise Functions. (line 10354)
+* RSTART variable: Auto-set. (line 8130)
+* RSTART variable, match function and: String Functions. (line 9273)
+* RT variable <1>: Auto-set. (line 8137)
+* RT variable <2>: Multiple Line. (line 3828)
+* RT variable: Records. (line 2921)
+* Rubin, Paul <1>: Contributors. (line 17066)
+* Rubin, Paul: History. (line 653)
+* rule, definition of: Getting Started. (line 1047)
+* rvalues/lvalues: Assignment Ops. (line 6014)
+* scalar values: Basic Data Typing. (line 19646)
+* Schreiber, Bert: Acknowledgments. (line 977)
+* Schreiber, Rita: Acknowledgments. (line 977)
+* search paths <1>: VMS Running. (line 18102)
+* search paths: PC Using. (line 17858)
+* search paths, for source files <1>: VMS Running. (line 18102)
+* search paths, for source files <2>: Igawk Program. (line 16601)
+* search paths, for source files: AWKPATH Variable. (line 12361)
+* searching: String Functions. (line 9218)
+* searching, files for regular expressions: Egrep Program. (line 14525)
+* searching, for words: Dupword Program. (line 15429)
+* sed utility <1>: Glossary. (line 19837)
+* sed utility <2>: Simple Sed. (line 16170)
+* sed utility: Field Splitting Summary.
+ (line 3555)
+* semicolon (;): Statements/Lines. (line 1853)
+* semicolon (;), AWKPATH variable and: PC Using. (line 17858)
+* semicolon (;), separating statements in actions <1>: Statements.
+ (line 7228)
+* semicolon (;), separating statements in actions: Action Overview.
+ (line 7178)
+* separators, field: User-modified. (line 7850)
+* separators, field, FIELDWIDTHS variable and: User-modified.
+ (line 7840)
+* separators, field, POSIX and: Fields. (line 3014)
+* separators, for records: Records. (line 2825)
+* separators, for records, regular expressions as: Records. (line 2921)
+* separators, for statements in actions: Action Overview. (line 7178)
+* separators, record: User-modified. (line 7926)
+* separators, subscript: User-modified. (line 7939)
+* set_value internal function: Internals. (line 18932)
+* shells, piping commands into: Redirection. (line 4981)
+* shells, quoting: Using Shell Variables.
+ (line 7120)
+* shells, quoting, rules for: Quoting. (line 1357)
+* shells, scripts: One-shot. (line 1133)
+* shells, variables: Using Shell Variables.
+ (line 7114)
+* shift, bitwise: Bitwise Functions. (line 10340)
+* short-circuit operators: Boolean Ops. (line 6514)
+* side effects <1>: Increment Ops. (line 6165)
+* side effects: Concatenation. (line 5943)
+* side effects, array indexing: Reference to Elements.
+ (line 8437)
+* side effects, asort function: Array Sorting. (line 8894)
+* side effects, assignment expressions: Assignment Ops. (line 6005)
+* side effects, Boolean operators: Boolean Ops. (line 6487)
+* side effects, conditional expressions: Conditional Exp. (line 6569)
+* side effects, decrement/increment operators: Increment Ops.
+ (line 6165)
+* side effects, FILENAME variable: Getline Notes. (line 4198)
+* side effects, function calls: Function Calls. (line 6635)
+* side effects, statements: Action Overview. (line 7191)
+* signals, HUP/SIGHUP: Profiling. (line 11943)
+* signals, INT/SIGINT (MS-DOS): Profiling. (line 11946)
+* signals, QUIT/SIGQUIT (MS-DOS): Profiling. (line 11946)
+* signals, USR1/SIGUSR1: Profiling. (line 11921)
+* sin function: Numeric Functions. (line 9076)
+* single quote (') <1>: Quoting. (line 1370)
+* single quote (') <2>: Long. (line 1223)
+* single quote ('): One-shot. (line 1126)
+* single quote ('), vs. apostrophe: Comments. (line 1317)
+* single quote ('), with double quotes: Quoting. (line 1392)
+* single-character fields: Single Character Fields.
+ (line 3401)
+* single-precision floating-point: Basic Data Typing. (line 19666)
+* Skywalker, Luke: Undocumented. (line 12443)
+* sleep utility: Alarm Program. (line 15572)
+* sockets: TCP/IP Networking. (line 11682)
+* sort function, arrays, sorting: Array Sorting. (line 8875)
+* sort utility: Word Sorting. (line 15876)
+* sort utility, coprocesses and: Two-way I/O. (line 11600)
+* sorting characters in different languages: Explaining gettext.
+ (line 11004)
+* source code, awka: Other Versions. (line 18453)
+* source code, Bell Laboratories awk: Other Versions. (line 18390)
+* source code, gawk: Gawk Distribution. (line 17174)
+* source code, mawk: Other Versions. (line 18410)
+* source code, mixing: Options. (line 12227)
+* source files, search path for: Igawk Program. (line 16601)
+* sparse arrays: Array Intro. (line 8377)
+* Spencer, Henry: Glossary. (line 19837)
+* split function: String Functions. (line 9344)
+* split function, array elements, deleting: Delete. (line 8635)
+* split utility: Split Program. (line 14862)
+* split.awk program: Split Program. (line 14886)
+* sprintf function <1>: String Functions. (line 9397)
+* sprintf function: OFMT. (line 4443)
+* sprintf function, OFMT variable and: User-modified. (line 7916)
+* sprintf function, print/printf statements and: Round Function.
+ (line 12900)
+* sqrt function: Numeric Functions. (line 9063)
+* square brackets ([]): Regexp Operators. (line 2230)
+* srand function: Numeric Functions. (line 9125)
+* Stallman, Richard <1>: Glossary. (line 20109)
+* Stallman, Richard <2>: Contributors. (line 17074)
+* Stallman, Richard <3>: Acknowledgments. (line 960)
+* Stallman, Richard: Manual History. (line 865)
+* standard input <1>: Special FD. (line 5019)
+* standard input: Read Terminal. (line 1146)
+* standard output: Special FD. (line 5019)
+* stat function, implementing in gawk: Sample Library. (line 19054)
+* statements, compound, control statements and: Statements. (line 7228)
+* statements, control, in actions: Statements. (line 7224)
+* statements, multiple: Statements/Lines. (line 1853)
+* stlen internal variable: Internals. (line 18836)
+* stptr internal variable: Internals. (line 18836)
+* stream editors <1>: Simple Sed. (line 16170)
+* stream editors: Field Splitting Summary.
+ (line 3555)
+* strftime function (gawk): Time Functions. (line 10034)
+* string constants: Scalar Constants. (line 5434)
+* string constants, vs. regexp constants: Computed Regexps. (line 2687)
+* string extraction (internationalization): String Extraction.
+ (line 11177)
+* string operators: Concatenation. (line 5911)
+* string-matching operators: Regexp Usage. (line 1989)
+* strings: Internals. (line 18863)
+* strings, converting: Conversion. (line 5719)
+* strings, converting, numbers to <1>: Bitwise Functions. (line 10407)
+* strings, converting, numbers to: User-modified. (line 7833)
+* strings, empty, See null strings: Records. (line 2912)
+* strings, extracting: String Extraction. (line 11177)
+* strings, for localization: Programmer i18n. (line 11059)
+* strings, length of: Scalar Constants. (line 5439)
+* strings, merging arrays into: Join Function. (line 13067)
+* strings, NODE internal type: Internals. (line 18809)
+* strings, null: Regexp Field Splitting.
+ (line 3379)
+* strings, numeric: Typing and Comparison.
+ (line 6281)
+* strings, splitting: String Functions. (line 9358)
+* strtonum function (gawk): String Functions. (line 9405)
+* strtonum function (gawk), --non-decimal-data option and: Nondecimal Data.
+ (line 11510)
+* sub function <1>: String Functions. (line 9426)
+* sub function: Using Constant Regexps.
+ (line 5582)
+* sub function, arguments of: String Functions. (line 9483)
+* sub function, escape processing: Gory Details. (line 9642)
+* subscript separators: User-modified. (line 7939)
+* subscripts in arrays, multidimensional: Multi-dimensional.
+ (line 8754)
+* subscripts in arrays, multidimensional, scanning: Multi-scanning.
+ (line 8840)
+* subscripts in arrays, numbers as: Numeric Array Subscripts.
+ (line 8656)
+* subscripts in arrays, uninitialized variables as: Uninitialized Subscripts.
+ (line 8707)
+* SUBSEP variable: User-modified. (line 7939)
+* SUBSEP variable, multidimensional arrays: Multi-dimensional.
+ (line 8760)
+* substr function: String Functions. (line 9570)
+* Sumner, Andrew: Other Versions. (line 18453)
+* switch statement: Switch Statement. (line 7464)
+* syntactic ambiguity: /= operator vs. /=.../ regexp constant: Assignment Ops.
+ (line 6137)
+* system function: I/O Functions. (line 9872)
+* systime function (gawk): Time Functions. (line 10005)
+* tandem: Tandem Installation.
+ (line 18278)
+* Tcl: Library Names. (line 12592)
+* TCP/IP: TCP/IP Networking. (line 11658)
+* TCP/IP, support for: Special Network. (line 5145)
+* tee utility: Tee Program. (line 14964)
+* tee.awk program: Tee Program. (line 14984)
+* terminating records: Records. (line 2921)
+* testbits.awk program: Bitwise Functions. (line 10368)
+* Texinfo <1>: Adding Code. (line 18640)
+* Texinfo <2>: Distribution contents.
+ (line 17315)
+* Texinfo <3>: Extract Program. (line 15985)
+* Texinfo <4>: Dupword Program. (line 15440)
+* Texinfo <5>: Library Functions. (line 12485)
+* Texinfo <6>: Sample Data Files. (line 1521)
+* Texinfo: Conventions. (line 819)
+* Texinfo, chapter beginnings in files: Regexp Operators. (line 2197)
+* Texinfo, extracting programs from source files: Extract Program.
+ (line 15979)
+* text, printing: Print. (line 4300)
+* text, printing, unduplicated lines of: Uniq Program. (line 15048)
+* textdomain function (C library): Explaining gettext.
+ (line 10942)
+* TEXTDOMAIN variable <1>: Programmer i18n. (line 11054)
+* TEXTDOMAIN variable: User-modified. (line 7945)
+* TEXTDOMAIN variable, BEGIN pattern and: Programmer i18n. (line 11103)
+* TEXTDOMAIN variable, portability and: I18N Portability. (line 11294)
+* tilde (~), ~ operator <1>: Expression Patterns.
+ (line 6851)
+* tilde (~), ~ operator <2>: Precedence. (line 6727)
+* tilde (~), ~ operator <3>: Typing and Comparison.
+ (line 6342)
+* tilde (~), ~ operator <4>: Regexp Constants. (line 5532)
+* tilde (~), ~ operator <5>: Computed Regexps. (line 2656)
+* tilde (~), ~ operator <6>: Case-sensitivity. (line 2569)
+* tilde (~), ~ operator: Regexp Usage. (line 1989)
+* time, alarm clock example program: Alarm Program. (line 15480)
+* time, localization and: Explaining gettext.
+ (line 11026)
+* time, managing: Gettimeofday Function.
+ (line 13112)
+* time, retrieving: Time Functions. (line 9998)
+* timestamps: Time Functions. (line 9987)
+* timestamps, converting dates to: Time Functions. (line 10050)
+* timestamps, formatted: Gettimeofday Function.
+ (line 13112)
+* tmp_number internal function: Internals. (line 18878)
+* tmp_string internal function: Internals. (line 18873)
+* tolower function: String Functions. (line 9612)
+* toupper function: String Functions. (line 9618)
+* tr utility: Translate Program. (line 15601)
+* translate.awk program: Translate Program. (line 15649)
+* troubleshooting, --non-decimal-data option: Options. (line 12170)
+* troubleshooting, -F option: Known Bugs. (line 12454)
+* troubleshooting, == operator: Typing and Comparison.
+ (line 6377)
+* troubleshooting, awk uses FS not IFS: Field Separators. (line 3285)
+* troubleshooting, backslash before nonspecial character: Escape Sequences.
+ (line 2145)
+* troubleshooting, division: Arithmetic Ops. (line 5861)
+* troubleshooting, fatal errors, field widths, specifying: Constant Size.
+ (line 3618)
+* troubleshooting, fatal errors, printf format strings: Format Modifiers.
+ (line 4767)
+* troubleshooting, fflush function: I/O Functions. (line 9860)
+* troubleshooting, function call syntax: Function Calls. (line 6615)
+* troubleshooting, gawk <1>: Compatibility Mode.
+ (line 18503)
+* troubleshooting, gawk: Known Bugs. (line 12454)
+* troubleshooting, gawk, bug reports: Bugs. (line 18317)
+* troubleshooting, gawk, fatal errors, function arguments: Calling Built-in.
+ (line 9017)
+* troubleshooting, getline function: File Checking. (line 13352)
+* troubleshooting, gsub/sub functions: String Functions. (line 9493)
+* troubleshooting, match function: String Functions. (line 9339)
+* troubleshooting, print statement, omitting commas: Print Examples.
+ (line 4338)
+* troubleshooting, printing: Redirection. (line 4959)
+* troubleshooting, quotes with file names: Special FD. (line 5076)
+* troubleshooting, readable data files: File Checking. (line 13334)
+* troubleshooting, regexp constants vs. string constants: Computed Regexps.
+ (line 2687)
+* troubleshooting, string concatenation: Concatenation. (line 5929)
+* troubleshooting, substr function: String Functions. (line 9588)
+* troubleshooting, system function: I/O Functions. (line 9896)
+* troubleshooting, typographical errors, global variables: Options.
+ (line 12107)
+* true, logical: Truth Values. (line 6246)
+* Trueman, David <1>: Contributors. (line 17081)
+* Trueman, David <2>: Acknowledgments. (line 986)
+* Trueman, David: History. (line 653)
+* trunc-mod operation: Arithmetic Ops. (line 5883)
+* truth values: Truth Values. (line 6246)
+* type conversion: Conversion. (line 5734)
+* type internal variable: Internals. (line 18844)
+* undefined functions: Function Caveats. (line 10740)
+* underscore (_), _ C macro: Explaining gettext.
+ (line 10983)
+* underscore (_), in names of private variables: Library Names.
+ (line 12564)
+* underscore (_), translatable string: Programmer i18n. (line 11112)
+* undocumented features: Undocumented. (line 12443)
+* uninitialized variables, as array subscripts: Uninitialized Subscripts.
+ (line 8707)
+* uniq utility: Uniq Program. (line 15048)
+* uniq.awk program: Uniq Program. (line 15107)
+* Unix: Glossary. (line 20404)
+* Unix awk, backslashes in escape sequences: Escape Sequences.
+ (line 2157)
+* Unix awk, close function and: Close Files And Pipes.
+ (line 5323)
+* Unix awk, password files, field separators and: Command Line Field Separator.
+ (line 3493)
+* Unix, awk scripts and: Executable Scripts.
+ (line 1233)
+* unsigned integers: Basic Data Typing. (line 19661)
+* update_ERRNO internal function: Internals. (line 18938)
+* update_ERRNO_saved internal function: Internals. (line 18943)
+* user database, reading: Passwd Functions. (line 13743)
+* user-defined, functions: User-defined. (line 10472)
+* user-defined, functions, counts: Profiling. (line 11868)
+* user-defined, variables: Variables. (line 5621)
+* user-modifiable variables: User-modified. (line 7813)
+* users, information about, printing: Id Program. (line 14755)
+* users, information about, retrieving: Passwd Functions. (line 13753)
+* USR1 signal: Profiling. (line 11921)
+* values, numeric: Basic Data Typing. (line 19646)
+* values, string: Basic Data Typing. (line 19646)
+* variable typing: Typing and Comparison.
+ (line 6277)
+* variables <1>: Basic Data Typing. (line 19639)
+* variables: Other Features. (line 1879)
+* variables, assigning on command line: Assignment Options.
+ (line 5671)
+* variables, built-in <1>: Built-in Variables.
+ (line 7787)
+* variables, built-in: Using Variables. (line 5650)
+* variables, built-in, -v option, setting with: Options. (line 12044)
+* variables, built-in, conveying information: Auto-set. (line 7967)
+* variables, flag: Boolean Ops. (line 6524)
+* variables, getline command into, using <1>: Getline/Variable/Coprocess.
+ (line 4167)
+* variables, getline command into, using <2>: Getline/Variable/Pipe.
+ (line 4110)
+* variables, getline command into, using <3>: Getline/Variable/File.
+ (line 4012)
+* variables, getline command into, using: Getline/Variable. (line 3938)
+* variables, global, for library functions: Library Names. (line 12546)
+* variables, global, printing list of: Options. (line 12101)
+* variables, initializing: Using Variables. (line 5650)
+* variables, names of: Arrays. (line 8287)
+* variables, private: Library Names. (line 12546)
+* variables, setting: Options. (line 12036)
+* variables, shadowing: Definition Syntax. (line 10542)
+* variables, types of: Assignment Ops. (line 6022)
+* variables, types of, comparison expressions and: Typing and Comparison.
+ (line 6277)
+* variables, uninitialized, as array subscripts: Uninitialized Subscripts.
+ (line 8707)
+* variables, user-defined: Variables. (line 5621)
+* vertical bar (|): Regexp Operators. (line 2243)
+* vertical bar (|), | operator (I/O) <1>: Precedence. (line 6711)
+* vertical bar (|), | operator (I/O): Getline/Pipe. (line 4051)
+* vertical bar (|), |& I/O operator (I/O): Two-way I/O. (line 11560)
+* vertical bar (|), |& operator (I/O) <1>: Precedence. (line 6711)
+* vertical bar (|), |& operator (I/O): Getline/Coprocess. (line 4137)
+* vertical bar (|), |& operator (I/O), two-way communications: Portal Files.
+ (line 11729)
+* vertical bar (|), || operator <1>: Precedence. (line 6736)
+* vertical bar (|), || operator: Boolean Ops. (line 6514)
+* vname internal variable: Internals. (line 18848)
+* w utility: Constant Size. (line 3618)
+* Wall, Larry: Future Extensions. (line 19424)
+* warnings, issuing: Options. (line 12150)
+* wc utility: Wc Program. (line 15264)
+* wc.awk program: Wc Program. (line 15303)
+* Weinberger, Peter <1>: Contributors. (line 17062)
+* Weinberger, Peter: History. (line 640)
+* while statement <1>: While Statement. (line 7299)
+* while statement: Regexp Usage. (line 1989)
+* whitespace, as field separators: Field Separators. (line 3320)
+* whitespace, functions, calling: Calling Built-in. (line 9011)
+* whitespace, newlines as: Options. (line 12182)
+* Williams, Kent: Contributors. (line 17087)
+* Woods, John: Contributors. (line 17078)
+* word boundaries, matching: GNU Regexp Operators.
+ (line 2485)
+* word, regexp definition of: GNU Regexp Operators.
+ (line 2461)
+* word-boundary operator (gawk): GNU Regexp Operators.
+ (line 2510)
+* wordfreq.awk program: Word Sorting. (line 15882)
+* words, counting: Wc Program. (line 15264)
+* words, duplicate, searching for: Dupword Program. (line 15429)
+* words, usage counts, generating: Word Sorting. (line 15828)
+* xgettext utility: String Extraction. (line 11184)
+* XML: Internals. (line 18964)
+* XOR bitwise operation: Bitwise Functions. (line 10314)
+* xor function (gawk): Bitwise Functions. (line 10349)
+* Zaretskii, Eli: Acknowledgments. (line 995)
+* zero, negative vs. positive: Floating Point Issues.
+ (line 19798)
+* zerofile.awk program: Empty Files. (line 13377)
+* Zoulas, Christos: Contributors. (line 17111)
+* {} (braces), actions and: Action Overview. (line 7178)
+* {} (braces), pgawk program: Profiling. (line 11873)
+* {} (braces), statements, grouping: Statements. (line 7228)
+* | (vertical bar): Regexp Operators. (line 2243)
+* | (vertical bar), | operator (I/O) <1>: Precedence. (line 6711)
+* | (vertical bar), | operator (I/O) <2>: Redirection. (line 4899)
+* | (vertical bar), | operator (I/O): Getline/Pipe. (line 4051)
+* | (vertical bar), |& operator (I/O) <1>: Two-way I/O. (line 11560)
+* | (vertical bar), |& operator (I/O) <2>: Precedence. (line 6711)
+* | (vertical bar), |& operator (I/O) <3>: Redirection. (line 4944)
+* | (vertical bar), |& operator (I/O): Getline/Coprocess. (line 4137)
+* | (vertical bar), |& operator (I/O), pipes, closing: Close Files And Pipes.
+ (line 5310)
+* | (vertical bar), |& operator (I/O), two-way communications: Portal Files.
+ (line 11729)
+* | (vertical bar), || operator <1>: Precedence. (line 6736)
+* | (vertical bar), || operator: Boolean Ops. (line 6514)
+* ~ (tilde), ~ operator <1>: Expression Patterns.
+ (line 6851)
+* ~ (tilde), ~ operator <2>: Precedence. (line 6727)
+* ~ (tilde), ~ operator <3>: Typing and Comparison.
+ (line 6342)
+* ~ (tilde), ~ operator <4>: Regexp Constants. (line 5532)
+* ~ (tilde), ~ operator <5>: Computed Regexps. (line 2656)
+* ~ (tilde), ~ operator: Case-sensitivity. (line 2569)
+
+
+\1f
+Tag Table:
+Node: Top\7f1326
+Node: Foreword\7f26895
+Node: Preface\7f31216
+Ref: Preface-Footnote-1\7f34077
+Node: History\7f34306
+Node: Names\7f36509
+Ref: Names-Footnote-1\7f37969
+Node: This Manual\7f38038
+Ref: This Manual-Footnote-1\7f42723
+Node: Conventions\7f42820
+Node: Manual History\7f44682
+Ref: Manual History-Footnote-1\7f48102
+Ref: Manual History-Footnote-2\7f48140
+Node: How To Contribute\7f48211
+Node: Acknowledgments\7f48809
+Node: Getting Started\7f52576
+Node: Running gawk\7f54940
+Node: One-shot\7f56120
+Node: Read Terminal\7f57336
+Ref: Read Terminal-Footnote-1\7f58982
+Node: Long\7f59150
+Node: Executable Scripts\7f60520
+Ref: Executable Scripts-Footnote-1\7f62404
+Ref: Executable Scripts-Footnote-2\7f62552
+Node: Comments\7f63000
+Node: Quoting\7f65353
+Node: Sample Data Files\7f69833
+Node: Very Simple\7f72853
+Node: Two Rules\7f77443
+Node: More Complex\7f79581
+Ref: More Complex-Footnote-1\7f82489
+Ref: More Complex-Footnote-2\7f82934
+Node: Statements/Lines\7f83014
+Ref: Statements/Lines-Footnote-1\7f87372
+Node: Other Features\7f87634
+Node: When\7f88480
+Ref: When-Footnote-1\7f90706
+Node: Regexp\7f90784
+Node: Regexp Usage\7f92235
+Node: Escape Sequences\7f94272
+Node: Regexp Operators\7f99988
+Ref: Regexp Operators-Footnote-1\7f107077
+Ref: Regexp Operators-Footnote-2\7f107221
+Node: Character Lists\7f107316
+Ref: table-char-classes\7f109260
+Node: GNU Regexp Operators\7f112784
+Node: Case-sensitivity\7f116355
+Ref: Case-sensitivity-Footnote-1\7f119505
+Node: Leftmost Longest\7f119737
+Node: Computed Regexps\7f120919
+Node: Locales\7f124282
+Node: Reading Files\7f126302
+Node: Records\7f128053
+Ref: Records-Footnote-1\7f136555
+Node: Fields\7f136589
+Ref: Fields-Footnote-1\7f139601
+Node: Nonconstant Fields\7f139684
+Node: Changing Fields\7f141876
+Node: Field Separators\7f147122
+Node: Regexp Field Splitting\7f150591
+Node: Single Character Fields\7f153047
+Node: Command Line Field Separator\7f154096
+Node: Field Splitting Summary\7f157513
+Ref: Field Splitting Summary-Footnote-1\7f160691
+Node: Constant Size\7f160789
+Node: Multiple Line\7f165245
+Ref: Multiple Line-Footnote-1\7f170908
+Node: Getline\7f171084
+Node: Plain Getline\7f173143
+Node: Getline/Variable\7f175185
+Node: Getline/File\7f176323
+Node: Getline/Variable/File\7f177641
+Node: Getline/Pipe\7f179188
+Node: Getline/Variable/Pipe\7f181244
+Node: Getline/Coprocess\7f182345
+Node: Getline/Variable/Coprocess\7f183576
+Node: Getline Notes\7f184284
+Node: Getline Summary\7f185927
+Ref: table-getline-variants\7f186211
+Node: Printing\7f187376
+Node: Print\7f189005
+Node: Print Examples\7f190325
+Node: Output Separators\7f193105
+Node: OFMT\7f194857
+Node: Printf\7f196209
+Node: Basic Printf\7f197128
+Node: Control Letters\7f198655
+Node: Format Modifiers\7f201875
+Node: Printf Examples\7f207914
+Node: Redirection\7f210613
+Node: Special Files\7f217175
+Node: Special FD\7f217809
+Node: Special Process\7f220823
+Node: Special Network\7f223055
+Node: Special Caveats\7f223894
+Ref: Special Caveats-Footnote-1\7f225089
+Node: Close Files And Pipes\7f225469
+Ref: Close Files And Pipes-Footnote-1\7f232348
+Ref: Close Files And Pipes-Footnote-2\7f232493
+Node: Expressions\7f232638
+Node: Constants\7f234824
+Node: Scalar Constants\7f235502
+Ref: Scalar Constants-Footnote-1\7f236351
+Node: Nondecimal-numbers\7f236530
+Node: Regexp Constants\7f239572
+Node: Using Constant Regexps\7f240045
+Node: Variables\7f243122
+Node: Using Variables\7f243778
+Node: Assignment Options\7f245279
+Node: Conversion\7f247153
+Ref: Conversion-Footnote-1\7f251902
+Node: Arithmetic Ops\7f252008
+Node: Concatenation\7f254503
+Node: Assignment Ops\7f257187
+Ref: table-assign-ops\7f262136
+Node: Increment Ops\7f264040
+Node: Truth Values\7f267515
+Node: Typing and Comparison\7f268562
+Ref: table-relational-ops\7f271609
+Ref: Typing and Comparison-Footnote-1\7f275850
+Node: Boolean Ops\7f275992
+Node: Conditional Exp\7f279998
+Node: Function Calls\7f281729
+Node: Precedence\7f284612
+Node: Patterns and Actions\7f288033
+Node: Pattern Overview\7f289084
+Node: Regexp Patterns\7f290518
+Node: Expression Patterns\7f291061
+Node: Ranges\7f294593
+Node: BEGIN/END\7f297667
+Node: Using BEGIN/END\7f298417
+Ref: Using BEGIN/END-Footnote-1\7f301135
+Node: I/O And BEGIN/END\7f301246
+Node: Empty\7f303503
+Node: Using Shell Variables\7f303811
+Node: Action Overview\7f306082
+Node: Statements\7f308434
+Node: If Statement\7f310287
+Node: While Statement\7f311783
+Node: Do Statement\7f313812
+Node: For Statement\7f314958
+Node: Switch Statement\7f318074
+Node: Break Statement\7f320338
+Node: Continue Statement\7f322386
+Node: Next Statement\7f324284
+Node: Nextfile Statement\7f326552
+Node: Exit Statement\7f329128
+Node: Built-in Variables\7f331183
+Node: User-modified\7f332275
+Ref: User-modified-Footnote-1\7f339515
+Node: Auto-set\7f339574
+Ref: Auto-set-Footnote-1\7f347911
+Node: ARGC and ARGV\7f348113
+Node: Arrays\7f351807
+Node: Array Intro\7f353709
+Node: Reference to Elements\7f357883
+Node: Assigning Elements\7f359738
+Node: Array Example\7f360205
+Node: Scanning an Array\7f361921
+Node: Delete\7f364182
+Ref: Delete-Footnote-1\7f366534
+Node: Numeric Array Subscripts\7f366588
+Node: Uninitialized Subscripts\7f368766
+Node: Multi-dimensional\7f370357
+Node: Multi-scanning\7f373353
+Node: Array Sorting\7f374962
+Node: Functions\7f378599
+Node: Built-in\7f379331
+Node: Calling Built-in\7f380301
+Node: Numeric Functions\7f382256
+Ref: Numeric Functions-Footnote-1\7f385995
+Ref: Numeric Functions-Footnote-2\7f386318
+Node: String Functions\7f386584
+Ref: String Functions-Footnote-1\7f406443
+Ref: String Functions-Footnote-2\7f406569
+Ref: String Functions-Footnote-3\7f406813
+Node: Gory Details\7f406897
+Ref: table-sub-escapes\7f408523
+Ref: table-sub-posix-92\7f409858
+Ref: table-sub-proposed\7f411197
+Ref: table-posix-2001-sub\7f412550
+Ref: table-gensub-escapes\7f413887
+Ref: Gory Details-Footnote-1\7f415070
+Node: I/O Functions\7f415118
+Ref: I/O Functions-Footnote-1\7f421680
+Node: Time Functions\7f421768
+Ref: Time Functions-Footnote-1\7f432452
+Ref: Time Functions-Footnote-2\7f432517
+Ref: Time Functions-Footnote-3\7f432672
+Ref: Time Functions-Footnote-4\7f432780
+Ref: Time Functions-Footnote-5\7f432902
+Ref: Time Functions-Footnote-6\7f433126
+Node: Bitwise Functions\7f433385
+Ref: table-bitwise-ops\7f433960
+Ref: Bitwise Functions-Footnote-1\7f438182
+Node: I18N Functions\7f438363
+Node: User-defined\7f440086
+Node: Definition Syntax\7f440867
+Node: Function Example\7f445193
+Node: Function Caveats\7f447758
+Node: Return Statement\7f451662
+Node: Dynamic Typing\7f454301
+Node: Internationalization\7f455035
+Node: I18N and L10N\7f456451
+Node: Explaining gettext\7f457135
+Ref: Explaining gettext-Footnote-1\7f462023
+Ref: Explaining gettext-Footnote-2\7f462259
+Node: Programmer i18n\7f462425
+Node: Translator i18n\7f466642
+Node: String Extraction\7f467429
+Ref: String Extraction-Footnote-1\7f468373
+Node: Printf Ordering\7f468496
+Ref: Printf Ordering-Footnote-1\7f471248
+Node: I18N Portability\7f471309
+Ref: I18N Portability-Footnote-1\7f473733
+Node: I18N Example\7f473793
+Ref: I18N Example-Footnote-1\7f476385
+Node: Gawk I18N\7f476454
+Node: Advanced Features\7f477033
+Node: Nondecimal Data\7f478427
+Node: Two-way I/O\7f479977
+Ref: Two-way I/O-Footnote-1\7f485426
+Node: TCP/IP Networking\7f485500
+Node: Portal Files\7f487911
+Node: Profiling\7f488552
+Node: Invoking Gawk\7f496068
+Node: Command Line\7f497245
+Node: Options\7f498024
+Ref: Options-Footnote-1\7f510187
+Node: Other Arguments\7f510209
+Node: AWKPATH Variable\7f512869
+Ref: AWKPATH Variable-Footnote-1\7f515626
+Node: Obsolete\7f515883
+Node: Undocumented\7f516877
+Node: Known Bugs\7f517136
+Node: Library Functions\7f517738
+Ref: Library Functions-Footnote-1\7f520692
+Node: Library Names\7f520860
+Ref: Library Names-Footnote-1\7f524307
+Ref: Library Names-Footnote-2\7f524523
+Node: General Functions\7f524606
+Node: Nextfile Function\7f525665
+Node: Strtonum Function\7f530004
+Node: Assert Function\7f532926
+Node: Round Function\7f536212
+Node: Cliff Random Function\7f537719
+Ref: Cliff Random Function-Footnote-1\7f538702
+Node: Ordinal Functions\7f538770
+Ref: Ordinal Functions-Footnote-1\7f541818
+Node: Join Function\7f542031
+Ref: Join Function-Footnote-1\7f543782
+Node: Gettimeofday Function\7f543979
+Node: Data File Management\7f547676
+Node: Filetrans Function\7f548308
+Node: Rewind Function\7f551716
+Node: File Checking\7f553153
+Node: Empty Files\7f554201
+Node: Ignoring Assigns\7f556408
+Node: Getopt Function\7f557944
+Ref: Getopt Function-Footnote-1\7f568908
+Node: Passwd Functions\7f569106
+Ref: Passwd Functions-Footnote-1\7f577714
+Node: Group Functions\7f577799
+Node: Sample Programs\7f585738
+Node: Running Examples\7f586412
+Node: Clones\7f587134
+Node: Cut Program\7f588260
+Node: Egrep Program\7f597933
+Ref: Egrep Program-Footnote-1\7f605635
+Node: Id Program\7f605742
+Node: Split Program\7f609332
+Node: Tee Program\7f612780
+Node: Uniq Program\7f615442
+Node: Wc Program\7f622780
+Ref: Wc Program-Footnote-1\7f626994
+Node: Miscellaneous Programs\7f627187
+Node: Dupword Program\7f628183
+Node: Alarm Program\7f630205
+Node: Translate Program\7f634730
+Ref: Translate Program-Footnote-1\7f638949
+Ref: Translate Program-Footnote-2\7f639183
+Node: Labels Program\7f639314
+Ref: Labels Program-Footnote-1\7f642587
+Node: Word Sorting\7f642668
+Node: History Sorting\7f646931
+Node: Extract Program\7f648757
+Node: Simple Sed\7f656078
+Node: Igawk Program\7f659112
+Ref: Igawk Program-Footnote-1\7f673741
+Ref: Igawk Program-Footnote-2\7f673939
+Node: Language History\7f674074
+Node: V7/SVR3.1\7f675458
+Node: SVR4\7f677538
+Node: POSIX\7f678977
+Node: BTL\7f680484
+Node: POSIX/GNU\7f682006
+Node: Contributors\7f689379
+Node: Installation\7f692822
+Node: Gawk Distribution\7f693793
+Node: Getting\7f694277
+Node: Extracting\7f695508
+Node: Distribution contents\7f696890
+Node: Unix Installation\7f701971
+Node: Quick Installation\7f702562
+Node: Additional Configuration Options\7f704253
+Node: Configuration Philosophy\7f706001
+Node: Non-Unix Installation\7f708349
+Node: Amiga Installation\7f708936
+Node: BeOS Installation\7f710023
+Node: PC Installation\7f711164
+Node: PC Binary Installation\7f712391
+Node: PC Compiling\7f714222
+Node: PC Dynamic\7f718742
+Node: PC Using\7f721088
+Node: Cygwin\7f725682
+Ref: Cygwin-Footnote-1\7f726674
+Node: VMS Installation\7f726703
+Node: VMS Compilation\7f727231
+Node: VMS Installation Details\7f728802
+Node: VMS Running\7f730426
+Node: VMS POSIX\7f732015
+Node: Unsupported\7f733286
+Node: Atari Installation\7f733689
+Node: Atari Compiling\7f734972
+Node: Atari Using\7f736844
+Node: Tandem Installation\7f739677
+Node: Bugs\7f741342
+Node: Other Versions\7f744605
+Ref: Other Versions-Footnote-1\7f748206
+Node: Notes\7f748245
+Node: Compatibility Mode\7f748937
+Node: Additions\7f749725
+Node: Adding Code\7f750472
+Node: New Ports\7f756519
+Node: Dynamic Extensions\7f760574
+Node: Internals\7f761821
+Node: Sample Library\7f772806
+Node: Internal File Description\7f773465
+Node: Internal File Ops\7f777146
+Ref: Internal File Ops-Footnote-1\7f782436
+Node: Using Internal File Ops\7f782581
+Node: Future Extensions\7f784598
+Node: Basic Concepts\7f788534
+Node: Basic High Level\7f789291
+Ref: Basic High Level-Footnote-1\7f793302
+Node: Basic Data Typing\7f793493
+Node: Floating Point Issues\7f797895
+Ref: Floating Point Issues-Footnote-1\7f801748
+Ref: Floating Point Issues-Footnote-2\7f801798
+Node: Glossary\7f801904
+Node: Copying\7f825513
+Node: GNU Free Documentation License\7f844649
+Node: Index\7f867040
+\1f
+End Tag Table
--- /dev/null
+\input texinfo @c -*-texinfo-*-
+@c %**start of header (This is for running Texinfo on a region.)
+@setfilename gawk.info
+@settitle The GNU Awk User's Guide
+@c %**end of header (This is for running Texinfo on a region.)
+
+@dircategory Text creation and manipulation
+@direntry
+* Gawk: (gawk). A text scanning and processing language.
+@end direntry
+@dircategory Individual utilities
+@direntry
+* awk: (gawk)Invoking gawk. Text scanning and processing.
+@end direntry
+
+@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.
+@set UPDATE-MONTH June, 2005
+@set VERSION 3.1
+@set PATCHLEVEL 5
+
+@set FSF
+
+@set TITLE GAWK: Effective AWK Programming
+@set SUBTITLE A User's Guide for GNU Awk
+@set EDITION 3
+
+@iftex
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER @inmargin{@image{lflashlight,1cm}, @image{rflashlight,1cm}}
+@end iftex
+@ifinfo
+@set DOCUMENT Info file
+@set CHAPTER major node
+@set APPENDIX major node
+@set SECTION minor node
+@set SUBSECTION node
+@set DARKCORNER (d.c.)
+@end ifinfo
+@ifhtml
+@set DOCUMENT Web page
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@end ifhtml
+@ifdocbook
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@end ifdocbook
+
+@c some special symbols
+@iftex
+@set LEQ @math{@leq}
+@end iftex
+@ifnottex
+@set LEQ <=
+@end ifnottex
+
+@set FN file name
+@set FFN File Name
+@set DF data file
+@set DDF Data File
+@set PVERSION version
+@set CTL Ctrl
+
+@ignore
+Some comments on the layout for TeX.
+1. Use at least texinfo.tex 2000-09-06.09
+2. I have done A LOT of work to make this look good. There are `@page' commands
+ and use of `@group ... @end group' in a number of places. If you muck
+ with anything, it's your responsibility not to break the layout.
+@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
+
+@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
+Copyright @copyright{} 1989, 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+@sp 2
+
+This is Edition @value{EDITION} of @cite{@value{TITLE}: @value{SUBTITLE}},
+for the @value{VERSION}.@value{PATCHLEVEL} (or later) version of the GNU
+implementation of AWK.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+@enumerate a
+@item
+``A GNU Manual''
+
+@item
+``You have freedom to copy and modify this GNU Manual, like GNU
+software. Copies published by the Free Software Foundation raise
+funds for GNU development.''
+@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.
+@c @setchapternewpage odd
+
+@titlepage
+@title @value{TITLE}
+@subtitle @value{SUBTITLE}
+@subtitle Edition @value{EDITION}
+@subtitle @value{UPDATE-MONTH}
+@author Arnold D. Robbins
+
+@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
+@ignore
+The programs and applications presented in this book have been
+included for their instructional value. They have been tested with care
+but are not guaranteed for any particular purpose. The publisher does not
+offer any warranties or representations, nor does it accept any
+liabilities with respect to the programs or applications.
+So there.
+@sp 2
+UNIX is a registered trademark of The Open Group in the United States and other countries. @*
+Microsoft, MS and MS-DOS are registered trademarks, and Windows is a
+trademark of Microsoft Corporation in the United States and other
+countries. @*
+Atari, 520ST, 1040ST, TT, STE, Mega and Falcon are registered trademarks
+or trademarks of Atari Corporation. @*
+DEC, Digital, OpenVMS, ULTRIX and VMS are trademarks of Digital Equipment
+Corporation. @*
+@end ignore
+``To boldly go where no man has gone before'' is a
+Registered Trademark of Paramount Pictures Corporation. @*
+@c sorry, i couldn't resist
+@sp 3
+Published by:
+@sp 1
+
+Free Software Foundation @*
+51 Franklin Street, Fifth Floor @*
+Boston, MA 02110-1301 USA @*
+Phone: +1-617-542-5942 @*
+Fax: +1-617-542-2652 @*
+Email: @email{gnu@@gnu.org} @*
+URL: @uref{http://www.gnu.org/} @*
+
+@c This one is correct for gawk 3.1.0 from the FSF
+ISBN 1-882114-28-0 @*
+@sp 2
+@insertcopying
+@sp 2
+Cover art by Etienne Suvasa.
+@end titlepage
+
+@c Thanks to Bob Chassell for directions on doing dedications.
+@iftex
+@headings off
+@page
+@w{ }
+@sp 9
+@center @i{To Miriam, for making me complete.}
+@sp 1
+@center @i{To Chana, for the joy you bring us.}
+@sp 1
+@center @i{To Rivka, for the exponential increase.}
+@sp 1
+@center @i{To Nachum, for the added dimension.}
+@sp 1
+@center @i{To Malka, for the new beginning.}
+@w{ }
+@page
+@w{ }
+@page
+@headings on
+@end iftex
+
+@iftex
+@headings off
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+
+@ifnottex
+@ifnotxml
+@node Top
+@top General Introduction
+@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.
+
+This file documents @command{awk}, a program that you can use to select
+particular records in a file and perform operations upon them.
+
+@insertcopying
+
+@end ifnotxml
+@end ifnottex
+
+@menu
+* Foreword:: Some nice words about this
+ @value{DOCUMENT}.
+* Preface:: What this @value{DOCUMENT} is about; brief
+ history and acknowledgments.
+* Getting Started:: A basic introduction to using
+ @command{awk}. How to run an @command{awk}
+ program. Command-line syntax.
+* Regexp:: All about matching things using regular
+ expressions.
+* Reading Files:: How to read files and manipulate fields.
+* Printing:: How to print using @command{awk}. Describes
+ the @code{print} and @code{printf}
+ statements. Also describes redirection of
+ output.
+* Expressions:: Expressions are the basic building blocks
+ of statements.
+* Patterns and Actions:: Overviews of patterns and actions.
+* Arrays:: The description and use of arrays. Also
+ includes array-oriented control statements.
+* Functions:: Built-in and user-defined functions.
+* Internationalization:: Getting @command{gawk} to speak your
+ language.
+* Advanced Features:: Stuff for advanced users, specific to
+ @command{gawk}.
+* Invoking Gawk:: How to run @command{gawk}.
+* Library Functions:: A Library of @command{awk} Functions.
+* Sample Programs:: Many @command{awk} programs with complete
+ explanations.
+* Language History:: The evolution of the @command{awk}
+ language.
+* Installation:: Installing @command{gawk} under various
+ operating systems.
+* Notes:: Notes about @command{gawk} extensions and
+ possible future work.
+* Basic Concepts:: A very quick intoduction to programming
+ concepts.
+* Glossary:: An explanation of some unfamiliar terms.
+* Copying:: Your right to copy and distribute
+ @command{gawk}.
+* GNU Free Documentation License:: The license for this @value{DOCUMENT}.
+* Index:: Concept and Variable Index.
+
+@detailmenu
+* History:: The history of @command{gawk} and
+ @command{awk}.
+* Names:: What name to use to find @command{awk}.
+* This Manual:: Using this @value{DOCUMENT}. Includes
+ sample input files that you can use.
+* Conventions:: Typographical Conventions.
+* Manual History:: Brief history of the GNU project and this
+ @value{DOCUMENT}.
+* How To Contribute:: Helping to save the world.
+* Acknowledgments:: Acknowledgments.
+* Running gawk:: How to run @command{gawk} programs;
+ includes command-line syntax.
+* One-shot:: Running a short throwaway @command{awk}
+ program.
+* Read Terminal:: Using no input files (input from terminal
+ instead).
+* Long:: Putting permanent @command{awk} programs in
+ files.
+* Executable Scripts:: Making self-contained @command{awk}
+ programs.
+* Comments:: Adding documentation to @command{gawk}
+ programs.
+* Quoting:: More discussion of shell quoting issues.
+* Sample Data Files:: Sample data files for use in the
+ @command{awk} programs illustrated in this
+ @value{DOCUMENT}.
+* Very Simple:: A very simple example.
+* Two Rules:: A less simple one-line example using two
+ rules.
+* More Complex:: A more complex example.
+* Statements/Lines:: Subdividing or combining statements into
+ lines.
+* Other Features:: Other Features of @command{awk}.
+* When:: When to use @command{gawk} and when to use
+ other things.
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Character Lists:: What can go between @samp{[...]}.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* Locales:: How the locale affects things.
+* Records:: Controlling how data is split into records.
+* Fields:: An introduction to fields.
+* Nonconstant Fields:: Nonconstant Field Numbers.
+* Changing Fields:: Changing the Contents of a Field.
+* Field Separators:: The field separator and how to change it.
+* Regexp Field Splitting:: Using regexps as the field separator.
+* Single Character Fields:: Making each character a separate field.
+* Command Line Field Separator:: Setting @code{FS} from the command-line.
+* Field Splitting Summary:: Some final points and a summary table.
+* Constant Size:: Reading constant width data.
+* Multiple Line:: Reading multi-line records.
+* Getline:: Reading files under explicit program
+ control using the @code{getline} function.
+* Plain Getline:: Using @code{getline} with no arguments.
+* Getline/Variable:: Using @code{getline} into a variable.
+* Getline/File:: Using @code{getline} from a file.
+* Getline/Variable/File:: Using @code{getline} into a variable from a
+ file.
+* Getline/Pipe:: Using @code{getline} from a pipe.
+* Getline/Variable/Pipe:: Using @code{getline} into a variable from a
+ pipe.
+* Getline/Coprocess:: Using @code{getline} from a coprocess.
+* Getline/Variable/Coprocess:: Using @code{getline} into a variable from a
+ coprocess.
+* Getline Notes:: Important things to know about
+ @code{getline}.
+* Getline Summary:: Summary of @code{getline} Variants.
+* Print:: The @code{print} statement.
+* Print Examples:: Simple examples of @code{print} statements.
+* Output Separators:: The output separators and how to change
+ them.
+* OFMT:: Controlling Numeric Output With
+ @code{print}.
+* Printf:: The @code{printf} statement.
+* Basic Printf:: Syntax of the @code{printf} statement.
+* Control Letters:: Format-control letters.
+* Format Modifiers:: Format-specification modifiers.
+* Printf Examples:: Several examples.
+* Redirection:: How to redirect output to multiple files
+ and pipes.
+* Special Files:: File name interpretation in @command{gawk}.
+ @command{gawk} allows access to inherited
+ file descriptors.
+* Special FD:: Special files for I/O.
+* Special Process:: Special files for process information.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+* Close Files And Pipes:: Closing Input and Output Files and Pipes.
+* Constants:: String, numeric and regexp constants.
+* Scalar Constants:: Numeric and string constants.
+* Nondecimal-numbers:: What are octal and hex numbers.
+* Regexp Constants:: Regular Expression constants.
+* Using Constant Regexps:: When and how to use a regexp constant.
+* Variables:: Variables give names to values for later
+ use.
+* Using Variables:: Using variables in your programs.
+* Assignment Options:: Setting variables on the command-line and a
+ summary of command-line syntax. This is an
+ advanced method of input.
+* Conversion:: The conversion of strings to numbers and
+ vice versa.
+* Arithmetic Ops:: Arithmetic operations (@samp{+}, @samp{-},
+ etc.)
+* Concatenation:: Concatenating strings.
+* Assignment Ops:: Changing the value of a variable or a
+ field.
+* Increment Ops:: Incrementing the numeric value of a
+ variable.
+* Truth Values:: What is ``true'' and what is ``false''.
+* Typing and Comparison:: How variables acquire types and how this
+ affects comparison of numbers and strings
+ with @samp{<}, etc.
+* Boolean Ops:: Combining comparison expressions using
+ boolean operators @samp{||} (``or''),
+ @samp{&&} (``and'') and @samp{!} (``not'').
+* Conditional Exp:: Conditional expressions select between two
+ subexpressions under control of a third
+ subexpression.
+* Function Calls:: A function call is an expression.
+* Precedence:: How various operators nest.
+* Pattern Overview:: What goes into a pattern.
+* Regexp Patterns:: Using regexps as patterns.
+* Expression Patterns:: Any expression can be used as a pattern.
+* Ranges:: Pairs of patterns specify record ranges.
+* BEGIN/END:: Specifying initialization and cleanup
+ rules.
+* Using BEGIN/END:: How and why to use BEGIN/END rules.
+* I/O And BEGIN/END:: I/O issues in BEGIN/END rules.
+* Empty:: The empty pattern, which matches every
+ record.
+* Using Shell Variables:: How to use shell variables with
+ @command{awk}.
+* Action Overview:: What goes into an action.
+* Statements:: Describes the various control statements in
+ detail.
+* If Statement:: Conditionally execute some @command{awk}
+ statements.
+* While Statement:: Loop until some condition is satisfied.
+* Do Statement:: Do specified action while looping until
+ some condition is satisfied.
+* For Statement:: Another looping statement, that provides
+ initialization and increment clauses.
+* Switch Statement:: Switch/case evaluation for conditional
+ execution of statements based on a value.
+* Break Statement:: Immediately exit the innermost enclosing
+ loop.
+* Continue Statement:: Skip to the end of the innermost enclosing
+ loop.
+* Next Statement:: Stop processing the current input record.
+* Nextfile Statement:: Stop processing the current file.
+* Exit Statement:: Stop execution of @command{awk}.
+* Built-in Variables:: Summarizes the built-in variables.
+* User-modified:: Built-in variables that you change to
+ control @command{awk}.
+* Auto-set:: Built-in variables where @command{awk}
+ gives you information.
+* ARGC and ARGV:: Ways to use @code{ARGC} and @code{ARGV}.
+* Array Intro:: Introduction to Arrays
+* Reference to Elements:: How to examine one element of an array.
+* Assigning Elements:: How to change an element of an array.
+* Array Example:: Basic Example of an Array
+* Scanning an Array:: A variation of the @code{for} statement. It
+ loops through the indices of an array's
+ existing elements.
+* Delete:: The @code{delete} statement removes an
+ element from an array.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ @command{awk}.
+* Uninitialized Subscripts:: Using Uninitialized variables as
+ subscripts.
+* Multi-dimensional:: Emulating multidimensional arrays in
+ @command{awk}.
+* Multi-scanning:: Scanning multidimensional arrays.
+* Array Sorting:: Sorting array values and indices.
+* Built-in:: Summarizes the built-in functions.
+* Calling Built-in:: How to call built-in functions.
+* Numeric Functions:: Functions that work with numbers, including
+ @code{int}, @code{sin} and @code{rand}.
+* String Functions:: Functions for string manipulation, such as
+ @code{split}, @code{match} and
+ @code{sprintf}.
+* Gory Details:: More than you want to know about @samp{\}
+ and @samp{&} with @code{sub}, @code{gsub},
+ and @code{gensub}.
+* I/O Functions:: Functions for files and shell commands.
+* Time Functions:: Functions for dealing with timestamps.
+* Bitwise Functions:: Functions for bitwise operations.
+* I18N Functions:: Functions for string translation.
+* User-defined:: Describes User-defined functions in detail.
+* Definition Syntax:: How to write definitions and what they
+ mean.
+* Function Example:: An example function definition and what it
+ does.
+* Function Caveats:: Things to watch out for.
+* Return Statement:: Specifying the value a function returns.
+* Dynamic Typing:: How variable types can change at runtime.
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @code{gettext} works.
+* Programmer i18n:: Features for the programmer.
+* Translator i18n:: Features for the translator.
+* String Extraction:: Extracting marked strings.
+* Printf Ordering:: Rearranging @code{printf} arguments.
+* I18N Portability:: @command{awk}-level portability issues.
+* I18N Example:: A simple i18n example.
+* Gawk I18N:: @command{gawk} is also internationalized.
+* Nondecimal Data:: Allowing nondecimal input data.
+* Two-way I/O:: Two-way communications with another
+ process.
+* TCP/IP Networking:: Using @command{gawk} for network
+ programming.
+* Portal Files:: Using @command{gawk} with BSD portals.
+* Profiling:: Profiling your @command{awk} programs.
+* Command Line:: How to run @command{awk}.
+* Options:: Command-line options and their meanings.
+* Other Arguments:: Input file names and variable assignments.
+* AWKPATH Variable:: Searching directories for @command{awk}
+ programs.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Known Bugs:: Known Bugs in @command{gawk}.
+* Library Names:: How to best name private global variables
+ in library functions.
+* General Functions:: Functions that are of general use.
+* Nextfile Function:: Two implementations of a @code{nextfile}
+ function.
+* Assert Function:: A function for assertions in @command{awk}
+ programs.
+* Round Function:: A function for rounding if @code{sprintf}
+ does not do it correctly.
+* Cliff Random Function:: The Cliff Random Number Generator.
+* Ordinal Functions:: Functions for using characters as numbers
+ and vice versa.
+* Join Function:: A function to join an array into a string.
+* Gettimeofday Function:: A function to get formatted times.
+* Data File Management:: Functions for managing command-line data
+ files.
+* Filetrans Function:: A function for handling data file
+ transitions.
+* Rewind Function:: A function for rereading the current file.
+* File Checking:: Checking that data files are readable.
+* Empty Files:: Checking for zero-length files.
+* Ignoring Assigns:: Treating assignments as file names.
+* Getopt Function:: A function for processing command-line
+ arguments.
+* Passwd Functions:: Functions for getting user information.
+* Group Functions:: Functions for getting group information.
+* Running Examples:: How to run these examples.
+* Clones:: Clones of common utilities.
+* Cut Program:: The @command{cut} utility.
+* Egrep Program:: The @command{egrep} utility.
+* Id Program:: The @command{id} utility.
+* Split Program:: The @command{split} utility.
+* Tee Program:: The @command{tee} utility.
+* Uniq Program:: The @command{uniq} utility.
+* Wc Program:: The @command{wc} utility.
+* Miscellaneous Programs:: Some interesting @command{awk} programs.
+* Dupword Program:: Finding duplicated words in a document.
+* Alarm Program:: An alarm clock.
+* Translate Program:: A program similar to the @command{tr}
+ utility.
+* Labels Program:: Printing mailing labels.
+* Word Sorting:: A program to produce a word usage count.
+* History Sorting:: Eliminating duplicate entries from a
+ history file.
+* Extract Program:: Pulling out programs from Texinfo source
+ files.
+* Simple Sed:: A Simple Stream Editor.
+* Igawk Program:: A wrapper for @command{awk} that includes
+ files.
+* V7/SVR3.1:: The major changes between V7 and System V
+ Release 3.1.
+* SVR4:: Minor changes between System V Releases 3.1
+ and 4.
+* POSIX:: New features from the POSIX standard.
+* BTL:: New features from the Bell Laboratories
+ version of @command{awk}.
+* POSIX/GNU:: The extensions in @command{gawk} not in
+ POSIX @command{awk}.
+* Contributors:: The major contributors to @command{gawk}.
+* Gawk Distribution:: What is in the @command{gawk} distribution.
+* Getting:: How to get the distribution.
+* Extracting:: How to extract the distribution.
+* Distribution contents:: What is in the distribution.
+* Unix Installation:: Installing @command{gawk} under various
+ versions of Unix.
+* Quick Installation:: Compiling @command{gawk} under Unix.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+* Non-Unix Installation:: Installation on Other Operating Systems.
+* Amiga Installation:: Installing @command{gawk} on an Amiga.
+* BeOS Installation:: Installing @command{gawk} on BeOS.
+* PC Installation:: Installing and Compiling @command{gawk} on
+ MS-DOS and OS/2.
+* PC Binary Installation:: Installing a prepared distribution.
+* PC Compiling:: Compiling @command{gawk} for MS-DOS, Windows32,
+ and OS/2.
+* PC Using:: Running @command{gawk} on MS-DOS, Windows32 and
+ OS/2.
+* PC Dynamic:: Compiling @command{gawk} for dynamic
+ libraries.
+* Cygwin:: Building and running @command{gawk} for
+ Cygwin.
+* VMS Installation:: Installing @command{gawk} on VMS.
+* VMS Compilation:: How to compile @command{gawk} under VMS.
+* VMS Installation Details:: How to install @command{gawk} under VMS.
+* VMS Running:: How to run @command{gawk} under VMS.
+* VMS POSIX:: Alternate instructions for VMS POSIX.
+* Unsupported:: Systems whose ports are no longer
+ supported.
+* Atari Installation:: Installing @command{gawk} on the Atari ST.
+* Atari Compiling:: Compiling @command{gawk} on Atari.
+* Atari Using:: Running @command{gawk} on Atari.
+* Tandem Installation:: Installing @command{gawk} on a Tandem.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available @command{awk}
+ implementations.
+* Compatibility Mode:: How to disable certain @command{gawk}
+ extensions.
+* Additions:: Making Additions To @command{gawk}.
+* Adding Code:: Adding code to the main body of
+ @command{gawk}.
+* New Ports:: Porting @command{gawk} to a new operating
+ system.
+* Dynamic Extensions:: Adding new built-in functions to
+ @command{gawk}.
+* Internals:: A brief look at some @command{gawk}
+ internals.
+* Sample Library:: A example of new functions.
+* Internal File Description:: What the new functions will do.
+* Internal File Ops:: The code for internal file operations.
+* Using Internal File Ops:: How to use an external extension.
+* Future Extensions:: New features that may be implemented one
+ day.
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+* Floating Point Issues:: Stuff to know about floating-point numbers.
+@end detailmenu
+@end menu
+
+@c dedication for Info file
+@ifinfo
+@center To Miriam, for making me complete.
+@sp 1
+@center To Chana, for the joy you bring us.
+@sp 1
+@center To Rivka, for the exponential increase.
+@sp 1
+@center To Nachum, for the added dimension.
+@sp 1
+@center To Malka, for the new beginning.
+@end ifinfo
+
+@summarycontents
+@contents
+
+@node Foreword
+@unnumbered Foreword
+
+Arnold Robbins and I are good friends. We were introduced 11 years ago
+by circumstances---and our favorite programming language, AWK.
+The circumstances started a couple of years
+earlier. I was working at a new job and noticed an unplugged
+Unix computer sitting in the corner. No one knew how to use it,
+and neither did I. However,
+a couple of days later it was running, and
+I was @code{root} and the one-and-only user.
+That day, I began the transition from statistician to Unix programmer.
+
+On one of many trips to the library or bookstore in search of
+books on Unix, I found the gray AWK book, a.k.a. Aho, Kernighan and
+Weinberger, @cite{The AWK Programming Language}, Addison-Wesley,
+1988. AWK's simple programming paradigm---find a pattern in the
+input and then perform an action---often reduced complex or tedious
+data manipulations to few lines of code. I was excited to try my
+hand at programming in AWK.
+
+Alas, the @command{awk} on my computer was a limited version of the
+language described in the AWK book. I discovered that my computer
+had ``old @command{awk}'' and the AWK book described ``new @command{awk}.''
+I learned that this was typical; the old version refused to step
+aside or relinquish its name. If a system had a new @command{awk}, it was
+invariably called @command{nawk}, and few systems had it.
+The best way to get a new @command{awk} was to @command{ftp} the source code for
+@command{gawk} from @code{prep.ai.mit.edu}. @command{gawk} was a version of
+new @command{awk} written by David Trueman and Arnold, and available under
+the GNU General Public License.
+
+(Incidentally,
+it's no longer difficult to find a new @command{awk}. @command{gawk} ships with
+Linux, and you can download binaries or source code for almost
+any system; my wife uses @command{gawk} on her VMS box.)
+
+My Unix system started out unplugged from the wall; it certainly was not
+plugged into a network. So, oblivious to the existence of @command{gawk}
+and the Unix community in general, and desiring a new @command{awk}, I wrote
+my own, called @command{mawk}.
+Before I was finished I knew about @command{gawk},
+but it was too late to stop, so I eventually posted
+to a @code{comp.sources} newsgroup.
+
+A few days after my posting, I got a friendly email
+from Arnold introducing
+himself. He suggested we share design and algorithms and
+attached a draft of the POSIX standard so
+that I could update @command{mawk} to support language extensions added
+after publication of the AWK book.
+
+Frankly, if our roles had
+been reversed, I would not have been so open and we probably would
+have never met. I'm glad we did meet.
+He is an AWK expert's AWK expert and a genuinely nice person.
+Arnold contributes significant amounts of his
+expertise and time to the Free Software Foundation.
+
+This book is the @command{gawk} reference manual, but at its core it
+is a book about AWK programming that
+will appeal to a wide audience.
+It is a definitive reference to the AWK language as defined by the
+1987 Bell Labs release and codified in the 1992 POSIX Utilities
+standard.
+
+On the other hand, the novice AWK programmer can study
+a wealth of practical programs that emphasize
+the power of AWK's basic idioms:
+data driven control-flow, pattern matching with regular expressions,
+and associative arrays.
+Those looking for something new can try out @command{gawk}'s
+interface to network protocols via special @file{/inet} files.
+
+The programs in this book make clear that an AWK program is
+typically much smaller and faster to develop than
+a counterpart written in C.
+Consequently, there is often a payoff to prototype an
+algorithm or design in AWK to get it running quickly and expose
+problems early. Often, the interpreted performance is adequate
+and the AWK prototype becomes the product.
+
+The new @command{pgawk} (profiling @command{gawk}), produces
+program execution counts.
+I recently experimented with an algorithm that for
+@math{n} lines of input, exhibited
+@tex
+$\sim\! Cn^2$
+@end tex
+@ifnottex
+~ C n^2
+@end ifnottex
+performance, while
+theory predicted
+@tex
+$\sim\! Cn\log n$
+@end tex
+@ifnottex
+~ C n log n
+@end ifnottex
+behavior. A few minutes poring
+over the @file{awkprof.out} profile pinpointed the problem to
+a single line of code. @command{pgawk} is a welcome addition to
+my programmer's toolbox.
+
+Arnold has distilled over a decade of experience writing and
+using AWK programs, and developing @command{gawk}, into this book. If you use
+AWK or want to learn how, then read this book.
+
+@display
+Michael Brennan
+Author of @command{mawk}
+@end display
+
+@node Preface
+@unnumbered Preface
+@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.
+
+Several kinds of tasks occur repeatedly
+when working with text files.
+You might want to extract certain lines and discard the rest.
+Or you may need to make changes wherever certain patterns appear,
+but leave the rest of the file alone.
+Writing single-use programs for these tasks in languages such as C, C++, or Pascal
+is time-consuming and inconvenient.
+Such jobs are often easier with @command{awk}.
+The @command{awk} utility interprets a special-purpose programming language
+that makes it easy to handle simple data-reformatting jobs.
+
+The GNU implementation of @command{awk} is called @command{gawk}; it is fully
+compatible with the System V Release 4 version of
+@command{awk}. @command{gawk} is also compatible with the POSIX
+specification of the @command{awk} language. This means that all
+properly written @command{awk} programs should work with @command{gawk}.
+Thus, we usually don't distinguish between @command{gawk} and other
+@command{awk} implementations.
+
+@cindex @command{awk}, POSIX and, See Also POSIX @command{awk}
+@cindex @command{awk}, POSIX and
+@cindex POSIX, @command{awk} and
+@cindex @command{gawk}, @command{awk} and
+@cindex @command{awk}, @command{gawk} and
+@cindex @command{awk}, uses for
+Using @command{awk} allows you to:
+
+@itemize @bullet
+@item
+Manage small, personal databases
+
+@item
+Generate reports
+
+@item
+Validate data
+
+@item
+Produce indexes and perform other document preparation tasks
+
+@item
+Experiment with algorithms that you can adapt later to other computer
+languages
+@end itemize
+
+@cindex @command{awk}, See Also @command{gawk}
+@cindex @command{gawk}, See Also @command{awk}
+@cindex @command{gawk}, uses for
+In addition,
+@command{gawk}
+provides facilities that make it easy to:
+
+@itemize @bullet
+@item
+Extract bits and pieces of data for processing
+
+@item
+Sort data
+
+@item
+Perform simple network communications
+@end itemize
+
+This @value{DOCUMENT} teaches you about the @command{awk} language and
+how you can use it effectively. You should already be familiar with basic
+system commands, such as @command{cat} and @command{ls},@footnote{These commands
+are available on POSIX-compliant systems, as well as on traditional
+Unix-based systems. If you are using some other operating system, you still need to
+be familiar with the ideas of I/O redirection and pipes.} as well as basic shell
+facilities, such as input/output (I/O) redirection and pipes.
+
+@cindex GNU @command{awk}, See @command{gawk}
+Implementations of the @command{awk} language are available for many
+different computing environments. This @value{DOCUMENT}, while describing
+the @command{awk} language in general, also describes the particular
+implementation of @command{awk} called @command{gawk} (which stands for
+``GNU awk''). @command{gawk} runs on a broad range of Unix systems,
+ranging from 80386 PC-based computers up through large-scale systems,
+such as Crays. @command{gawk} has also been ported to Mac OS X,
+MS-DOS, Microsoft Windows (all versions) and OS/2 PCs, Atari and Amiga
+microcomputers, BeOS, Tandem D20, and VMS.
+
+@menu
+* History:: The history of @command{gawk} and
+ @command{awk}.
+* Names:: What name to use to find @command{awk}.
+* This Manual:: Using this @value{DOCUMENT}. Includes sample
+ input files that you can use.
+* Conventions:: Typographical Conventions.
+* Manual History:: Brief history of the GNU project and this
+ @value{DOCUMENT}.
+* How To Contribute:: Helping to save the world.
+* Acknowledgments:: Acknowledgments.
+@end menu
+
+@node History
+@unnumberedsec History of @command{awk} and @command{gawk}
+@cindex recipe for a programming language
+@cindex programming language, recipe for
+@center Recipe For A Programming Language
+
+@multitable {2 parts} {1 part @code{egrep}} {1 part @code{snobol}}
+@item @tab 1 part @code{egrep} @tab 1 part @code{snobol}
+@item @tab 2 parts @code{ed} @tab 3 parts C
+@end multitable
+
+@quotation
+Blend all parts well using @code{lex} and @code{yacc}.
+Document minimally and release.
+
+After eight years, add another part @code{egrep} and two
+more parts C. Document very well and release.
+@end quotation
+
+@cindex Aho, Alfred
+@cindex Weinberger, Peter
+@cindex Kernighan, Brian
+@cindex @command{awk}, history of
+The name @command{awk} comes from the initials of its designers: Alfred V.@:
+Aho, Peter J.@: Weinberger and Brian W.@: Kernighan. The original version of
+@command{awk} was written in 1977 at AT&T Bell Laboratories.
+In 1985, a new version made the programming
+language more powerful, introducing user-defined functions, multiple input
+streams, and computed regular expressions.
+This new version became widely available with Unix System V
+Release 3.1 (SVR3.1).
+The version in SVR4 added some new features and cleaned
+up the behavior in some of the ``dark corners'' of the language.
+The specification for @command{awk} in the POSIX Command Language
+and Utilities standard further clarified the language.
+Both the @command{gawk} designers and the original Bell Laboratories @command{awk}
+designers provided feedback for the POSIX specification.
+
+@cindex Rubin, Paul
+@cindex Fenlason, Jay
+@cindex Trueman, David
+Paul Rubin wrote the GNU implementation, @command{gawk}, in 1986.
+Jay Fenlason completed it, with advice from Richard Stallman. John Woods
+contributed parts of the code as well. In 1988 and 1989, David Trueman, with
+help from me, thoroughly reworked @command{gawk} for compatibility
+with the newer @command{awk}.
+Circa 1995, I became the primary maintainer.
+Current development focuses on bug fixes,
+performance improvements, standards compliance, and occasionally, new features.
+
+In May of 1997, J@"urgen Kahrs felt the need for network access
+from @command{awk}, and with a little help from me, set about adding
+features to do this for @command{gawk}. At that time, he also
+wrote the bulk of
+@cite{TCP/IP Internetworking with @command{gawk}}
+(a separate document, available as part of the @command{gawk} distribution).
+His code finally became part of the main @command{gawk} distribution
+with @command{gawk} @value{PVERSION} 3.1.
+
+@xref{Contributors},
+for a complete list of those who made important contributions to @command{gawk}.
+
+@node Names
+@section A Rose by Any Other Name
+
+@cindex @command{awk}, new vs. old
+The @command{awk} language has evolved over the years. Full details are
+provided in @ref{Language History}.
+The language described in this @value{DOCUMENT}
+is often referred to as ``new @command{awk}'' (@command{nawk}).
+
+@cindex @command{awk}, versions of
+Because of this, many systems have multiple
+versions of @command{awk}.
+Some systems have an @command{awk} utility that implements the
+original version of the @command{awk} language and a @command{nawk} utility
+for the new
+version.
+Others have an @command{oawk} version for the ``old @command{awk}''
+language and plain @command{awk} for the new one. Still others only
+have one version, which is usually the new one.@footnote{Often, these systems
+use @command{gawk} for their @command{awk} implementation!}
+
+@cindex @command{nawk} utility
+@cindex @command{oawk} utility
+All in all, this makes it difficult for you to know which version of
+@command{awk} you should run when writing your programs. The best advice
+I can give here is to check your local documentation. Look for @command{awk},
+@command{oawk}, and @command{nawk}, as well as for @command{gawk}.
+It is likely that you already
+have some version of new @command{awk} on your system, which is what
+you should use when running your programs. (Of course, if you're reading
+this @value{DOCUMENT}, chances are good that you have @command{gawk}!)
+
+Throughout this @value{DOCUMENT}, whenever we refer to a language feature
+that should be available in any complete implementation of POSIX @command{awk},
+we simply use the term @command{awk}. When referring to a feature that is
+specific to the GNU implementation, we use the term @command{gawk}.
+
+@node This Manual
+@section Using This Book
+@cindex @command{awk}, terms describing
+
+The term @command{awk} refers to a particular program as well as to the language you
+use to tell this program what to do. When we need to be careful, we call
+the language ``the @command{awk} language,''
+and the program ``the @command{awk} utility.''
+This @value{DOCUMENT} explains
+both the @command{awk} language and how to run the @command{awk} utility.
+The term @dfn{@command{awk} program} refers to a program written by you in
+the @command{awk} programming language.
+
+@cindex @command{gawk}, @command{awk} and
+@cindex @command{awk}, @command{gawk} and
+@cindex POSIX @command{awk}
+Primarily, this @value{DOCUMENT} explains the features of @command{awk},
+as defined in the POSIX standard. It does so in the context of the
+@command{gawk} implementation. While doing so, it also
+attempts to describe important differences between @command{gawk}
+and other @command{awk} implementations.@footnote{All such differences
+appear in the index under the
+entry ``differences in @command{awk} and @command{gawk}.''}
+Finally, any @command{gawk} features that are not in
+the POSIX standard for @command{awk} are noted.
+
+@ifnotinfo
+This @value{DOCUMENT} has the difficult task of being both a tutorial and a reference.
+If you are a novice, feel free to skip over details that seem too complex.
+You should also ignore the many cross-references; they are for the
+expert user and for the online Info version of the document.
+@end ifnotinfo
+
+There are
+subsections labelled
+as @strong{Advanced Notes}
+scattered throughout the @value{DOCUMENT}.
+They add a more complete explanation of points that are relevant, but not likely
+to be of interest on first reading.
+All appear in the index, under the heading ``advanced features.''
+
+Most of the time, the examples use complete @command{awk} programs.
+In some of the more advanced sections, only the part of the @command{awk}
+program that illustrates the concept currently being described is shown.
+
+While this @value{DOCUMENT} is aimed principally at people who have not been
+exposed
+to @command{awk}, there is a lot of information here that even the @command{awk}
+expert should find useful. In particular, the description of POSIX
+@command{awk} and the example programs in
+@ref{Library Functions}, and in
+@ref{Sample Programs},
+should be of interest.
+
+@ref{Getting Started},
+provides the essentials you need to know to begin using @command{awk}.
+
+@ref{Regexp},
+introduces regular expressions in general, and in particular the flavors
+supported by POSIX @command{awk} and @command{gawk}.
+
+@ref{Reading Files},
+describes how @command{awk} reads your data.
+It introduces the concepts of records and fields, as well
+as the @code{getline} command.
+I/O redirection is first described here.
+
+@ref{Printing},
+describes how @command{awk} programs can produce output with
+@code{print} and @code{printf}.
+
+@ref{Expressions},
+describes expressions, which are the basic building blocks
+for getting most things done in a program.
+
+@ref{Patterns and Actions},
+describes how to write patterns for matching records, actions for
+doing something when a record is matched, and the built-in variables
+@command{awk} and @command{gawk} use.
+
+@ref{Arrays},
+covers @command{awk}'s one-and-only data structure: associative arrays.
+Deleting array elements and whole arrays is also described, as well as
+sorting arrays in @command{gawk}.
+
+@ref{Functions},
+describes the built-in functions @command{awk} and
+@command{gawk} provide, as well as how to define
+your own functions.
+
+@ref{Internationalization},
+describes special features in @command{gawk} for translating program
+messages into different languages at runtime.
+
+@ref{Advanced Features},
+describes a number of @command{gawk}-specific advanced features.
+Of particular note
+are the abilities to have two-way communications with another process,
+perform TCP/IP networking, and
+profile your @command{awk} programs.
+
+@ref{Invoking Gawk},
+describes how to run @command{gawk}, the meaning of its
+command-line options, and how it finds @command{awk}
+program source files.
+
+@ref{Library Functions}, and
+@ref{Sample Programs},
+provide many sample @command{awk} programs.
+Reading them allows you to see @command{awk}
+solving real problems.
+
+@ref{Language History},
+describes how the @command{awk} language has evolved since
+first release to present. It also describes how @command{gawk}
+has acquired features over time.
+
+@ref{Installation},
+describes how to get @command{gawk}, how to compile it
+under Unix, and how to compile and use it on different
+non-Unix systems. It also describes how to report bugs
+in @command{gawk} and where to get three other freely
+available implementations of @command{awk}.
+
+@ref{Notes},
+describes how to disable @command{gawk}'s extensions, as
+well as how to contribute new code to @command{gawk},
+how to write extension libraries, and some possible
+future directions for @command{gawk} development.
+
+@ref{Basic Concepts},
+provides some very cursory background material for those who
+are completely unfamiliar with computer programming.
+Also centralized there is a discussion of some of the issues
+surrounding floating-point numbers.
+
+The
+@ref{Glossary},
+defines most, if not all, the significant terms used
+throughout the book.
+If you find terms that you aren't familiar with, try looking them up here.
+
+@ref{Copying}, and
+@ref{GNU Free Documentation License},
+present the licenses that cover the @command{gawk} source code
+and this @value{DOCUMENT}, respectively.
+
+@node Conventions
+@section Typographical Conventions
+
+@cindex Texinfo
+This @value{DOCUMENT} is written using Texinfo, the GNU documentation
+formatting language.
+A single Texinfo source file is used to produce both the printed and online
+versions of the documentation.
+@ifnotinfo
+Because of this, the typographical conventions
+are slightly different than in other books you may have read.
+@end ifnotinfo
+@ifinfo
+This @value{SECTION} briefly documents the typographical conventions used in Texinfo.
+@end ifinfo
+
+Examples you would type at the command-line are preceded by the common
+shell primary and secondary prompts, @samp{$} and @samp{>}.
+Output from the command is preceded by the glyph ``@print{}''.
+This typically represents the command's standard output.
+Error messages, and other output on the command's standard error, are preceded
+by the glyph ``@error{}''. For example:
+
+@example
+$ echo hi on stdout
+@print{} hi on stdout
+$ echo hello on stderr 1>&2
+@error{} hello on stderr
+@end example
+
+@ifnotinfo
+In the text, command names appear in @code{this font}, while code segments
+appear in the same font and quoted, @samp{like this}. Some things are
+emphasized @emph{like this}, and if a point needs to be made
+strongly, it is done @strong{like this}. The first occurrence of
+a new term is usually its @dfn{definition} and appears in the same
+font as the previous occurrence of ``definition'' in this sentence.
+@value{FN}s are indicated like this: @file{/path/to/ourfile}.
+@end ifnotinfo
+
+Characters that you type at the keyboard look @kbd{like this}. In particular,
+there are special characters called ``control characters.'' These are
+characters that you type by holding down both the @kbd{CONTROL} key and
+another key, at the same time. For example, a @kbd{@value{CTL}-d} is typed
+by first pressing and holding the @kbd{CONTROL} key, next
+pressing the @kbd{d} key and finally releasing both keys.
+
+@c fakenode --- for prepinfo
+@subsubheading Dark Corners
+@cindex Kernighan, Brian
+@quotation
+@i{Dark corners are basically fractal --- no matter how much
+you illuminate, there's always a smaller but darker one.}@*
+Brian Kernighan
+@end quotation
+
+@cindex d.c., See dark corner
+@cindex dark corner
+Until the POSIX standard (and @cite{The Gawk Manual}),
+many features of @command{awk} were either poorly documented or not
+documented at all. Descriptions of such features
+(often called ``dark corners'') are noted in this @value{DOCUMENT} with
+@iftex
+the picture of a flashlight in the margin, as shown here.
+@value{DARKCORNER}
+@end iftex
+@ifnottex
+``(d.c.)''.
+@end ifnottex
+They also appear in the index under the heading ``dark corner.''
+
+As noted by the opening quote, though, any
+coverage of dark corners
+is, by definition, something that is incomplete.
+
+@node Manual History
+@unnumberedsec The GNU Project and This Book
+
+@cindex FSF (Free Software Foundation)
+@cindex Free Software Foundation (FSF)
+@cindex Stallman, Richard
+The Free Software Foundation (FSF) is a nonprofit organization dedicated
+to the production and distribution of freely distributable software.
+It was founded by Richard M.@: Stallman, the author of the original
+Emacs editor. GNU Emacs is the most widely used version of Emacs today.
+
+@cindex GNU Project
+@cindex GPL (General Public License)
+@cindex General Public License, See GPL
+@cindex documentation, online
+The GNU@footnote{GNU stands for ``GNU's not Unix.''}
+Project is an ongoing effort on the part of the Free Software
+Foundation to create a complete, freely distributable, POSIX-compliant
+computing environment.
+The FSF uses the ``GNU General Public License'' (GPL) to ensure that
+their software's
+source code is always available to the end user. A
+copy of the GPL is included
+@ifnotinfo
+in this @value{DOCUMENT}
+@end ifnotinfo
+for your reference
+(@pxref{Copying}).
+The GPL applies to the C language source code for @command{gawk}.
+To find out more about the FSF and the GNU Project online,
+see @uref{http://www.gnu.org, the GNU Project's home page}.
+This @value{DOCUMENT} may also be read from
+@uref{http://www.gnu.org/manual/gawk/, their web site}.
+
+A shell, an editor (Emacs), highly portable optimizing C, C++, and
+Objective-C compilers, a symbolic debugger and dozens of large and
+small utilities (such as @command{gawk}), have all been completed and are
+freely available. The GNU operating
+system kernel (the HURD), has been released but is still in an early
+stage of development.
+
+@cindex Linux
+@cindex GNU/Linux
+@cindex operating systems, BSD-based
+@cindex Alpha (DEC)
+Until the GNU operating system is more fully developed, you should
+consider using GNU/Linux, a freely distributable, Unix-like operating
+system for Intel 80386, DEC Alpha, Sun SPARC, IBM S/390, and other
+systems.@footnote{The terminology ``GNU/Linux'' is explained
+in the @ref{Glossary}.}
+There are
+many books on GNU/Linux. One that is freely available is @cite{Linux
+Installation and Getting Started}, by Matt Welsh.
+Many GNU/Linux distributions are often available in computer stores or
+bundled on CD-ROMs with books about Linux.
+(There are three other freely available, Unix-like operating systems for
+80386 and other systems: NetBSD, FreeBSD, and OpenBSD. All are based on the
+4.4-Lite Berkeley Software Distribution, and they use recent versions
+of @command{gawk} for their versions of @command{awk}.)
+
+@ifnotinfo
+The @value{DOCUMENT} you are reading is actually free---at least, the
+information in it is free to anyone. The machine-readable
+source code for the @value{DOCUMENT} comes with @command{gawk}; anyone
+may take this @value{DOCUMENT} to a copying machine and make as many
+copies as they like. (Take a moment to check the Free Documentation
+License in @ref{GNU Free Documentation License}.)
+
+Although you could just print it out yourself, bound books are much
+easier to read and use. Furthermore,
+the proceeds from sales of this book go back to the FSF
+to help fund development of more free software.
+@end ifnotinfo
+
+@ignore
+@cindex Close, Diane
+The @value{DOCUMENT} itself has gone through several previous,
+preliminary editions.
+Paul Rubin wrote the very first draft of @cite{The GAWK Manual};
+it was around 40 pages in size.
+Diane Close and Richard Stallman improved it, yielding the
+version which I started working with in the fall of 1988.
+It was around 90 pages long and barely described the original, ``old''
+version of @command{awk}. After substantial revision, the first version of
+the @cite{The GAWK Manual} to be released was Edition 0.11 Beta in
+October of 1989. The manual then underwent more substantial revision
+for Edition 0.13 of December 1991.
+David Trueman, Pat Rankin and Michal Jaegermann contributed sections
+of the manual for Edition 0.13.
+That edition was published by the
+FSF as a bound book early in 1992. Since then there were several
+minor revisions, notably Edition 0.14 of November 1992 that was published
+by the FSF in January of 1993 and Edition 0.16 of August 1993.
+
+Edition 1.0 of @cite{GAWK: The GNU Awk User's Guide} represented a significant re-working
+of @cite{The GAWK Manual}, with much additional material.
+The FSF and I agreed that I was now the primary author.
+@c I also felt that the manual needed a more descriptive title.
+
+In January 1996, SSC published Edition 1.0 under the title @cite{Effective AWK Programming}.
+In February 1997, they published Edition 1.0.3 which had minor changes
+as a ``second edition.''
+In 1999, the FSF published this same version as Edition 2
+of @cite{GAWK: The GNU Awk User's Guide}.
+
+Edition @value{EDITION} maintains the basic structure of Edition 1.0,
+but with significant additional material, reflecting the host of new features
+in @command{gawk} @value{PVERSION} @value{VERSION}.
+Of particular note is
+@ref{Array Sorting},
+@ref{Bitwise Functions},
+@ref{Internationalization},
+@ref{Advanced Features},
+and
+@ref{Dynamic Extensions}.
+@end ignore
+
+@cindex Close, Diane
+The @value{DOCUMENT} itself has gone through a number of previous editions.
+Paul Rubin wrote the very first draft of @cite{The GAWK Manual};
+it was around 40 pages in size.
+Diane Close and Richard Stallman improved it, yielding a
+version that was
+around 90 pages long and barely described the original, ``old''
+version of @command{awk}.
+
+I started working with that version in the fall of 1988.
+As work on it progressed,
+the FSF published several preliminary versions (numbered 0.@var{x}).
+In 1996, Edition 1.0 was released with @command{gawk} 3.0.0.
+The FSF published the first two editions under
+the title @cite{The GNU Awk User's Guide}.
+
+This edition maintains the basic structure of Edition 1.0,
+but with significant additional material, reflecting the host of new features
+in @command{gawk} @value{PVERSION} @value{VERSION}.
+Of particular note is
+@ref{Array Sorting},
+as well as
+@ref{Bitwise Functions},
+@ref{Internationalization},
+and also
+@ref{Advanced Features},
+and
+@ref{Dynamic Extensions}.
+
+@cite{@value{TITLE}} will undoubtedly continue to evolve.
+An electronic version
+comes with the @command{gawk} distribution from the FSF.
+If you find an error in this @value{DOCUMENT}, please report it!
+@xref{Bugs}, for information on submitting
+problem reports electronically, or write to me in care of the publisher.
+
+@node How To Contribute
+@unnumberedsec How to Contribute
+
+As the maintainer of GNU @command{awk},
+I am starting a collection of publicly available @command{awk}
+programs.
+For more information,
+see @uref{ftp://ftp.freefriends.org/arnold/Awkstuff}.
+If you have written an interesting @command{awk} program, or have written a
+@command{gawk} extension that you would like to
+share with the rest of the world, please contact me (@email{arnold@@skeeve.com}).
+Making things available on the Internet helps keep the
+@command{gawk} distribution down to manageable size.
+
+@node Acknowledgments
+@unnumberedsec Acknowledgments
+
+The initial draft of @cite{The GAWK Manual} had the following acknowledgments:
+
+@quotation
+Many people need to be thanked for their assistance in producing this
+manual. Jay Fenlason contributed many ideas and sample programs. Richard
+Mlynarik and Robert Chassell gave helpful comments on drafts of this
+manual. The paper @cite{A Supplemental Document for @command{awk}} by John W.@:
+Pierce of the Chemistry Department at UC San Diego, pinpointed several
+issues relevant both to @command{awk} implementation and to this manual, that
+would otherwise have escaped us.
+@end quotation
+
+@cindex Stallman, Richard
+I would like to acknowledge Richard M.@: Stallman, for his vision of a
+better world and for his courage in founding the FSF and starting the
+GNU Project.
+
+The following people (in alphabetical order)
+provided helpful comments on various
+versions of this book, up to and including this edition.
+Rick Adams,
+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,
+and
+Chuck Toporek.
+
+@cindex Berry, Karl
+@cindex Chassell, Robert J.@:
+@c @cindex Texinfo
+Robert J.@: Chassell provided much valuable advice on
+the use of Texinfo.
+He also deserves special thanks for
+convincing me @emph{not} to title this @value{DOCUMENT}
+@cite{How To Gawk Politely}.
+Karl Berry helped significantly with the @TeX{} part of Texinfo.
+
+@cindex Hartholz, Marshall
+@cindex Hartholz, Elaine
+@cindex Schreiber, Bert
+@cindex Schreiber, Rita
+I would like to thank Marshall and Elaine Hartholz of Seattle and
+Dr.@: Bert and Rita Schreiber of Detroit for large amounts of quiet vacation
+time in their homes, which allowed me to make significant progress on
+this @value{DOCUMENT} and on @command{gawk} itself.
+
+@cindex Hughes, Phil
+Phil Hughes of SSC
+contributed in a very important way by loaning me his laptop GNU/Linux
+system, not once, but twice, which allowed me to do a lot of work while
+away from home.
+
+@cindex Trueman, David
+David Trueman deserves special credit; he has done a yeoman job
+of evolving @command{gawk} so that it performs well and without bugs.
+Although he is no longer involved with @command{gawk},
+working with him on this project was a significant pleasure.
+
+@cindex Drepper, Ulrich
+@cindex GNITS mailing list
+@cindex mailing list, GNITS
+The intrepid members of the GNITS mailing list, and most notably Ulrich
+Drepper, provided invaluable help and feedback for the design of the
+internationalization features.
+
+@cindex Beebe, Nelson
+@cindex Brown, Martin
+@cindex Buening, Andreas
+@cindex Deifik, Scott
+@cindex Hankerson, Darrel
+@cindex Hasegawa, Isamu
+@cindex Jaegermann, Michal
+@cindex Kahrs, J@"urgen
+@cindex Rankin, Pat
+@cindex Rommel, Kai Uwe
+@cindex Zaretskii, Eli
+Nelson Beebe,
+Martin Brown,
+Andreas Buening,
+Scott Deifik,
+Darrel Hankerson,
+Isamu Hasegawa,
+Michal Jaegermann,
+J@"urgen Kahrs,
+Pat Rankin,
+Kai Uwe Rommel,
+and Eli Zaretskii
+(in alphabetical order)
+make up the
+@command{gawk} ``crack portability team.'' Without their hard work and
+help, @command{gawk} would not be nearly the fine program it is today. It
+has been and continues to be a pleasure working with this team of fine
+people.
+
+@cindex Kernighan, Brian
+David and I would like to thank Brian Kernighan of Bell Laboratories for
+invaluable assistance during the testing and debugging of @command{gawk}, and for
+help in clarifying numerous points about the language. We could not have
+done nearly as good a job on either @command{gawk} or its documentation without
+his help.
+
+Chuck Toporek, Mary Sheehan, and Claire Coutier of O'Reilly & Associates contributed
+significant editorial help for this @value{DOCUMENT} for the
+3.1 release of @command{gawk}.
+
+@cindex Robbins, Miriam
+@cindex Robbins, Jean
+@cindex Robbins, Harry
+@cindex G-d
+I must thank my wonderful wife, Miriam, for her patience through
+the many versions of this project, for her proofreading,
+and for sharing me with the computer.
+I would like to thank my parents for their love, and for the grace with
+which they raised and educated me.
+Finally, I also must acknowledge my gratitude to G-d, for the many opportunities
+He has sent my way, as well as for the gifts He has given me with which to
+take advantage of those opportunities.
+@sp 2
+@noindent
+Arnold Robbins @*
+Nof Ayalon @*
+ISRAEL @*
+March, 2001
+
+@ignore
+@c Try this
+@iftex
+@page
+@headings off
+@majorheading I@ @ @ @ The @command{awk} Language and @command{gawk}
+Part I describes the @command{awk} language and @command{gawk} program in detail.
+It starts with the basics, and continues through all of the features of @command{awk}
+and @command{gawk}. It contains the following chapters:
+
+@itemize @bullet
+@item
+@ref{Getting Started}.
+
+@item
+@ref{Regexp}.
+
+@item
+@ref{Reading Files}.
+
+@item
+@ref{Printing}.
+
+@item
+@ref{Expressions}.
+
+@item
+@ref{Patterns and Actions}.
+
+@item
+@ref{Arrays}.
+
+@item
+@ref{Functions}.
+
+@item
+@ref{Internationalization}.
+
+@item
+@ref{Advanced Features}.
+
+@item
+@ref{Invoking Gawk}.
+@end itemize
+
+@page
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+@end ignore
+
+@node Getting Started
+@chapter Getting Started with @command{awk}
+@c @cindex script, definition of
+@c @cindex rule, definition of
+@c @cindex program, definition of
+@c @cindex basic function of @command{awk}
+@cindex @command{awk}, function of
+
+The basic function of @command{awk} is to search files for lines (or other
+units of text) that contain certain patterns. When a line matches one
+of the patterns, @command{awk} performs specified actions on that line.
+@command{awk} keeps processing input lines in this way until it reaches
+the end of the input files.
+
+@cindex @command{awk}, uses for
+@cindex programming languages@comma{} data-driven vs. procedural
+@cindex @command{awk} programs
+Programs in @command{awk} are different from programs in most other languages,
+because @command{awk} programs are @dfn{data-driven}; that is, you describe
+the data you want to work with and then what to do when you find it.
+Most other languages are @dfn{procedural}; you have to describe, in great
+detail, every step the program is to take. When working with procedural
+languages, it is usually much
+harder to clearly describe the data your program will process.
+For this reason, @command{awk} programs are often refreshingly easy to
+read and write.
+
+@cindex program, definition of
+@cindex rule, definition of
+When you run @command{awk}, you specify an @command{awk} @dfn{program} that
+tells @command{awk} what to do. The program consists of a series of
+@dfn{rules}. (It may also contain @dfn{function definitions},
+an advanced feature that we will ignore for now.
+@xref{User-defined}.) Each rule specifies one
+pattern to search for and one action to perform
+upon finding the pattern.
+
+Syntactically, a rule consists of a pattern followed by an action. The
+action is enclosed in curly braces to separate it from the pattern.
+Newlines usually separate rules. Therefore, an @command{awk}
+program looks like this:
+
+@example
+@var{pattern} @{ @var{action} @}
+@var{pattern} @{ @var{action} @}
+@dots{}
+@end example
+
+@menu
+* Running gawk:: How to run @command{gawk} programs; includes
+ command-line syntax.
+* Sample Data Files:: Sample data files for use in the @command{awk}
+ programs illustrated in this @value{DOCUMENT}.
+* Very Simple:: A very simple example.
+* Two Rules:: A less simple one-line example using two
+ rules.
+* More Complex:: A more complex example.
+* Statements/Lines:: Subdividing or combining statements into
+ lines.
+* Other Features:: Other Features of @command{awk}.
+* When:: When to use @command{gawk} and when to use
+ other things.
+@end menu
+
+@node Running gawk
+@section How to Run @command{awk} Programs
+
+@cindex @command{awk} programs, running
+There are several ways to run an @command{awk} program. If the program is
+short, it is easiest to include it in the command that runs @command{awk},
+like this:
+
+@example
+awk '@var{program}' @var{input-file1} @var{input-file2} @dots{}
+@end example
+
+@cindex command line, formats
+When the program is long, it is usually more convenient to put it in a file
+and run it with a command like this:
+
+@example
+awk -f @var{program-file} @var{input-file1} @var{input-file2} @dots{}
+@end example
+
+This @value{SECTION} discusses both mechanisms, along with several
+variations of each.
+
+@menu
+* One-shot:: Running a short throwaway @command{awk}
+ program.
+* Read Terminal:: Using no input files (input from terminal
+ instead).
+* Long:: Putting permanent @command{awk} programs in
+ files.
+* Executable Scripts:: Making self-contained @command{awk} programs.
+* Comments:: Adding documentation to @command{gawk}
+ programs.
+* Quoting:: More discussion of shell quoting issues.
+@end menu
+
+@node One-shot
+@subsection One-Shot Throwaway @command{awk} Programs
+
+Once you are familiar with @command{awk}, you will often type in simple
+programs the moment you want to use them. Then you can write the
+program as the first argument of the @command{awk} command, like this:
+
+@example
+awk '@var{program}' @var{input-file1} @var{input-file2} @dots{}
+@end example
+
+@noindent
+where @var{program} consists of a series of @var{patterns} and
+@var{actions}, as described earlier.
+
+@cindex single quote (@code{'})
+@cindex @code{'} (single quote)
+This command format instructs the @dfn{shell}, or command interpreter,
+to start @command{awk} and use the @var{program} to process records in the
+input file(s). There are single quotes around @var{program} so
+the shell won't interpret any @command{awk} characters as special shell
+characters. The quotes also cause the shell to treat all of @var{program} as
+a single argument for @command{awk}, and allow @var{program} to be more
+than one line long.
+
+@cindex shells, scripts
+@cindex @command{awk} programs, running, from shell scripts
+This format is also useful for running short or medium-sized @command{awk}
+programs from shell scripts, because it avoids the need for a separate
+file for the @command{awk} program. A self-contained shell script is more
+reliable because there are no other files to misplace.
+
+@ref{Very Simple},
+@ifnotinfo
+later in this @value{CHAPTER},
+@end ifnotinfo
+presents several short,
+self-contained programs.
+
+@c Removed for gawk 3.1, doesn't really add anything here.
+@ignore
+As an interesting side point, the command
+
+@example
+awk '/foo/' @var{files} @dots{}
+@end example
+
+@noindent
+is essentially the same as
+
+@cindex @command{egrep} utility
+@example
+egrep foo @var{files} @dots{}
+@end example
+@end ignore
+
+@node Read Terminal
+@subsection Running @command{awk} Without Input Files
+
+@cindex standard input
+@cindex input, standard
+@cindex input files, running @command{awk} without
+You can also run @command{awk} without any input files. If you type the
+following command line:
+
+@example
+awk '@var{program}'
+@end example
+
+@noindent
+@command{awk} applies the @var{program} to the @dfn{standard input},
+which usually means whatever you type on the terminal. This continues
+until you indicate end-of-file by typing @kbd{@value{CTL}-d}.
+(On other operating systems, the end-of-file character may be different.
+For example, on OS/2 and MS-DOS, it is @kbd{@value{CTL}-z}.)
+
+@cindex files, input, See input files
+@cindex input files, running @command{awk} without
+@cindex @command{awk} programs, running, without input files
+As an example, the following program prints a friendly piece of advice
+(from Douglas Adams's @cite{The Hitchhiker's Guide to the Galaxy}),
+to keep you from worrying about the complexities of computer programming
+(@code{BEGIN} is a feature we haven't discussed yet):
+
+@example
+$ awk "BEGIN @{ print \"Don't Panic!\" @}"
+@print{} Don't Panic!
+@end example
+
+@cindex quoting
+@cindex double quote (@code{"})
+@cindex @code{"} (double quote)
+@cindex @code{\} (backslash)
+@cindex backslash (@code{\})
+This program does not read any input. The @samp{\} before each of the
+inner double quotes is necessary because of the shell's quoting
+rules---in particular because it mixes both single quotes and
+double quotes.@footnote{Although we generally recommend the use of single
+quotes around the program text, double quotes are needed here in order to
+put the single quote into the message.}
+
+This next simple @command{awk} program
+emulates the @command{cat} utility; it copies whatever you type on the
+keyboard to its standard output (why this works is explained shortly).
+
+@example
+$ awk '@{ print @}'
+Now is the time for all good men
+@print{} Now is the time for all good men
+to come to the aid of their country.
+@print{} to come to the aid of their country.
+Four score and seven years ago, ...
+@print{} Four score and seven years ago, ...
+What, me worry?
+@print{} What, me worry?
+@kbd{@value{CTL}-d}
+@end example
+
+@node Long
+@subsection Running Long Programs
+
+@cindex @command{awk} programs, running
+@cindex @command{awk} programs, lengthy
+@cindex files, @command{awk} programs in
+Sometimes your @command{awk} programs can be very long. In this case, it is
+more convenient to put the program into a separate file. In order to tell
+@command{awk} to use that file for its program, you type:
+
+@example
+awk -f @var{source-file} @var{input-file1} @var{input-file2} @dots{}
+@end example
+
+@cindex @code{-f} option
+@cindex command line, options
+@cindex options, command-line
+The @option{-f} instructs the @command{awk} utility to get the @command{awk} program
+from the file @var{source-file}. Any @value{FN} can be used for
+@var{source-file}. For example, you could put the program:
+
+@example
+BEGIN @{ print "Don't Panic!" @}
+@end example
+
+@noindent
+into the file @file{advice}. Then this command:
+
+@example
+awk -f advice
+@end example
+
+@noindent
+does the same thing as this one:
+
+@example
+awk "BEGIN @{ print \"Don't Panic!\" @}"
+@end example
+
+@cindex quoting
+@noindent
+This was explained earlier
+(@pxref{Read Terminal}).
+Note that you don't usually need single quotes around the @value{FN} that you
+specify with @option{-f}, because most @value{FN}s don't contain any of the shell's
+special characters. Notice that in @file{advice}, the @command{awk}
+program did not have single quotes around it. The quotes are only needed
+for programs that are provided on the @command{awk} command line.
+
+@c STARTOFRANGE sq1x
+@cindex single quote (@code{'})
+@c STARTOFRANGE qs2x
+@cindex @code{'} (single quote)
+If you want to identify your @command{awk} program files clearly as such,
+you can add the extension @file{.awk} to the @value{FN}. This doesn't
+affect the execution of the @command{awk} program but it does make
+``housekeeping'' easier.
+
+@node Executable Scripts
+@subsection Executable @command{awk} Programs
+@cindex @command{awk} programs
+@cindex @code{#} (number sign), @code{#!} (executable scripts)
+@cindex number sign (@code{#}), @code{#!} (executable scripts)
+@cindex Unix, @command{awk} scripts and
+@cindex @code{#} (number sign), @code{#!} (executable scripts), portability issues with
+@cindex number sign (@code{#}), @code{#!} (executable scripts), portability issues with
+
+Once you have learned @command{awk}, you may want to write self-contained
+@command{awk} scripts, using the @samp{#!} script mechanism. You can do
+this on many Unix systems@footnote{The @samp{#!} mechanism works on
+Linux systems,
+systems derived from the 4.4-Lite Berkeley Software Distribution,
+and most commercial Unix systems.} as well as on the GNU system.
+For example, you could update the file @file{advice} to look like this:
+
+@example
+#! /bin/awk -f
+
+BEGIN @{ print "Don't Panic!" @}
+@end example
+
+@noindent
+After making this file executable (with the @command{chmod} utility),
+simply type @samp{advice}
+at the shell and the system arranges to run @command{awk}@footnote{The
+line beginning with @samp{#!} lists the full @value{FN} of an interpreter
+to run and an optional initial command-line argument to pass to that
+interpreter. The operating system then runs the interpreter with the given
+argument and the full argument list of the executed program. The first argument
+in the list is the full @value{FN} of the @command{awk} program. The rest of the
+argument list contains either options to @command{awk}, or @value{DF}s,
+or both.} as if you had
+typed @samp{awk -f advice}:
+
+@example
+$ chmod +x advice
+$ advice
+@print{} Don't Panic!
+@end example
+
+@noindent
+(We assume you have the current directory in your shell's search
+path variable (typically @code{$PATH}). If not, you may need
+to type @samp{./advice} at the shell.)
+
+Self-contained @command{awk} scripts are useful when you want to write a
+program that users can invoke without their having to know that the program is
+written in @command{awk}.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Portability Issues with @samp{#!}
+@cindex portability, @code{#!} (executable scripts)
+
+Some systems limit the length of the interpreter name to 32 characters.
+Often, this can be dealt with by using a symbolic link.
+
+You should not put more than one argument on the @samp{#!}
+line after the path to @command{awk}. It does not work. The operating system
+treats the rest of the line as a single argument and passes it to @command{awk}.
+Doing this leads to confusing behavior---most likely a usage diagnostic
+of some sort from @command{awk}.
+
+@cindex @code{ARGC}/@code{ARGV} variables, portability and
+@cindex portability, @code{ARGV} variable
+Finally,
+the value of @code{ARGV[0]}
+(@pxref{Built-in Variables})
+varies depending upon your operating system.
+Some systems put @samp{awk} there, some put the full pathname
+of @command{awk} (such as @file{/bin/awk}), and some put the name
+of your script (@samp{advice}). Don't rely on the value of @code{ARGV[0]}
+to provide your script name.
+
+@node Comments
+@subsection Comments in @command{awk} Programs
+@cindex @code{#} (number sign), commenting
+@cindex number sign (@code{#}), commenting
+@cindex commenting
+@cindex @command{awk} programs, documenting
+
+A @dfn{comment} is some text that is included in a program for the sake
+of human readers; it is not really an executable part of the program. Comments
+can explain what the program does and how it works. Nearly all
+programming languages have provisions for comments, as programs are
+typically hard to understand without them.
+
+In the @command{awk} language, a comment starts with the sharp sign
+character (@samp{#}) and continues to the end of the line.
+The @samp{#} does not have to be the first character on the line. The
+@command{awk} language ignores the rest of a line following a sharp sign.
+For example, we could have put the following into @file{advice}:
+
+@example
+# This program prints a nice friendly message. It helps
+# keep novice users from being afraid of the computer.
+BEGIN @{ print "Don't Panic!" @}
+@end example
+
+You can put comment lines into keyboard-composed throwaway @command{awk}
+programs, but this usually isn't very useful; the purpose of a
+comment is to help you or another person understand the program
+when reading it at a later time.
+
+@cindex quoting
+@cindex single quote (@code{'}), vs. apostrophe
+@cindex @code{'} (single quote), vs. apostrophe
+@strong{Caution:} As mentioned in
+@ref{One-shot},
+you can enclose small to medium programs in single quotes, in order to keep
+your shell scripts self-contained. When doing so, @emph{don't} put
+an apostrophe (i.e., a single quote) into a comment (or anywhere else
+in your program). The shell interprets the quote as the closing
+quote for the entire program. As a result, usually the shell
+prints a message about mismatched quotes, and if @command{awk} actually
+runs, it will probably print strange messages about syntax errors.
+For example, look at the following:
+
+@example
+$ awk '@{ print "hello" @} # let's be cute'
+>
+@end example
+
+The shell sees that the first two quotes match, and that
+a new quoted object begins at the end of the command line.
+It therefore prompts with the secondary prompt, waiting for more input.
+With Unix @command{awk}, closing the quoted string produces this result:
+
+@example
+$ awk '@{ print "hello" @} # let's be cute'
+> '
+@error{} awk: can't open file be
+@error{} source line number 1
+@end example
+
+@cindex @code{\} (backslash)
+@cindex backslash (@code{\})
+Putting a backslash before the single quote in @samp{let's} wouldn't help,
+since backslashes are not special inside single quotes.
+The next @value{SUBSECTION} describes the shell's quoting rules.
+
+@node Quoting
+@subsection Shell-Quoting Issues
+@cindex quoting, rules for
+
+For short to medium length @command{awk} programs, it is most convenient
+to enter the program on the @command{awk} command line.
+This is best done by enclosing the entire program in single quotes.
+This is true whether you are entering the program interactively at
+the shell prompt, or writing it as part of a larger shell script:
+
+@example
+awk '@var{program text}' @var{input-file1} @var{input-file2} @dots{}
+@end example
+
+@cindex shells, quoting, rules for
+@cindex Bourne shell, quoting rules for
+Once you are working with the shell, it is helpful to have a basic
+knowledge of shell quoting rules. The following rules apply only to
+POSIX-compliant, Bourne-style shells (such as @command{bash}, the GNU Bourne-Again
+Shell). If you use @command{csh}, you're on your own.
+
+@itemize @bullet
+@item
+Quoted items can be concatenated with nonquoted items as well as with other
+quoted items. The shell turns everything into one argument for
+the command.
+
+@item
+Preceding any single character with a backslash (@samp{\}) quotes
+that character. The shell removes the backslash and passes the quoted
+character on to the command.
+
+@item
+@cindex @code{\} (backslash)
+@cindex backslash (@code{\})
+@cindex single quote (@code{'})
+@cindex @code{'} (single quote)
+Single quotes protect everything between the opening and closing quotes.
+The shell does no interpretation of the quoted text, passing it on verbatim
+to the command.
+It is @emph{impossible} to embed a single quote inside single-quoted text.
+Refer back to
+@ref{Comments},
+for an example of what happens if you try.
+
+@item
+@cindex double quote (@code{"})
+@cindex @code{"} (double quote)
+Double quotes protect most things between the opening and closing quotes.
+The shell does at least variable and command substitution on the quoted text.
+Different shells may do additional kinds of processing on double-quoted text.
+
+Since certain characters within double-quoted text are processed by the shell,
+they must be @dfn{escaped} within the text. Of note are the characters
+@samp{$}, @samp{`}, @samp{\}, and @samp{"}, all of which must be preceded by
+a backslash within double-quoted text if they are to be passed on literally
+to the program. (The leading backslash is stripped first.)
+Thus, the example seen
+@ifnotinfo
+previously
+@end ifnotinfo
+in @ref{Read Terminal},
+is applicable:
+
+@example
+$ awk "BEGIN @{ print \"Don't Panic!\" @}"
+@print{} Don't Panic!
+@end example
+
+@cindex single quote (@code{'}), with double quotes
+@cindex @code{'} (single quote), with double quotes
+Note that the single quote is not special within double quotes.
+
+@item
+Null strings are removed when they occur as part of a non-null
+command-line argument, while explicit non-null objects are kept.
+For example, to specify that the field separator @code{FS} should
+be set to the null string, use:
+
+@example
+awk -F "" '@var{program}' @var{files} # correct
+@end example
+
+@noindent
+@cindex null strings, quoting and
+Don't use this:
+
+@example
+awk -F"" '@var{program}' @var{files} # wrong!
+@end example
+
+@noindent
+In the second case, @command{awk} will attempt to use the text of the program
+as the value of @code{FS}, and the first @value{FN} as the text of the program!
+This results in syntax errors at best, and confusing behavior at worst.
+@end itemize
+
+@cindex quoting, tricks for
+Mixing single and double quotes is difficult. You have to resort
+to shell quoting tricks, like this:
+
+@example
+$ awk 'BEGIN @{ print "Here is a single quote <'"'"'>" @}'
+@print{} Here is a single quote <'>
+@end example
+
+@noindent
+This program consists of three concatenated quoted strings. The first and the
+third are single-quoted, the second is double-quoted.
+
+This can be ``simplified'' to:
+
+@example
+$ awk 'BEGIN @{ print "Here is a single quote <'\''>" @}'
+@print{} Here is a single quote <'>
+@end example
+
+@noindent
+Judge for yourself which of these two is the more readable.
+
+Another option is to use double quotes, escaping the embedded, @command{awk}-level
+double quotes:
+
+@example
+$ awk "BEGIN @{ print \"Here is a single quote <'>\" @}"
+@print{} Here is a single quote <'>
+@end example
+
+@noindent
+@c ENDOFRANGE sq1x
+@c ENDOFRANGE qs2x
+This option is also painful, because double quotes, backslashes, and dollar signs
+are very common in @command{awk} programs.
+
+A third option is to use the octal escape sequence equivalents for the
+single- and double-quote characters, like so:
+
+@example
+$ awk 'BEGIN @{ print "Here is a single quote <\47>" @}'
+@print{} Here is a single quote <'>
+$ awk 'BEGIN @{ print "Here is a double quote <\42>" @}'
+@print{} Here is a double quote <">
+@end example
+
+@noindent
+This works nicely, except that you should comment clearly what the
+escapes mean.
+
+A fourth option is to use command-line variable assignment, like this:
+
+@example
+$ awk -v sq="'" 'BEGIN @{ print "Here is a single quote <" sq ">" @}'
+@print{} Here is a single quote <'>
+@end example
+
+If you really need both single and double quotes in your @command{awk}
+program, it is probably best to move it into a separate file, where
+the shell won't be part of the picture, and you can say what you mean.
+
+@node Sample Data Files
+@section @value{DDF}s for the Examples
+@c For gawk >= 3.2, update these data files. No-one has such slow modems!
+
+@cindex input files, examples
+@cindex @code{BBS-list} file
+Many of the examples in this @value{DOCUMENT} take their input from two sample
+@value{DF}s. The first, @file{BBS-list}, represents a list of
+computer bulletin board systems together with information about those systems.
+The second @value{DF}, called @file{inventory-shipped}, contains
+information about monthly shipments. In both files,
+each line is considered to be one @dfn{record}.
+
+In the @value{DF} @file{BBS-list}, each record contains the name of a computer
+bulletin board, its phone number, the board's baud rate(s), and a code for
+the number of hours it is operational. An @samp{A} in the last column
+means the board operates 24 hours a day. A @samp{B} in the last
+column means the board only operates on evening and weekend hours.
+A @samp{C} means the board operates only on weekends:
+
+@c 2e: Update the baud rates to reflect today's faster modems
+@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/BBS-list
+aardvark 555-5553 1200/300 B
+alpo-net 555-3412 2400/1200/300 A
+barfly 555-7685 1200/300 A
+bites 555-1675 2400/1200/300 A
+camelot 555-0542 300 C
+core 555-2912 1200/300 C
+fooey 555-1234 2400/1200/300 B
+foot 555-6699 1200/300 B
+macfoo 555-6480 1200/300 A
+sdace 555-3430 2400/1200/300 A
+sabafoo 555-2127 1200/300 C
+@c endfile
+@end example
+
+@cindex @code{inventory-shipped} file
+The @value{DF} @file{inventory-shipped} represents
+information about shipments during the year.
+Each record contains the month, the number
+of green crates shipped, the number of red boxes shipped, the number of
+orange bags shipped, and the number of blue packages shipped,
+respectively. There are 16 entries, covering the 12 months of last year
+and the first four months of the current year.
+
+@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
+
+@ifinfo
+If you are reading this in GNU Emacs using Info, you can copy the regions
+of text showing these sample files into your own test files. This way you
+can try out the examples shown in the remainder of this document. You do
+this by using the command @kbd{M-x write-region} to copy text from the Info
+file into a file for use with @command{awk}
+(@xref{Misc File Ops, , Miscellaneous File Operations, emacs, GNU Emacs Manual},
+for more information). Using this information, create your own
+@file{BBS-list} and @file{inventory-shipped} files and practice what you
+learn in this @value{DOCUMENT}.
+
+@cindex Texinfo
+If you are using the stand-alone version of Info,
+see @ref{Extract Program},
+for an @command{awk} program that extracts these @value{DF}s from
+@file{gawk.texi}, the Texinfo source file for this Info file.
+@end ifinfo
+
+@node Very Simple
+@section Some Simple Examples
+
+The following command runs a simple @command{awk} program that searches the
+input file @file{BBS-list} for the character string @samp{foo} (a
+grouping of characters is usually called a @dfn{string};
+the term @dfn{string} is based on similar usage in English, such
+as ``a string of pearls,'' or ``a string of cars in a train''):
+
+@example
+awk '/foo/ @{ print $0 @}' BBS-list
+@end example
+
+@noindent
+When lines containing @samp{foo} are found, they are printed because
+@w{@samp{print $0}} means print the current line. (Just @samp{print} by
+itself means the same thing, so we could have written that
+instead.)
+
+You will notice that slashes (@samp{/}) surround the string @samp{foo}
+in the @command{awk} program. The slashes indicate that @samp{foo}
+is the pattern to search for. This type of pattern is called a
+@dfn{regular expression}, which is covered in more detail later
+(@pxref{Regexp}).
+The pattern is allowed to match parts of words.
+There are
+single quotes around the @command{awk} program so that the shell won't
+interpret any of it as special shell characters.
+
+Here is what this program prints:
+
+@example
+$ awk '/foo/ @{ print $0 @}' BBS-list
+@print{} fooey 555-1234 2400/1200/300 B
+@print{} foot 555-6699 1200/300 B
+@print{} macfoo 555-6480 1200/300 A
+@print{} sabafoo 555-2127 1200/300 C
+@end example
+
+@cindex actions, default
+@cindex patterns, default
+In an @command{awk} rule, either the pattern or the action can be omitted,
+but not both. If the pattern is omitted, then the action is performed
+for @emph{every} input line. If the action is omitted, the default
+action is to print all lines that match the pattern.
+
+@cindex actions, empty
+Thus, we could leave out the action (the @code{print} statement and the curly
+braces) in the previous example and the result would be the same: all
+lines matching the pattern @samp{foo} are printed. By comparison,
+omitting the @code{print} statement but retaining the curly braces makes an
+empty action that does nothing (i.e., no lines are printed).
+
+@cindex @command{awk} programs, one-line examples
+Many practical @command{awk} programs are just a line or two. Following is a
+collection of useful, short programs to get you started. Some of these
+programs contain constructs that haven't been covered yet. (The description
+of the program will give you a good idea of what is going on, but please
+read the rest of the @value{DOCUMENT} to become an @command{awk} expert!)
+Most of the examples use a @value{DF} named @file{data}. This is just a
+placeholder; if you use these programs yourself, substitute
+your own @value{FN}s for @file{data}.
+For future reference, note that there is often more than
+one way to do things in @command{awk}. At some point, you may want
+to look back at these examples and see if
+you can come up with different ways to do the same things shown here:
+
+@itemize @bullet
+@item
+Print the length of the longest input line:
+
+@example
+awk '@{ if (length($0) > max) max = length($0) @}
+ END @{ print max @}' data
+@end example
+
+@item
+Print every line that is longer than 80 characters:
+
+@example
+awk 'length($0) > 80' data
+@end example
+
+The sole rule has a relational expression as its pattern and it has no
+action---so the default action, printing the record, is used.
+
+@cindex @command{expand} utility
+@item
+Print the length of the longest line in @file{data}:
+
+@example
+expand data | awk '@{ if (x < length()) x = length() @}
+ END @{ print "maximum line length is " x @}'
+@end example
+
+The input is processed by the @command{expand} utility to change tabs
+into spaces, so the widths compared are actually the right-margin columns.
+
+@item
+Print every line that has at least one field:
+
+@example
+awk 'NF > 0' data
+@end example
+
+This is an easy way to delete blank lines from a file (or rather, to
+create a new file similar to the old file but from which the blank lines
+have been removed).
+
+@item
+Print seven random numbers from 0 to 100, inclusive:
+
+@example
+awk 'BEGIN @{ for (i = 1; i <= 7; i++)
+ print int(101 * rand()) @}'
+@end example
+
+@item
+Print the total number of bytes used by @var{files}:
+
+@example
+ls -l @var{files} | awk '@{ x += $5 @}
+ END @{ print "total bytes: " x @}'
+@end example
+
+@item
+Print the total number of kilobytes used by @var{files}:
+
+@c Don't use \ continuation, not discussed yet
+@example
+ls -l @var{files} | awk '@{ x += $5 @}
+ END @{ print "total K-bytes: " (x + 1023)/1024 @}'
+@end example
+
+@item
+Print a sorted list of the login names of all users:
+
+@example
+awk -F: '@{ print $1 @}' /etc/passwd | sort
+@end example
+
+@item
+Count the lines in a file:
+
+@example
+awk 'END @{ print NR @}' data
+@end example
+
+@item
+Print the even-numbered lines in the @value{DF}:
+
+@example
+awk 'NR % 2 == 0' data
+@end example
+
+If you use the expression @samp{NR % 2 == 1} instead,
+the program would print the odd-numbered lines.
+@end itemize
+
+@node Two Rules
+@section An Example with Two Rules
+@cindex @command{awk} programs
+
+The @command{awk} utility reads the input files one line at a
+time. For each line, @command{awk} tries the patterns of each of the rules.
+If several patterns match, then several actions are run in the order in
+which they appear in the @command{awk} program. If no patterns match, then
+no actions are run.
+
+After processing all the rules that match the line (and perhaps there are none),
+@command{awk} reads the next line. (However,
+@pxref{Next Statement},
+and also @pxref{Nextfile Statement}).
+This continues until the program reaches the end of the file.
+For example, the following @command{awk} program contains two rules:
+
+@example
+/12/ @{ print $0 @}
+/21/ @{ print $0 @}
+@end example
+
+@noindent
+The first rule has the string @samp{12} as the
+pattern and @samp{print $0} as the action. The second rule has the
+string @samp{21} as the pattern and also has @samp{print $0} as the
+action. Each rule's action is enclosed in its own pair of braces.
+
+This program prints every line that contains the string
+@samp{12} @emph{or} the string @samp{21}. If a line contains both
+strings, it is printed twice, once by each rule.
+
+This is what happens if we run this program on our two sample @value{DF}s,
+@file{BBS-list} and @file{inventory-shipped}:
+
+@example
+$ awk '/12/ @{ print $0 @}
+> /21/ @{ print $0 @}' BBS-list inventory-shipped
+@print{} aardvark 555-5553 1200/300 B
+@print{} alpo-net 555-3412 2400/1200/300 A
+@print{} barfly 555-7685 1200/300 A
+@print{} bites 555-1675 2400/1200/300 A
+@print{} core 555-2912 1200/300 C
+@print{} fooey 555-1234 2400/1200/300 B
+@print{} foot 555-6699 1200/300 B
+@print{} macfoo 555-6480 1200/300 A
+@print{} sdace 555-3430 2400/1200/300 A
+@print{} sabafoo 555-2127 1200/300 C
+@print{} sabafoo 555-2127 1200/300 C
+@print{} Jan 21 36 64 620
+@print{} Apr 21 70 74 514
+@end example
+
+@noindent
+Note how the line beginning with @samp{sabafoo}
+in @file{BBS-list} was printed twice, once for each rule.
+
+@node More Complex
+@section A More Complex Example
+
+Now that we've mastered some simple tasks, let's look at
+what typical @command{awk}
+programs do. This example shows how @command{awk} can be used to
+summarize, select, and rearrange the output of another utility. It uses
+features that haven't been covered yet, so don't worry if you don't
+understand all the details:
+
+@example
+ls -l | awk '$6 == "Nov" @{ sum += $5 @}
+ END @{ print sum @}'
+@end example
+
+@cindex @command{csh} utility, backslash continuation and
+@cindex @command{ls} utility
+@cindex backslash (@code{\}), continuing lines and, in @command{csh}
+@cindex @code{\} (backslash), continuing lines and, in @command{csh}
+This command prints the total number of bytes in all the files in the
+current directory that were last modified in November (of any year).
+@footnote{In the C shell (@command{csh}), you need to type
+a semicolon and then a backslash at the end of the first line; see
+@ref{Statements/Lines}, for an
+explanation. In a POSIX-compliant shell, such as the Bourne
+shell or @command{bash}, you can type the example as shown. If the command
+@samp{echo $path} produces an empty output line, you are most likely
+using a POSIX-compliant shell. Otherwise, you are probably using the
+C shell or a shell derived from it.}
+The @w{@samp{ls -l}} part of this example is a system command that gives
+you a listing of the files in a directory, including each file's size and the date
+the file was last modified. Its output looks like this:
+
+@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 line continuations, with C shell
+The first field contains read-write permissions, the second field contains
+the number of links to the file, and the third field identifies the owner of
+the file. The fourth field identifies the group of the file.
+The fifth field contains the size of the file in bytes. The
+sixth, seventh, and eighth fields contain the month, day, and time,
+respectively, that the file was last modified. Finally, the ninth field
+contains the name of the file.@footnote{On some
+very old systems, you may need to use @samp{ls -lg} to get this output.}
+
+@c @cindex automatic initialization
+@cindex initialization, automatic
+The @samp{$6 == "Nov"} in our @command{awk} program is an expression that
+tests whether the sixth field of the output from @w{@samp{ls -l}}
+matches the string @samp{Nov}. Each time a line has the string
+@samp{Nov} for its sixth field, the action @samp{sum += $5} is
+performed. This adds the fifth field (the file's size) to the variable
+@code{sum}. As a result, when @command{awk} has finished reading all the
+input lines, @code{sum} is the total of the sizes of the files whose
+lines matched the pattern. (This works because @command{awk} variables
+are automatically initialized to zero.)
+
+After the last line of output from @command{ls} has been processed, the
+@code{END} rule executes and prints the value of @code{sum}.
+In this example, the value of @code{sum} is 80600.
+
+These more advanced @command{awk} techniques are covered in later sections
+(@pxref{Action Overview}). Before you can move on to more
+advanced @command{awk} programming, you have to know how @command{awk} interprets
+your input and displays your output. By manipulating fields and using
+@code{print} statements, you can produce some very useful and
+impressive-looking reports.
+
+@node Statements/Lines
+@section @command{awk} Statements Versus Lines
+@cindex line breaks
+@cindex newlines
+
+Most often, each line in an @command{awk} program is a separate statement or
+separate rule, like this:
+
+@example
+awk '/12/ @{ print $0 @}
+ /21/ @{ print $0 @}' BBS-list inventory-shipped
+@end example
+
+@cindex @command{gawk}, newlines in
+However, @command{gawk} ignores newlines after any of the following
+symbols and keywords:
+
+@example
+, @{ ? : || && do else
+@end example
+
+@noindent
+A newline at any other point is considered the end of the
+statement.@footnote{The @samp{?} and @samp{:} referred to here is the
+three-operand conditional expression described in
+@ref{Conditional Exp}.
+Splitting lines after @samp{?} and @samp{:} is a minor @command{gawk}
+extension; if @option{--posix} is specified
+(@pxref{Options}), then this extension is disabled.}
+
+@cindex @code{\} (backslash), continuing lines and
+@cindex backslash (@code{\}), continuing lines and
+If you would like to split a single statement into two lines at a point
+where a newline would terminate it, you can @dfn{continue} it by ending the
+first line with a backslash character (@samp{\}). The backslash must be
+the final character on the line in order to be recognized as a continuation
+character. A backslash is allowed anywhere in the statement, even
+in the middle of a string or regular expression. For example:
+
+@example
+awk '/This regular expression is too long, so continue it\
+ on the next line/ @{ print $1 @}'
+@end example
+
+@noindent
+@cindex portability, backslash continuation and
+We have generally not used backslash continuation in the sample programs
+in this @value{DOCUMENT}. In @command{gawk}, there is no limit on the
+length of a line, so backslash continuation is never strictly necessary;
+it just makes programs more readable. For this same reason, as well as
+for clarity, we have kept most statements short in the sample programs
+presented throughout the @value{DOCUMENT}. Backslash continuation is
+most useful when your @command{awk} program is in a separate source file
+instead of entered from the command line. You should also note that
+many @command{awk} implementations are more particular about where you
+may use backslash continuation. For example, they may not allow you to
+split a string constant using backslash continuation. Thus, for maximum
+portability of your @command{awk} programs, it is best not to split your
+lines in the middle of a regular expression or a string.
+@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 @command{csh} utility
+@cindex backslash (@code{\}), continuing lines and, in @command{csh}
+@cindex @code{\} (backslash), continuing lines and, in @command{csh}
+@strong{Caution:} @emph{Backslash continuation does not work as described
+with the C shell.} It works for @command{awk} programs in files and
+for one-shot programs, @emph{provided} you are using a POSIX-compliant
+shell, such as the Unix Bourne shell or @command{bash}. But the C shell behaves
+differently! There, you must use two backslashes in a row, followed by
+a newline. Note also that when using the C shell, @emph{every} newline
+in your awk program must be escaped with a backslash. To illustrate:
+
+@example
+% awk 'BEGIN @{ \
+? print \\
+? "hello, world" \
+? @}'
+@print{} hello, world
+@end example
+
+@noindent
+Here, the @samp{%} and @samp{?} are the C shell's primary and secondary
+prompts, analogous to the standard shell's @samp{$} and @samp{>}.
+
+Compare the previous example to how it is done with a POSIX-compliant shell:
+
+@example
+$ awk 'BEGIN @{
+> print \
+> "hello, world"
+> @}'
+@print{} hello, world
+@end example
+
+@command{awk} is a line-oriented language. Each rule's action has to
+begin on the same line as the pattern. To have the pattern and action
+on separate lines, you @emph{must} use backslash continuation; there
+is no other option.
+
+@cindex backslash (@code{\}), continuing lines and, comments and
+@cindex @code{\} (backslash), continuing lines and, comments and
+@cindex commenting, backslash continuation and
+Another thing to keep in mind is that backslash continuation and
+comments do not mix. As soon as @command{awk} sees the @samp{#} that
+starts a comment, it ignores @emph{everything} on the rest of the
+line. For example:
+
+@example
+$ gawk 'BEGIN @{ print "dont panic" # a friendly \
+> BEGIN rule
+> @}'
+@error{} gawk: cmd. line:2: BEGIN rule
+@error{} gawk: cmd. line:2: ^ parse error
+@end example
+
+@noindent
+In this case, it looks like the backslash would continue the comment onto the
+next line. However, the backslash-newline combination is never even
+noticed because it is ``hidden'' inside the comment. Thus, the
+@code{BEGIN} is noted as a syntax error.
+
+@cindex statements, multiple
+@cindex @code{;} (semicolon)
+@cindex semicolon (@code{;})
+When @command{awk} statements within one rule are short, you might want to put
+more than one of them on a line. This is accomplished by separating the statements
+with a semicolon (@samp{;}).
+This also applies to the rules themselves.
+Thus, the program shown at the start of this @value{SECTION}
+could also be written this way:
+
+@example
+/12/ @{ print $0 @} ; /21/ @{ print $0 @}
+@end example
+
+@quotation NOTE
+The requirement that states that rules on the same line must be
+separated with a semicolon was not in the original @command{awk}
+language; it was added for consistency with the treatment of statements
+within an action.
+@end quotation
+
+@node Other Features
+@section Other Features of @command{awk}
+
+@cindex variables
+The @command{awk} language provides a number of predefined, or
+@dfn{built-in}, variables that your programs can use to get information
+from @command{awk}. There are other variables your program can set
+as well to control how @command{awk} processes your data.
+
+In addition, @command{awk} provides a number of built-in functions for doing
+common computational and string-related operations.
+@command{gawk} provides built-in functions for working with timestamps,
+performing bit manipulation, and for runtime string translation.
+
+As we develop our presentation of the @command{awk} language, we introduce
+most of the variables and many of the functions. They are defined
+systematically in @ref{Built-in Variables}, and
+@ref{Built-in}.
+
+@node When
+@section When to Use @command{awk}
+
+@cindex @command{awk}, uses for
+Now that you've seen some of what @command{awk} can do,
+you might wonder how @command{awk} could be useful for you. By using
+utility programs, advanced patterns, field separators, arithmetic
+statements, and other selection criteria, you can produce much more
+complex output. The @command{awk} language is very useful for producing
+reports from large amounts of raw data, such as summarizing information
+from the output of other utility programs like @command{ls}.
+(@xref{More Complex}.)
+
+Programs written with @command{awk} are usually much smaller than they would
+be in other languages. This makes @command{awk} programs easy to compose and
+use. Often, @command{awk} programs can be quickly composed at your terminal,
+used once, and thrown away. Because @command{awk} programs are interpreted, you
+can avoid the (usually lengthy) compilation part of the typical
+edit-compile-test-debug cycle of software development.
+
+Complex programs have been written in @command{awk}, including a complete
+retargetable assembler for eight-bit microprocessors (@pxref{Glossary}, for
+more information), and a microcode assembler for a special-purpose Prolog
+computer. More recently, @command{gawk} was used for writing a Wiki
+clone.@footnote{@uref{http://www.awk-scripting.de/cgi/wiki.cgi/yawk/, Yet Another Wiki Clone}.}
+While the original @command{awk}'s capabilities were strained by tasks
+of such complexity, modern versions are more capable. Even the Bell
+Labs version of @command{awk} has fewer predefined limits, and those
+that it has are much larger than they used to be.
+
+@cindex @command{awk} programs, complex
+If you find yourself writing @command{awk} scripts of more than, say, a few
+hundred lines, you might consider using a different programming
+language. Emacs Lisp is a good choice if you need sophisticated string
+or pattern matching capabilities. The shell is also good at string and
+pattern matching; in addition, it allows powerful use of the system
+utilities. More conventional languages, such as C, C++, and Java, offer
+better facilities for system programming and for managing the complexity
+of large programs. Programs in these languages may require more lines
+of source code than the equivalent @command{awk} programs, but they are
+easier to maintain and usually run more efficiently.
+
+@node Regexp
+@chapter Regular Expressions
+@cindex regexp, See regular expressions
+@c STARTOFRANGE regexp
+@cindex regular expressions
+
+A @dfn{regular expression}, or @dfn{regexp}, is a way of describing a
+set of strings.
+Because regular expressions are such a fundamental part of @command{awk}
+programming, their format and use deserve a separate @value{CHAPTER}.
+
+@cindex forward slash (@code{/})
+@cindex @code{/} (forward slash)
+A regular expression enclosed in slashes (@samp{/})
+is an @command{awk} pattern that matches every input record whose text
+belongs to that set.
+The simplest regular expression is a sequence of letters, numbers, or
+both. Such a regexp matches any string that contains that sequence.
+Thus, the regexp @samp{foo} matches any string containing @samp{foo}.
+Therefore, the pattern @code{/foo/} matches any input record containing
+the three characters @samp{foo} @emph{anywhere} in the record. Other
+kinds of regexps let you specify more complicated classes of strings.
+
+@ifnotinfo
+Initially, the examples in this @value{CHAPTER} are simple.
+As we explain more about how
+regular expressions work, we will present more complicated instances.
+@end ifnotinfo
+
+@menu
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Character Lists:: What can go between @samp{[...]}.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* Locales:: How the locale affects things.
+@end menu
+
+@node Regexp Usage
+@section How to Use Regular Expressions
+
+@cindex regular expressions, as patterns
+A regular expression can be used as a pattern by enclosing it in
+slashes. Then the regular expression is tested against the
+entire text of each record. (Normally, it only needs
+to match some part of the text in order to succeed.) For example, the
+following prints the second field of each record that contains the string
+@samp{foo} anywhere in it:
+
+@example
+$ awk '/foo/ @{ print $2 @}' BBS-list
+@print{} 555-1234
+@print{} 555-6699
+@print{} 555-6480
+@print{} 555-2127
+@end example
+
+@cindex regular expressions, operators
+@cindex operators, string-matching
+@c @cindex operators, @code{~}
+@cindex string-matching operators
+@code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@c @cindex operators, @code{!~}
+@cindex @code{if} statement
+@cindex @code{while} statement
+@cindex @code{do}-@code{while} statement
+@c @cindex statements, @code{if}
+@c @cindex statements, @code{while}
+@c @cindex statements, @code{do}
+Regular expressions can also be used in matching expressions. These
+expressions allow you to specify the string to match against; it need
+not be the entire current input record. The two operators @samp{~}
+and @samp{!~} perform regular expression comparisons. Expressions
+using these operators can be used as patterns, or in @code{if},
+@code{while}, @code{for}, and @code{do} statements.
+(@xref{Statements}.)
+For example:
+
+@example
+@var{exp} ~ /@var{regexp}/
+@end example
+
+@noindent
+is true if the expression @var{exp} (taken as a string)
+matches @var{regexp}. The following example matches, or selects,
+all input records with the uppercase letter @samp{J} somewhere in the
+first field:
+
+@example
+$ 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
+
+So does this:
+
+@example
+awk '@{ if ($1 ~ /J/) print @}' inventory-shipped
+@end example
+
+This next example is true if the expression @var{exp}
+(taken as a character string)
+does @emph{not} match @var{regexp}:
+
+@example
+@var{exp} !~ /@var{regexp}/
+@end example
+
+The following example matches,
+or selects, all input records whose first field @emph{does not} contain
+the uppercase letter @samp{J}:
+
+@example
+$ 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 regexp constants
+@cindex regular expressions, constants, See regexp constants
+When a regexp is enclosed in slashes, such as @code{/foo/}, we call it
+a @dfn{regexp constant}, much like @code{5.27} is a numeric constant and
+@code{"foo"} is a string constant.
+
+@node Escape Sequences
+@section Escape Sequences
+
+@cindex escape sequences
+@cindex backslash (@code{\}), in escape sequences
+@cindex @code{\} (backslash), in escape sequences
+Some characters cannot be included literally in string constants
+(@code{"foo"}) or regexp constants (@code{/foo/}).
+Instead, they should be represented with @dfn{escape sequences},
+which are character sequences beginning with a backslash (@samp{\}).
+One use of an escape sequence is to include a double-quote character in
+a string constant. Because a plain double quote ends the string, you
+must use @samp{\"} to represent an actual double-quote character as a
+part of the string. For example:
+
+@example
+$ awk 'BEGIN @{ print "He said \"hi!\" to her." @}'
+@print{} He said "hi!" to her.
+@end example
+
+The backslash character itself is another character that cannot be
+included normally; you must write @samp{\\} to put one backslash in the
+string or regexp. Thus, the string whose contents are the two characters
+@samp{"} and @samp{\} must be written @code{"\"\\"}.
+
+Backslash also represents unprintable characters
+such as TAB or newline. While there is nothing to stop you from entering most
+unprintable characters directly in a string constant or regexp constant,
+they may look ugly.
+
+The following table lists
+all the escape sequences used in @command{awk} and
+what they represent. Unless noted otherwise, all these escape
+sequences apply to both string constants and regexp constants:
+
+@table @code
+@item \\
+A literal backslash, @samp{\}.
+
+@c @cindex @command{awk} language, V.4 version
+@cindex @code{\} (backslash), @code{\a} escape sequence
+@cindex backslash (@code{\}), @code{\a} escape sequence
+@item \a
+The ``alert'' character, @kbd{@value{CTL}-g}, ASCII code 7 (BEL).
+(This usually makes some sort of audible noise.)
+
+@cindex @code{\} (backslash), @code{\b} escape sequence
+@cindex backslash (@code{\}), @code{\b} escape sequence
+@item \b
+Backspace, @kbd{@value{CTL}-h}, ASCII code 8 (BS).
+
+@cindex @code{\} (backslash), @code{\f} escape sequence
+@cindex backslash (@code{\}), @code{\f} escape sequence
+@item \f
+Formfeed, @kbd{@value{CTL}-l}, ASCII code 12 (FF).
+
+@cindex @code{\} (backslash), @code{\n} escape sequence
+@cindex backslash (@code{\}), @code{\n} escape sequence
+@item \n
+Newline, @kbd{@value{CTL}-j}, ASCII code 10 (LF).
+
+@cindex @code{\} (backslash), @code{\r} escape sequence
+@cindex backslash (@code{\}), @code{\r} escape sequence
+@item \r
+Carriage return, @kbd{@value{CTL}-m}, ASCII code 13 (CR).
+
+@cindex @code{\} (backslash), @code{\t} escape sequence
+@cindex backslash (@code{\}), @code{\t} escape sequence
+@item \t
+Horizontal TAB, @kbd{@value{CTL}-i}, ASCII code 9 (HT).
+
+@c @cindex @command{awk} language, V.4 version
+@cindex @code{\} (backslash), @code{\v} escape sequence
+@cindex backslash (@code{\}), @code{\v} escape sequence
+@item \v
+Vertical tab, @kbd{@value{CTL}-k}, ASCII code 11 (VT).
+
+@cindex @code{\} (backslash), @code{\}@var{nnn} escape sequence
+@cindex backslash (@code{\}), @code{\}@var{nnn} escape sequence
+@item \@var{nnn}
+The octal value @var{nnn}, where @var{nnn} stands for 1 to 3 digits
+between @samp{0} and @samp{7}. For example, the code for the ASCII ESC
+(escape) character is @samp{\033}.
+
+@c @cindex @command{awk} language, V.4 version
+@c @cindex @command{awk} language, POSIX version
+@cindex @code{\} (backslash), @code{\x} escape sequence
+@cindex backslash (@code{\}), @code{\x} escape sequence
+@item \x@var{hh}@dots{}
+The hexadecimal value @var{hh}, where @var{hh} stands for a sequence
+of hexadecimal digits (@samp{0}--@samp{9}, and either @samp{A}--@samp{F}
+or @samp{a}--@samp{f}). Like the same construct
+in ISO C, the escape sequence continues until the first nonhexadecimal
+digit is seen. However, using more than two hexadecimal digits produces
+undefined results. (The @samp{\x} escape sequence is not allowed in
+POSIX @command{awk}.)
+
+@cindex @code{\} (backslash), @code{\/} escape sequence
+@cindex backslash (@code{\}), @code{\/} escape sequence
+@item \/
+A literal slash (necessary for regexp constants only).
+This expression is used when you want to write a regexp
+constant that contains a slash. Because the regexp is delimited by
+slashes, you need to escape the slash that is part of the pattern,
+in order to tell @command{awk} to keep processing the rest of the regexp.
+
+@cindex @code{\} (backslash), @code{\"} escape sequence
+@cindex backslash (@code{\}), @code{\"} escape sequence
+@item \"
+A literal double quote (necessary for string constants only).
+This expression is used when you want to write a string
+constant that contains a double quote. Because the string is delimited by
+double quotes, you need to escape the quote that is part of the string,
+in order to tell @command{awk} to keep processing the rest of the string.
+@end table
+
+In @command{gawk}, a number of additional two-character sequences that begin
+with a backslash have special meaning in regexps.
+@xref{GNU Regexp Operators}.
+
+In a regexp, a backslash before any character that is not in the previous list
+and not listed in
+@ref{GNU Regexp Operators},
+means that the next character should be taken literally, even if it would
+normally be a regexp operator. For example, @code{/a\+b/} matches the three
+characters @samp{a+b}.
+
+@cindex backslash (@code{\}), in escape sequences
+@cindex @code{\} (backslash), in escape sequences
+@cindex portability
+For complete portability, do not use a backslash before any character not
+shown in the previous list.
+
+To summarize:
+
+@itemize @bullet
+@item
+The escape sequences in the table above are always processed first,
+for both string constants and regexp constants. This happens very early,
+as soon as @command{awk} reads your program.
+
+@item
+@command{gawk} processes both regexp constants and dynamic regexps
+(@pxref{Computed Regexps}),
+for the special operators listed in
+@ref{GNU Regexp Operators}.
+
+@item
+A backslash before any other character means to treat that character
+literally.
+@end itemize
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Backslash Before Regular Characters
+@cindex portability, backslash in escape sequences
+@cindex POSIX @command{awk}, backslashes in string constants
+@cindex backslash (@code{\}), in escape sequences, POSIX and
+@cindex @code{\} (backslash), in escape sequences, POSIX and
+
+@cindex troubleshooting, backslash before nonspecial character
+If you place a backslash in a string constant before something that is
+not one of the characters previously listed, POSIX @command{awk} purposely
+leaves what happens as undefined. There are two choices:
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@table @asis
+@item Strip the backslash out
+This is what Unix @command{awk} and @command{gawk} both do.
+For example, @code{"a\qc"} is the same as @code{"aqc"}.
+(Because this is such an easy bug both to introduce and to miss,
+@command{gawk} warns you about it.)
+Consider @samp{FS = @w{"[ \t]+\|[ \t]+"}} to use vertical bars
+surrounded by whitespace as the field separator. There should be
+two backslashes in the string @samp{FS = @w{"[ \t]+\\|[ \t]+"}}.)
+@c I did this! This is why I added the warning.
+
+@cindex @command{gawk}, escape sequences
+@cindex Unix @command{awk}, backslashes in escape sequences
+@item Leave the backslash alone
+Some other @command{awk} implementations do this.
+In such implementations, typing @code{"a\qc"} is the same as typing
+@code{"a\\qc"}.
+@end table
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Escape Sequences for Metacharacters
+@cindex metacharacters, escape sequences for
+
+Suppose you use an octal or hexadecimal
+escape to represent a regexp metacharacter.
+(See @ref{Regexp Operators}.)
+Does @command{awk} treat the character as a literal character or as a regexp
+operator?
+
+@cindex dark corner, escape sequences, for metacharacters
+Historically, such characters were taken literally.
+@value{DARKCORNER}
+However, the POSIX standard indicates that they should be treated
+as real metacharacters, which is what @command{gawk} does.
+In compatibility mode (@pxref{Options}),
+@command{gawk} treats the characters represented by octal and hexadecimal
+escape sequences literally when used in regexp constants. Thus,
+@code{/a\52b/} is equivalent to @code{/a\*b/}.
+
+@node Regexp Operators
+@section Regular Expression Operators
+@c STARTOFRANGE regexpo
+@cindex regular expressions, operators
+
+You can combine regular expressions with special characters,
+called @dfn{regular expression operators} or @dfn{metacharacters}, to
+increase the power and versatility of regular expressions.
+
+The escape sequences described
+@ifnotinfo
+earlier
+@end ifnotinfo
+in @ref{Escape Sequences},
+are valid inside a regexp. They are introduced by a @samp{\} and
+are recognized and converted into corresponding real characters as
+the very first step in processing regexps.
+
+Here is a list of metacharacters. All characters that are not escape
+sequences and that are not listed in the table stand for themselves:
+
+@table @code
+@cindex backslash (@code{\})
+@cindex @code{\} (backslash)
+@item \
+This is used to suppress the special meaning of a character when
+matching. For example, @samp{\$}
+matches the character @samp{$}.
+
+@cindex regular expressions, anchors in
+@cindex Texinfo, chapter beginnings in files
+@cindex @code{^} (caret)
+@cindex caret (@code{^})
+@item ^
+This matches the beginning of a string. For example, @samp{^@@chapter}
+matches @samp{@@chapter} at the beginning of a string and can be used
+to identify chapter beginnings in Texinfo source files.
+The @samp{^} is known as an @dfn{anchor}, because it anchors the pattern to
+match only at the beginning of the string.
+
+It is important to realize that @samp{^} does not match the beginning of
+a line embedded in a string.
+The condition is not true in the following example:
+
+@example
+if ("line1\nLINE 2" ~ /^L/) @dots{}
+@end example
+
+@cindex @code{$} (dollar sign)
+@cindex dollar sign (@code{$})
+@item $
+This is similar to @samp{^}, but it matches only at the end of a string.
+For example, @samp{p$}
+matches a record that ends with a @samp{p}. The @samp{$} is an anchor
+and does not match the end of a line embedded in a string.
+The condition in the following example is not true:
+
+@example
+if ("line1\nLINE 2" ~ /1$/) @dots{}
+@end example
+
+@cindex @code{.} (period)
+@cindex period (@code{.})
+@item .
+This matches any single character,
+@emph{including} the newline character. For example, @samp{.P}
+matches any single character followed by a @samp{P} in a string. Using
+concatenation, we can make a regular expression such as @samp{U.A}, which
+matches any three-character sequence that begins with @samp{U} and ends
+with @samp{A}.
+
+@cindex POSIX @command{awk}, period (@code{.})@comma{} using
+In strict POSIX mode (@pxref{Options}),
+@samp{.} does not match the @sc{nul}
+character, which is a character with all bits equal to zero.
+Otherwise, @sc{nul} is just another character. Other versions of @command{awk}
+may not be able to match the @sc{nul} character.
+
+@cindex @code{[]} (square brackets)
+@cindex square brackets (@code{[]})
+@cindex character lists
+@cindex character sets, See Also character lists
+@cindex bracket expressions, See character lists
+@item [@dots{}]
+This is called a @dfn{character list}.@footnote{In other literature,
+you may see a character list referred to as either a
+@dfn{character set}, a @dfn{character class}, or a @dfn{bracket expression}.}
+It matches any @emph{one} of the characters that are enclosed in
+the square brackets. For example, @samp{[MVX]} matches any one of
+the characters @samp{M}, @samp{V}, or @samp{X} in a string. A full
+discussion of what can be inside the square brackets of a character list
+is given in
+@ref{Character Lists}.
+
+@cindex character lists, complemented
+@item [^ @dots{}]
+This is a @dfn{complemented character list}. The first character after
+the @samp{[} @emph{must} be a @samp{^}. It matches any characters
+@emph{except} those in the square brackets. For example, @samp{[^awk]}
+matches any character that is not an @samp{a}, @samp{w},
+or @samp{k}.
+
+@cindex @code{|} (vertical bar)
+@cindex vertical bar (@code{|})
+@item |
+This is the @dfn{alternation operator} and it is used to specify
+alternatives.
+The @samp{|} has the lowest precedence of all the regular
+expression operators.
+For example, @samp{^P|[[:digit:]]}
+matches any string that matches either @samp{^P} or @samp{[[:digit:]]}. This
+means it matches any string that starts with @samp{P} or contains a digit.
+
+The alternation applies to the largest possible regexps on either side.
+
+@cindex @code{()} (parentheses)
+@cindex parentheses @code{()}
+@item (@dots{})
+Parentheses are used for grouping in regular expressions, as in
+arithmetic. They can be used to concatenate regular expressions
+containing the alternation operator, @samp{|}. For example,
+@samp{@@(samp|code)\@{[^@}]+\@}} matches both @samp{@@code@{foo@}} and
+@samp{@@samp@{bar@}}.
+(These are Texinfo formatting control sequences. The @samp{+} is
+explained further on in this list.)
+
+@cindex @code{*} (asterisk), @code{*} operator, as regexp operator
+@cindex asterisk (@code{*}), @code{*} operator, as regexp operator
+@item *
+This symbol means that the preceding regular expression should be
+repeated as many times as necessary to find a match. For example, @samp{ph*}
+applies the @samp{*} symbol to the preceding @samp{h} and looks for matches
+of one @samp{p} followed by any number of @samp{h}s. This also matches
+just @samp{p} if no @samp{h}s are present.
+
+The @samp{*} repeats the @emph{smallest} possible preceding expression.
+(Use parentheses if you want to repeat a larger expression.) It finds
+as many repetitions as possible. For example,
+@samp{awk '/\(c[ad][ad]*r x\)/ @{ print @}' sample}
+prints every record in @file{sample} containing a string of the form
+@samp{(car x)}, @samp{(cdr x)}, @samp{(cadr x)}, and so on.
+Notice the escaping of the parentheses by preceding them
+with backslashes.
+
+@cindex @code{+} (plus sign)
+@cindex plus sign (@code{+})
+@item +
+This symbol is similar to @samp{*}, except that the preceding expression must be
+matched at least once. This means that @samp{wh+y}
+would match @samp{why} and @samp{whhy}, but not @samp{wy}, whereas
+@samp{wh*y} would match all three of these strings.
+The following is a simpler
+way of writing the last @samp{*} example:
+
+@example
+awk '/\(c[ad]+r x\)/ @{ print @}' sample
+@end example
+
+@cindex @code{?} (question mark)
+@cindex question mark (@code{?})
+@item ?
+This symbol is similar to @samp{*}, except that the preceding expression can be
+matched either once or not at all. For example, @samp{fe?d}
+matches @samp{fed} and @samp{fd}, but nothing else.
+
+@cindex interval expressions
+@item @{@var{n}@}
+@itemx @{@var{n},@}
+@itemx @{@var{n},@var{m}@}
+One or two numbers inside braces denote an @dfn{interval expression}.
+If there is one number in the braces, the preceding regexp is repeated
+@var{n} times.
+If there are two numbers separated by a comma, the preceding regexp is
+repeated @var{n} to @var{m} times.
+If there is one number followed by a comma, then the preceding regexp
+is repeated at least @var{n} times:
+
+@table @code
+@item wh@{3@}y
+Matches @samp{whhhy}, but not @samp{why} or @samp{whhhhy}.
+
+@item wh@{3,5@}y
+Matches @samp{whhhy}, @samp{whhhhy}, or @samp{whhhhhy}, only.
+
+@item wh@{2,@}y
+Matches @samp{whhy} or @samp{whhhy}, and so on.
+@end table
+
+@cindex POSIX @command{awk}, interval expressions in
+Interval expressions were not traditionally available in @command{awk}.
+They were added as part of the POSIX standard to make @command{awk}
+and @command{egrep} consistent with each other.
+
+@cindex @command{gawk}, interval expressions and
+However, because old programs may use @samp{@{} and @samp{@}} in regexp
+constants, by default @command{gawk} does @emph{not} match interval expressions
+in regexps. If either @option{--posix} or @option{--re-interval} are specified
+(@pxref{Options}), then interval expressions
+are allowed in regexps.
+
+For new programs that use @samp{@{} and @samp{@}} in regexp constants,
+it is good practice to always escape them with a backslash. Then the
+regexp constants are valid and work the way you want them to, using
+any version of @command{awk}.@footnote{Use two backslashes if you're
+using a string constant with a regexp operator or function.}
+@end table
+
+@cindex precedence, regexp operators
+@cindex regular expressions, operators, precedence of
+In regular expressions, the @samp{*}, @samp{+}, and @samp{?} operators,
+as well as the braces @samp{@{} and @samp{@}},
+have
+the highest precedence, followed by concatenation, and finally by @samp{|}.
+As in arithmetic, parentheses can change how operators are grouped.
+
+@cindex POSIX @command{awk}, regular expressions and
+@cindex @command{gawk}, regular expressions, precedence
+In POSIX @command{awk} and @command{gawk}, the @samp{*}, @samp{+}, and @samp{?} operators
+stand for themselves when there is nothing in the regexp that precedes them.
+For example, @samp{/+/} matches a literal plus sign. However, many other versions of
+@command{awk} treat such a usage as a syntax error.
+
+If @command{gawk} is in compatibility mode
+(@pxref{Options}),
+POSIX character classes and interval expressions are not available in
+regular expressions.
+@c ENDOFRANGE regexpo
+
+@node Character Lists
+@section Using Character Lists
+@c STARTOFRANGE charlist
+@cindex character lists
+@cindex character lists, range expressions
+@cindex range expressions
+
+Within a character list, a @dfn{range expression} consists of two
+characters separated by a hyphen. It matches any single character that
+sorts between the two characters, using the locale's
+collating sequence and character set. For example, in the default C
+locale, @samp{[a-dx-z]} is equivalent to @samp{[abcdxyz]}. Many locales
+sort characters in dictionary order, and in these locales,
+@samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]}; instead it
+might be equivalent to @samp{[aBbCcDdxXyYz]}, for example. To obtain
+the traditional interpretation of bracket expressions, you can use the C
+locale by setting the @env{LC_ALL} environment variable to the value
+@samp{C}.
+
+@cindex @code{\} (backslash), in character lists
+@cindex backslash (@code{\}), in character lists
+@cindex @code{^} (caret), in character lists
+@cindex caret (@code{^}), in character lists
+@cindex @code{-} (hyphen), in character lists
+@cindex hyphen (@code{-}), in character lists
+To include one of the characters @samp{\}, @samp{]}, @samp{-}, or @samp{^} in a
+character list, put a @samp{\} in front of it. For example:
+
+@example
+[d\]]
+@end example
+
+@noindent
+matches either @samp{d} or @samp{]}.
+
+@cindex POSIX @command{awk}, character lists and
+@cindex Extended Regular Expressions (EREs)
+@cindex EREs (Extended Regular Expressions)
+@cindex @command{egrep} utility
+This treatment of @samp{\} in character lists
+is compatible with other @command{awk}
+implementations and is also mandated by POSIX.
+The regular expressions in @command{awk} are a superset
+of the POSIX specification for Extended Regular Expressions (EREs).
+POSIX EREs are based on the regular expressions accepted by the
+traditional @command{egrep} utility.
+
+@cindex character lists, character classes
+@cindex POSIX @command{awk}, character lists and, character classes
+@dfn{Character classes} are a new feature introduced in the POSIX standard.
+A character class is a special notation for describing
+lists of characters that have a specific attribute, but the
+actual characters can vary from country to country and/or
+from character set to character set. For example, the notion of what
+is an alphabetic character differs between the United States and France.
+
+A character class is only valid in a regexp @emph{inside} the
+brackets of a character list. Character classes consist of @samp{[:},
+a keyword denoting the class, and @samp{:]}.
+@ref{table-char-classes} lists the character classes defined by the
+POSIX standard.
+
+@float Table,table-char-classes
+@caption{POSIX Character Classes}
+@multitable @columnfractions .15 .85
+@headitem Class @tab Meaning
+@item @code{[:alnum:]} @tab Alphanumeric characters.
+@item @code{[:alpha:]} @tab Alphabetic characters.
+@item @code{[:blank:]} @tab Space and TAB characters.
+@item @code{[:cntrl:]} @tab Control characters.
+@item @code{[:digit:]} @tab Numeric characters.
+@item @code{[:graph:]} @tab Characters that are both printable and visible.
+(A space is printable but not visible, whereas an @samp{a} is both.)
+@item @code{[:lower:]} @tab Lowercase alphabetic characters.
+@item @code{[:print:]} @tab Printable characters (characters that are not control characters).
+@item @code{[:punct:]} @tab Punctuation characters (characters that are not letters, digits,
+control characters, or space characters).
+@item @code{[:space:]} @tab Space characters (such as space, TAB, and formfeed, to name a few).
+@item @code{[:upper:]} @tab Uppercase alphabetic characters.
+@item @code{[:xdigit:]} @tab Characters that are hexadecimal digits.
+@end multitable
+@end float
+
+For example, before the POSIX standard, you had to write @code{/[A-Za-z0-9]/}
+to match alphanumeric characters. If your
+character set had other alphabetic characters in it, this would not
+match them, and if your character set collated differently from
+ASCII, this might not even match the ASCII alphanumeric characters.
+With the POSIX character classes, you can write
+@code{/[[:alnum:]]/} to match the alphabetic
+and numeric characters in your character set.
+
+@cindex character lists, collating elements
+@cindex character lists, non-ASCII
+@cindex collating elements
+Two additional special sequences can appear in character lists.
+These apply to non-ASCII character sets, which can have single symbols
+(called @dfn{collating elements}) that are represented with more than one
+character. They can also have several characters that are equivalent for
+@dfn{collating}, or sorting, purposes. (For example, in French, a plain ``e''
+and a grave-accented ``@`e'' are equivalent.)
+These sequences are:
+
+@table @asis
+@cindex character lists, collating symbols
+@cindex collating symbols
+@item Collating symbols
+Multicharacter collating elements enclosed between
+@samp{[.} and @samp{.]}. For example, if @samp{ch} is a collating element,
+then @code{[[.ch.]]} is a regexp that matches this collating element, whereas
+@code{[ch]} is a regexp that matches either @samp{c} or @samp{h}.
+
+@cindex character lists, equivalence classes
+@item Equivalence classes
+Locale-specific names for a list of
+characters that are equal. The name is enclosed between
+@samp{[=} and @samp{=]}.
+For example, the name @samp{e} might be used to represent all of
+``e,'' ``@`e,'' and ``@'e.'' In this case, @code{[[=e=]]} is a regexp
+that matches any of @samp{e}, @samp{@'e}, or @samp{@`e}.
+@end table
+
+These features are very valuable in non-English-speaking locales.
+
+@cindex internationalization, localization, character classes
+@cindex @command{gawk}, character classes and
+@cindex POSIX @command{awk}, character lists and, character classes
+@strong{Caution:} The library functions that @command{gawk} uses for regular
+expression matching currently recognize only POSIX character classes;
+they do not recognize collating symbols or equivalence classes.
+@c maybe one day ...
+@c ENDOFRANGE charlist
+
+@node GNU Regexp Operators
+@section @command{gawk}-Specific Regexp Operators
+
+@c This section adapted (long ago) from the regex-0.12 manual
+
+@c STARTOFRANGE regexpg
+@cindex regular expressions, operators, @command{gawk}
+@c STARTOFRANGE gregexp
+@cindex @command{gawk}, regular expressions, operators
+@cindex operators, GNU-specific
+@cindex regular expressions, operators, for words
+@cindex word, regexp definition of
+GNU software that deals with regular expressions provides a number of
+additional regexp operators. These operators are described in this
+@value{SECTION} and are specific to @command{gawk};
+they are not available in other @command{awk} implementations.
+Most of the additional operators deal with word matching.
+For our purposes, a @dfn{word} is a sequence of one or more letters, digits,
+or underscores (@samp{_}):
+
+@table @code
+@c @cindex operators, @code{\w} (@command{gawk})
+@cindex backslash (@code{\}), @code{\w} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\w} operator (@command{gawk})
+@item \w
+Matches any word-constituent character---that is, it matches any
+letter, digit, or underscore. Think of it as shorthand for
+@w{@code{[[:alnum:]_]}}.
+
+@c @cindex operators, @code{\W} (@command{gawk})
+@cindex backslash (@code{\}), @code{\W} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\W} operator (@command{gawk})
+@item \W
+Matches any character that is not word-constituent.
+Think of it as shorthand for
+@w{@code{[^[:alnum:]_]}}.
+
+@c @cindex operators, @code{\<} (@command{gawk})
+@cindex backslash (@code{\}), @code{\<} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\<} operator (@command{gawk})
+@item \<
+Matches the empty string at the beginning of a word.
+For example, @code{/\<away/} matches @samp{away} but not
+@samp{stowaway}.
+
+@c @cindex operators, @code{\>} (@command{gawk})
+@cindex backslash (@code{\}), @code{\>} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\>} operator (@command{gawk})
+@item \>
+Matches the empty string at the end of a word.
+For example, @code{/stow\>/} matches @samp{stow} but not @samp{stowaway}.
+
+@c @cindex operators, @code{\y} (@command{gawk})
+@cindex backslash (@code{\}), @code{\y} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\y} operator (@command{gawk})
+@cindex word boundaries@comma{} matching
+@item \y
+Matches the empty string at either the beginning or the
+end of a word (i.e., the word boundar@strong{y}). For example, @samp{\yballs?\y}
+matches either @samp{ball} or @samp{balls}, as a separate word.
+
+@c @cindex operators, @code{\B} (@command{gawk})
+@cindex backslash (@code{\}), @code{\B} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\B} operator (@command{gawk})
+@item \B
+Matches the empty string that occurs between two
+word-constituent characters. For example,
+@code{/\Brat\B/} matches @samp{crate} but it does not match @samp{dirty rat}.
+@samp{\B} is essentially the opposite of @samp{\y}.
+@end table
+
+@cindex buffers, operators for
+@cindex regular expressions, operators, for buffers
+@cindex operators, string-matching, for buffers
+There are two other operators that work on buffers. In Emacs, a
+@dfn{buffer} is, naturally, an Emacs buffer. For other programs,
+@command{gawk}'s regexp library routines consider the entire
+string to match as the buffer.
+The operators are:
+
+@table @code
+@item \`
+@c @cindex operators, @code{\`} (@command{gawk})
+@cindex backslash (@code{\}), @code{\`} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\`} operator (@command{gawk})
+Matches the empty string at the
+beginning of a buffer (string).
+
+@c @cindex operators, @code{\'} (@command{gawk})
+@cindex backslash (@code{\}), @code{\'} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\'} operator (@command{gawk})
+@item \'
+Matches the empty string at the
+end of a buffer (string).
+@end table
+
+@cindex @code{^} (caret)
+@cindex caret (@code{^})
+@cindex @code{?} (question mark)
+@cindex question mark (@code{?})
+Because @samp{^} and @samp{$} always work in terms of the beginning
+and end of strings, these operators don't add any new capabilities
+for @command{awk}. They are provided for compatibility with other
+GNU software.
+
+@cindex @command{gawk}, word-boundary operator
+@cindex word-boundary operator (@command{gawk})
+@cindex operators, word-boundary (@command{gawk})
+In other GNU software, the word-boundary operator is @samp{\b}. However,
+that conflicts with the @command{awk} language's definition of @samp{\b}
+as backspace, so @command{gawk} uses a different letter.
+An alternative method would have been to require two backslashes in the
+GNU operators, but this was deemed too confusing. The current
+method of using @samp{\y} for the GNU @samp{\b} appears to be the
+lesser of two evils.
+
+@c NOTE!!! Keep this in sync with the same table in the summary appendix!
+@c
+@c Should really do this with file inclusion.
+@cindex regular expressions, @command{gawk}, command-line options
+@cindex @command{gawk}, command-line options
+The various command-line options
+(@pxref{Options})
+control how @command{gawk} interprets characters in regexps:
+
+@table @asis
+@item No options
+In the default case, @command{gawk} provides all the facilities of
+POSIX regexps and the
+@ifnotinfo
+previously described
+GNU regexp operators.
+@end ifnotinfo
+@ifnottex
+GNU regexp operators described
+in @ref{Regexp Operators}.
+@end ifnottex
+However, interval expressions are not supported.
+
+@item @code{--posix}
+Only POSIX regexps are supported; the GNU operators are not special
+(e.g., @samp{\w} matches a literal @samp{w}). Interval expressions
+are allowed.
+
+@item @code{--traditional}
+Traditional Unix @command{awk} regexps are matched. The GNU operators
+are not special, interval expressions are not available, nor
+are the POSIX character classes (@code{[[:alnum:]]}, etc.).
+Characters described by octal and hexadecimal escape sequences are
+treated literally, even if they represent regexp metacharacters.
+
+@item @code{--re-interval}
+Allow interval expressions in regexps, even if @option{--traditional}
+has been provided. (@option{--posix} automatically enables
+interval expressions, so @option{--re-interval} is redundant
+when @option{--posix} is is used.)
+@end table
+@c ENDOFRANGE gregexp
+@c ENDOFRANGE regexpg
+
+@node Case-sensitivity
+@section Case Sensitivity in Matching
+
+@c STARTOFRANGE regexpcs
+@cindex regular expressions, case sensitivity
+@c STARTOFRANGE csregexp
+@cindex case sensitivity, regexps and
+Case is normally significant in regular expressions, both when matching
+ordinary characters (i.e., not metacharacters) and inside character
+sets. Thus, a @samp{w} in a regular expression matches only a lowercase
+@samp{w} and not an uppercase @samp{W}.
+
+The simplest way to do a case-independent match is to use a character
+list---for example, @samp{[Ww]}. However, this can be cumbersome if
+you need to use it often, and it can make the regular expressions harder
+to read. There are two alternatives that you might prefer.
+
+One way to perform a case-insensitive match at a particular point in the
+program is to convert the data to a single case, using the
+@code{tolower} or @code{toupper} built-in string functions (which we
+haven't discussed yet;
+@pxref{String Functions}).
+For example:
+
+@example
+tolower($1) ~ /foo/ @{ @dots{} @}
+@end example
+
+@noindent
+converts the first field to lowercase before matching against it.
+This works in any POSIX-compliant @command{awk}.
+
+@cindex @command{gawk}, regular expressions, case sensitivity
+@cindex case sensitivity, @command{gawk}
+@cindex differences in @command{awk} and @command{gawk}, regular expressions
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@cindex @code{IGNORECASE} variable
+@c @cindex variables, @code{IGNORECASE}
+Another method, specific to @command{gawk}, is to set the variable
+@code{IGNORECASE} to a nonzero value (@pxref{Built-in Variables}).
+When @code{IGNORECASE} is not zero, @emph{all} regexp and string
+operations ignore case. Changing the value of
+@code{IGNORECASE} dynamically controls the case-sensitivity of the
+program as it runs. Case is significant by default because
+@code{IGNORECASE} (like most variables) is initialized to zero:
+
+@example
+x = "aB"
+if (x ~ /ab/) @dots{} # this test will fail
+
+IGNORECASE = 1
+if (x ~ /ab/) @dots{} # now it will succeed
+@end example
+
+In general, you cannot use @code{IGNORECASE} to make certain rules
+case-insensitive and other rules case-sensitive, because there is no
+straightforward way
+to set @code{IGNORECASE} just for the pattern of
+a particular rule.@footnote{Experienced C and C++ programmers will note
+that it is possible, using something like
+@samp{IGNORECASE = 1 && /foObAr/ @{ @dots{} @}}
+and
+@samp{IGNORECASE = 0 || /foobar/ @{ @dots{} @}}.
+However, this is somewhat obscure and we don't recommend it.}
+To do this, use either character lists or @code{tolower}. However, one
+thing you can do with @code{IGNORECASE} only is dynamically turn
+case-sensitivity on or off for all the rules at once.
+
+@code{IGNORECASE} can be set on the command line or in a @code{BEGIN} rule
+(@pxref{Other Arguments}; also
+@pxref{Using BEGIN/END}).
+Setting @code{IGNORECASE} from the command line is a way to make
+a program case-insensitive without having to edit it.
+
+Prior to @command{gawk} 3.0, the value of @code{IGNORECASE}
+affected regexp operations only. It did not affect string comparison
+with @samp{==}, @samp{!=}, and so on.
+Beginning with @value{PVERSION} 3.0, both regexp and string comparison
+operations are also affected by @code{IGNORECASE}.
+
+@c @cindex ISO 8859-1
+@c @cindex ISO Latin-1
+Beginning with @command{gawk} 3.0,
+the equivalences between upper-
+and lowercase characters are based on the ISO-8859-1 (ISO Latin-1)
+character set. This character set is a superset of the traditional 128
+ASCII characters, which also provides a number of characters suitable
+for use with European languages.
+
+As of @command{gawk} 3.1.4, the case equivalencies are fully
+locale-aware. They are based on the C @code{<ctype.h>} facilities,
+such as @code{isalpha()} and @code{toupper()}.
+
+The value of @code{IGNORECASE} has no effect if @command{gawk} is in
+compatibility mode (@pxref{Options}).
+Case is always significant in compatibility mode.
+@c ENDOFRANGE csregexp
+@c ENDOFRANGE regexpcs
+
+@node Leftmost Longest
+@section How Much Text Matches?
+
+@cindex regular expressions, leftmost longest match
+@c @cindex matching, leftmost longest
+Consider the following:
+
+@example
+echo aaaabcd | awk '@{ sub(/a+/, "<A>"); print @}'
+@end example
+
+This example uses the @code{sub} function (which we haven't discussed yet;
+@pxref{String Functions})
+to make a change to the input record. Here, the regexp @code{/a+/}
+indicates ``one or more @samp{a} characters,'' and the replacement
+text is @samp{<A>}.
+
+The input contains four @samp{a} characters.
+@command{awk} (and POSIX) regular expressions always match
+the leftmost, @emph{longest} sequence of input characters that can
+match. Thus, all four @samp{a} characters are
+replaced with @samp{<A>} in this example:
+
+@example
+$ echo aaaabcd | awk '@{ sub(/a+/, "<A>"); print @}'
+@print{} <A>bcd
+@end example
+
+For simple match/no-match tests, this is not so important. But when doing
+text matching and substitutions with the @code{match}, @code{sub}, @code{gsub},
+and @code{gensub} functions, it is very important.
+@ifinfo
+@xref{String Functions},
+for more information on these functions.
+@end ifinfo
+Understanding this principle is also important for regexp-based record
+and field splitting (@pxref{Records},
+and also @pxref{Field Separators}).
+
+@node Computed Regexps
+@section Using Dynamic Regexps
+
+@c STARTOFRANGE dregexp
+@cindex regular expressions, computed
+@c STARTOFRANGE regexpd
+@cindex regular expressions, dynamic
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@c @cindex operators, @code{~}
+@c @cindex operators, @code{!~}
+The righthand side of a @samp{~} or @samp{!~} operator need not be a
+regexp constant (i.e., a string of characters between slashes). It may
+be any expression. The expression is evaluated and converted to a string
+if necessary; the contents of the string are used as the
+regexp. A regexp that is computed in this way is called a @dfn{dynamic
+regexp}:
+
+@example
+BEGIN @{ digits_regexp = "[[:digit:]]+" @}
+$0 ~ digits_regexp @{ print @}
+@end example
+
+@noindent
+This sets @code{digits_regexp} to a regexp that describes one or more digits,
+and tests whether the input record matches this regexp.
+
+@strong{Caution:} When using the @samp{~} and @samp{!~}
+operators, there is a difference between a regexp constant
+enclosed in slashes and a string constant enclosed in double quotes.
+If you are going to use a string constant, you have to understand that
+the string is, in essence, scanned @emph{twice}: the first time when
+@command{awk} reads your program, and the second time when it goes to
+match the string on the lefthand side of the operator with the pattern
+on the right. This is true of any string-valued expression (such as
+@code{digits_regexp}, shown previously), not just string constants.
+
+@cindex regexp constants, slashes vs. quotes
+@cindex @code{\} (backslash), regexp constants
+@cindex backslash (@code{\}), regexp constants
+@cindex @code{"} (double quote), regexp constants
+@cindex double quote (@code{"}), regexp constants
+What difference does it make if the string is
+scanned twice? The answer has to do with escape sequences, and particularly
+with backslashes. To get a backslash into a regular expression inside a
+string, you have to type two backslashes.
+
+For example, @code{/\*/} is a regexp constant for a literal @samp{*}.
+Only one backslash is needed. To do the same thing with a string,
+you have to type @code{"\\*"}. The first backslash escapes the
+second one so that the string actually contains the
+two characters @samp{\} and @samp{*}.
+
+@cindex troubleshooting, regexp constants vs. string constants
+@cindex regexp constants, vs. string constants
+@cindex string constants, vs. regexp constants
+Given that you can use both regexp and string constants to describe
+regular expressions, which should you use? The answer is ``regexp
+constants,'' for several reasons:
+
+@itemize @bullet
+@item
+String constants are more complicated to write and
+more difficult to read. Using regexp constants makes your programs
+less error-prone. Not understanding the difference between the two
+kinds of constants is a common source of errors.
+
+@item
+It is more efficient to use regexp constants. @command{awk} can note
+that you have supplied a regexp and store it internally in a form that
+makes pattern matching more efficient. When using a string constant,
+@command{awk} must first convert the string into this internal form and
+then perform the pattern matching.
+
+@item
+Using regexp constants is better form; it shows clearly that you
+intend a regexp match.
+@end itemize
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Using @code{\n} in Character Lists of Dynamic Regexps
+@cindex regular expressions, dynamic, with embedded newlines
+@cindex newlines, in dynamic regexps
+
+Some commercial versions of @command{awk} do not allow the newline
+character to be used inside a character list for a dynamic regexp:
+
+@example
+$ awk '$0 ~ "[ \t\n]"'
+@error{} awk: newline in character class [
+@error{} ]...
+@error{} source line number 1
+@error{} context is
+@error{} >>> <<<
+@end example
+
+@cindex newlines, in regexp constants
+But a newline in a regexp constant works with no problem:
+
+@example
+$ awk '$0 ~ /[ \t\n]/'
+here is a sample line
+@print{} here is a sample line
+@kbd{@value{CTL}-d}
+@end example
+
+@command{gawk} does not have this problem, and it isn't likely to
+occur often in practice, but it's worth noting for future reference.
+@c ENDOFRANGE dregexp
+@c ENDOFRANGE regexpd
+@c ENDOFRANGE regexp
+
+@node Locales
+@section Where You Are Makes A Difference
+
+Modern systems support the notion of @dfn{locales}: a way to tell
+the system about the local character set and language. The current
+locale setting can affect the way regexp matching works, often
+in surprising ways. In particular, many locales do case-insensitive
+matching, even when you may have specified characters of only
+one particular case.
+
+The following example uses the @code{sub} function, which
+does text replacement
+(@pxref{String Functions}).
+Here, the intent is to remove trailing uppercase characters:
+
+@example
+$ echo something1234abc | gawk '@{ sub("[A-Z]*$", ""); print @}'
+@print{} something1234
+@end example
+
+@noindent
+This output is unexpected, since the @samp{abc} at the end of @samp{something1234abc}
+should not normally match @samp{[A-Z]*}. This result is due to the
+locale setting (and thus you may not see it on your system).
+There are two fixes. The first is to use the POSIX character
+class @samp{[[:upper:]]}, instead of @samp{[A-Z]}.
+The second is to change the locale setting in the environment,
+before running @command{gawk},
+by using the shell statements:
+
+@example
+LANG=C LC_ALL=C
+export LANG LC_ALL
+@end example
+
+The setting @samp{C} forces @command{gawk} to behave in the traditional
+Unix manner, where case distinctions do matter.
+You may wish to put these statements into your shell startup file,
+e.g., @file{$HOME/.profile}.
+
+Similar considerations apply to other ranges. For example,
+@samp{["-/]} is perfectly valid in ASCII, but is not valid in many
+Unicode locales, such as @samp{en_US.UTF-8}. (In general, such
+ranges should be avoided; either list the characters individually,
+or use a POSIX character class such as @samp{[[:punct:]]}.)
+
+For the normal case of @samp{RS = "\n"}, the locale is largely irrelevant.
+For other single byte record separators, using @samp{LC_ALL=C} will give you
+much better performance when reading records. Otherwise, @command{gawk} has
+to make several function calls, @emph{per input character} to find the record
+terminator.
+
+@node Reading Files
+@chapter Reading Input Files
+
+@c STARTOFRANGE infir
+@cindex input files, reading
+@cindex input files
+@cindex @code{FILENAME} variable
+In the typical @command{awk} program, all input is read either from the
+standard input (by default, this is the keyboard, but often it is a pipe from another
+command) or from files whose names you specify on the @command{awk}
+command line. If you specify input files, @command{awk} reads them
+in order, processing all the data from one before going on to the next.
+The name of the current input file can be found in the built-in variable
+@code{FILENAME}
+(@pxref{Built-in Variables}).
+
+@cindex records
+@cindex fields
+The input is read in units called @dfn{records}, and is processed by the
+rules of your program one record at a time.
+By default, each record is one line. Each
+record is automatically split into chunks called @dfn{fields}.
+This makes it more convenient for programs to work on the parts of a record.
+
+@cindex @code{getline} command
+On rare occasions, you may need to use the @code{getline} command.
+The @code{getline} command is valuable, both because it
+can do explicit input from any number of files, and because the files
+used with it do not have to be named on the @command{awk} command line
+(@pxref{Getline}).
+
+@menu
+* Records:: Controlling how data is split into records.
+* Fields:: An introduction to fields.
+* Nonconstant Fields:: Nonconstant Field Numbers.
+* Changing Fields:: Changing the Contents of a Field.
+* Field Separators:: The field separator and how to change it.
+* Constant Size:: Reading constant width data.
+* Multiple Line:: Reading multi-line records.
+* Getline:: Reading files under explicit program control
+ using the @code{getline} function.
+@end menu
+
+@node Records
+@section How Input Is Split into Records
+
+@c STARTOFRANGE inspl
+@cindex input, splitting into records
+@c STARTOFRANGE recspl
+@cindex records, splitting input into
+@cindex @code{NR} variable
+@cindex @code{FNR} variable
+The @command{awk} utility divides the input for your @command{awk}
+program into records and fields.
+@command{awk} keeps track of the number of records that have
+been read
+so far
+from the current input file. This value is stored in a
+built-in variable called @code{FNR}. It is reset to zero when a new
+file is started. Another built-in variable, @code{NR}, is the total
+number of input records read so far from all @value{DF}s. It starts at zero,
+but is never automatically reset to zero.
+
+@cindex separators, for records
+@cindex record separators
+Records are separated by a character called the @dfn{record separator}.
+By default, the record separator is the newline character.
+This is why records are, by default, single lines.
+A different character can be used for the record separator by
+assigning the character to the built-in variable @code{RS}.
+
+@cindex newlines, as record separators
+@cindex @code{RS} variable
+Like any other variable,
+the value of @code{RS} can be changed in the @command{awk} program
+with the assignment operator, @samp{=}
+(@pxref{Assignment Ops}).
+The new record-separator character should be enclosed in quotation marks,
+which indicate a string constant. Often the right time to do this is
+at the beginning of execution, before any input is processed,
+so that the very first record is read with the proper separator.
+To do this, use the special @code{BEGIN} pattern
+(@pxref{BEGIN/END}).
+For example:
+
+@cindex @code{BEGIN} pattern
+@example
+awk 'BEGIN @{ RS = "/" @}
+ @{ print $0 @}' BBS-list
+@end example
+
+@noindent
+changes the value of @code{RS} to @code{"/"}, before reading any input.
+This is a string whose first character is a slash; as a result, records
+are separated by slashes. Then the input file is read, and the second
+rule in the @command{awk} program (the action with no pattern) prints each
+record. Because each @code{print} statement adds a newline at the end of
+its output, this @command{awk} program copies the input
+with each slash changed to a newline. Here are the results of running
+the program on @file{BBS-list}:
+
+@example
+$ awk 'BEGIN @{ RS = "/" @}
+> @{ print $0 @}' BBS-list
+@print{} aardvark 555-5553 1200
+@print{} 300 B
+@print{} alpo-net 555-3412 2400
+@print{} 1200
+@print{} 300 A
+@print{} barfly 555-7685 1200
+@print{} 300 A
+@print{} bites 555-1675 2400
+@print{} 1200
+@print{} 300 A
+@print{} camelot 555-0542 300 C
+@print{} core 555-2912 1200
+@print{} 300 C
+@print{} fooey 555-1234 2400
+@print{} 1200
+@print{} 300 B
+@print{} foot 555-6699 1200
+@print{} 300 B
+@print{} macfoo 555-6480 1200
+@print{} 300 A
+@print{} sdace 555-3430 2400
+@print{} 1200
+@print{} 300 A
+@print{} sabafoo 555-2127 1200
+@print{} 300 C
+@print{}
+@end example
+
+@noindent
+Note that the entry for the @samp{camelot} BBS is not split.
+In the original @value{DF}
+(@pxref{Sample Data Files}),
+the line looks like this:
+
+@example
+camelot 555-0542 300 C
+@end example
+
+@noindent
+It has one baud rate only, so there are no slashes in the record,
+unlike the others which have two or more baud rates.
+In fact, this record is treated as part of the record
+for the @samp{core} BBS; the newline separating them in the output
+is the original newline in the @value{DF}, not the one added by
+@command{awk} when it printed the record!
+
+@cindex record separators, changing
+@cindex separators, for records
+Another way to change the record separator is on the command line,
+using the variable-assignment feature
+(@pxref{Other Arguments}):
+
+@example
+awk '@{ print $0 @}' RS="/" BBS-list
+@end example
+
+@noindent
+This sets @code{RS} to @samp{/} before processing @file{BBS-list}.
+
+Using an unusual character such as @samp{/} for the record separator
+produces correct behavior in the vast majority of cases. However,
+the following (extreme) pipeline prints a surprising @samp{1}:
+
+@example
+$ echo | awk 'BEGIN @{ RS = "a" @} ; @{ print NF @}'
+@print{} 1
+@end example
+
+There is one field, consisting of a newline. The value of the built-in
+variable @code{NF} is the number of fields in the current record.
+
+@cindex dark corner, input files
+Reaching the end of an input file terminates the current input record,
+even if the last character in the file is not the character in @code{RS}.
+@value{DARKCORNER}
+
+@cindex null strings
+@cindex strings, empty, See null strings
+The empty string @code{""} (a string without any characters)
+has a special meaning
+as the value of @code{RS}. It means that records are separated
+by one or more blank lines and nothing else.
+@xref{Multiple Line}, for more details.
+
+If you change the value of @code{RS} in the middle of an @command{awk} run,
+the new value is used to delimit subsequent records, but the record
+currently being processed, as well as records already processed, are not
+affected.
+
+@cindex @code{RT} variable
+@cindex records, terminating
+@cindex terminating records
+@cindex differences in @command{awk} and @command{gawk}, record separators
+@cindex regular expressions, as record separators
+@cindex record separators, regular expressions as
+@cindex separators, for records, regular expressions as
+After the end of the record has been determined, @command{gawk}
+sets the variable @code{RT} to the text in the input that matched
+@code{RS}.
+When using @command{gawk},
+the value of @code{RS} is not limited to a one-character
+string. It can be any regular expression
+(@pxref{Regexp}).
+In general, each record
+ends at the next string that matches the regular expression; the next
+record starts at the end of the matching string. This general rule is
+actually at work in the usual case, where @code{RS} contains just a
+newline: a record ends at the beginning of the next matching string (the
+next newline in the input), and the following record starts just after
+the end of this string (at the first character of the following line).
+The newline, because it matches @code{RS}, is not part of either record.
+
+When @code{RS} is a single character, @code{RT}
+contains the same single character. However, when @code{RS} is a
+regular expression, @code{RT} contains
+the actual input text that matched the regular expression.
+
+The following example illustrates both of these features.
+It sets @code{RS} equal to a regular expression that
+matches either a newline or a series of one or more uppercase letters
+with optional leading and/or trailing whitespace:
+
+@example
+$ echo record 1 AAAA record 2 BBBB record 3 |
+> gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}
+> @{ print "Record =", $0, "and RT =", RT @}'
+@print{} Record = record 1 and RT = AAAA
+@print{} Record = record 2 and RT = BBBB
+@print{} Record = record 3 and RT =
+@print{}
+@end example
+
+@noindent
+The final line of output has an extra blank line. This is because the
+value of @code{RT} is a newline, and the @code{print} statement
+supplies its own terminating newline.
+@xref{Simple Sed}, for a more useful example
+of @code{RS} as a regexp and @code{RT}.
+
+If you set @code{RS} to a regular expression that allows optional
+trailing text, such as @samp{RS = "abc(XYZ)?"} it is possible, due
+to implementation constraints, that @command{gawk} may match the leading
+part of the regular expression, but not the trailing part, particularly
+if the input text that could match the trailing part is fairly long.
+@command{gawk} attempts to avoid this problem, but currently, there's
+no guarantee that this will never happen.
+
+@quotation NOTE
+Remember that in @command{awk}, the @samp{^} and @samp{$} anchor
+metacharacters match the beginning and end of a @emph{string}, and not
+the beginning and end of a @emph{line}. As a result, something like
+@samp{RS = "^[[:upper:]]"} can only match at the beginning of a file.
+This is because @command{gawk} views the input file as one long string
+that happens to contain newline characters in it.
+It is thus best to avoid anchor characters in the value of @code{RS}.
+@end quotation
+
+@cindex differences in @command{awk} and @command{gawk}, @code{RS}/@code{RT} variables
+The use of @code{RS} as a regular expression and the @code{RT}
+variable are @command{gawk} extensions; they are not available in
+compatibility mode
+(@pxref{Options}).
+In compatibility mode, only the first character of the value of
+@code{RS} is used to determine the end of the record.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: @code{RS = "\0"} Is Not Portable
+
+@cindex advanced features, @value{DF}s as single record
+@cindex portability, @value{DF}s as single record
+There are times when you might want to treat an entire @value{DF} as a
+single record. The only way to make this happen is to give @code{RS}
+a value that you know doesn't occur in the input file. This is hard
+to do in a general way, such that a program always works for arbitrary
+input files.
+@c can you say `understatement' boys and girls?
+
+You might think that for text files, the @sc{nul} character, which
+consists of a character with all bits equal to zero, is a good
+value to use for @code{RS} in this case:
+
+@example
+BEGIN @{ RS = "\0" @} # whole file becomes one record?
+@end example
+
+@cindex differences in @command{awk} and @command{gawk}, strings, storing
+@command{gawk} in fact accepts this, and uses the @sc{nul}
+character for the record separator.
+However, this usage is @emph{not} portable
+to other @command{awk} implementations.
+
+@cindex dark corner, strings, storing
+All other @command{awk} implementations@footnote{At least that we know
+about.} store strings internally as C-style strings. C strings use the
+@sc{nul} character as the string terminator. In effect, this means that
+@samp{RS = "\0"} is the same as @samp{RS = ""}.
+@value{DARKCORNER}
+
+@cindex records, treating files as
+@cindex files, as single records
+The best way to treat a whole file as a single record is to
+simply read the file in, one record at a time, concatenating each
+record onto the end of the previous ones.
+@c ENDOFRANGE inspl
+@c ENDOFRANGE recspl
+
+@node Fields
+@section Examining Fields
+
+@cindex examining fields
+@cindex fields
+@cindex accessing fields
+@c STARTOFRANGE fiex
+@cindex fields, examining
+@cindex POSIX @command{awk}, field separators and
+@cindex field separators, POSIX and
+@cindex separators, field, POSIX and
+When @command{awk} reads an input record, the record is
+automatically @dfn{parsed} or separated by the interpreter into chunks
+called @dfn{fields}. By default, fields are separated by @dfn{whitespace},
+like words in a line.
+Whitespace in @command{awk} means any string of one or more spaces,
+tabs, or newlines;@footnote{In POSIX @command{awk}, newlines are not
+considered whitespace for separating fields.} other characters, such as
+formfeed, vertical tab, etc.@: that are
+considered whitespace by other languages, are @emph{not} considered
+whitespace by @command{awk}.
+
+The purpose of fields is to make it more convenient for you to refer to
+these pieces of the record. You don't have to use them---you can
+operate on the whole record if you want---but fields are what make
+simple @command{awk} programs so powerful.
+
+@cindex @code{$} field operator
+@cindex field operator @code{$}
+@cindex @code{$} (dollar sign), @code{$} field operator
+@cindex dollar sign (@code{$}), @code{$} field operator
+@cindex field operators@comma{} dollar sign as
+A dollar-sign (@samp{$}) is used
+to refer to a field in an @command{awk} program,
+followed by the number of the field you want. Thus, @code{$1}
+refers to the first field, @code{$2} to the second, and so on.
+(Unlike the Unix shells, the field numbers are not limited to single digits.
+@code{$127} is the one hundred twenty-seventh field in the record.)
+For example, suppose the following is a line of input:
+
+@example
+This seems like a pretty nice example.
+@end example
+
+@noindent
+Here the first field, or @code{$1}, is @samp{This}, the second field, or
+@code{$2}, is @samp{seems}, and so on. Note that the last field,
+@code{$7}, is @samp{example.}. Because there is no space between the
+@samp{e} and the @samp{.}, the period is considered part of the seventh
+field.
+
+@cindex @code{NF} variable
+@cindex fields, number of
+@code{NF} is a built-in variable whose value is the number of fields
+in the current record. @command{awk} automatically updates the value
+of @code{NF} each time it reads a record. No matter how many fields
+there are, the last field in a record can be represented by @code{$NF}.
+So, @code{$NF} is the same as @code{$7}, which is @samp{example.}.
+If you try to reference a field beyond the last
+one (such as @code{$8} when the record has only seven fields), you get
+the empty string. (If used in a numeric operation, you get zero.)
+
+The use of @code{$0}, which looks like a reference to the ``zero-th'' field, is
+a special case: it represents the whole input record
+when you are not interested in specific fields.
+Here are some more examples:
+
+@example
+$ awk '$1 ~ /foo/ @{ print $0 @}' BBS-list
+@print{} fooey 555-1234 2400/1200/300 B
+@print{} foot 555-6699 1200/300 B
+@print{} macfoo 555-6480 1200/300 A
+@print{} sabafoo 555-2127 1200/300 C
+@end example
+
+@noindent
+This example prints each record in the file @file{BBS-list} whose first
+field contains the string @samp{foo}. The operator @samp{~} is called a
+@dfn{matching operator}
+(@pxref{Regexp Usage});
+it tests whether a string (here, the field @code{$1}) matches a given regular
+expression.
+
+By contrast, the following example
+looks for @samp{foo} in @emph{the entire record} and prints the first
+field and the last field for each matching input record:
+
+@example
+$ awk '/foo/ @{ print $1, $NF @}' BBS-list
+@print{} fooey B
+@print{} foot B
+@print{} macfoo A
+@print{} sabafoo C
+@end example
+@c ENDOFRANGE fiex
+
+@node Nonconstant Fields
+@section Nonconstant Field Numbers
+@cindex fields, numbers
+@cindex field numbers
+
+The number of a field does not need to be a constant. Any expression in
+the @command{awk} language can be used after a @samp{$} to refer to a
+field. The value of the expression specifies the field number. If the
+value is a string, rather than a number, it is converted to a number.
+Consider this example:
+
+@example
+awk '@{ print $NR @}'
+@end example
+
+@noindent
+Recall that @code{NR} is the number of records read so far: one in the
+first record, two in the second, etc. So this example prints the first
+field of the first record, the second field of the second record, and so
+on. For the twentieth record, field number 20 is printed; most likely,
+the record has fewer than 20 fields, so this prints a blank line.
+Here is another example of using expressions as field numbers:
+
+@example
+awk '@{ print $(2*2) @}' BBS-list
+@end example
+
+@command{awk} evaluates the expression @samp{(2*2)} and uses
+its value as the number of the field to print. The @samp{*} sign
+represents multiplication, so the expression @samp{2*2} evaluates to four.
+The parentheses are used so that the multiplication is done before the
+@samp{$} operation; they are necessary whenever there is a binary
+operator in the field-number expression. This example, then, prints the
+hours of operation (the fourth field) for every line of the file
+@file{BBS-list}. (All of the @command{awk} operators are listed, in
+order of decreasing precedence, in
+@ref{Precedence}.)
+
+If the field number you compute is zero, you get the entire record.
+Thus, @samp{$(2-2)} has the same value as @code{$0}. Negative field
+numbers are not allowed; trying to reference one usually terminates
+the program. (The POSIX standard does not define
+what happens when you reference a negative field number. @command{gawk}
+notices this and terminates your program. Other @command{awk}
+implementations may behave differently.)
+
+As mentioned in @ref{Fields},
+@command{awk} stores the current record's number of fields in the built-in
+variable @code{NF} (also @pxref{Built-in Variables}). The expression
+@code{$NF} is not a special feature---it is the direct consequence of
+evaluating @code{NF} and using its value as a field number.
+
+@node Changing Fields
+@section Changing the Contents of a Field
+
+@c STARTOFRANGE ficon
+@cindex fields, changing contents of
+The contents of a field, as seen by @command{awk}, can be changed within an
+@command{awk} program; this changes what @command{awk} perceives as the
+current input record. (The actual input is untouched; @command{awk} @emph{never}
+modifies the input file.)
+Consider the following example and its output:
+
+@example
+$ awk '@{ nboxes = $3 ; $3 = $3 - 10
+> print nboxes, $3 @}' inventory-shipped
+@print{} 25 15
+@print{} 32 22
+@print{} 24 14
+@dots{}
+@end example
+
+@noindent
+The program first saves the original value of field three in the variable
+@code{nboxes}.
+The @samp{-} sign represents subtraction, so this program reassigns
+field three, @code{$3}, as the original value of field three minus ten:
+@samp{$3 - 10}. (@xref{Arithmetic Ops}.)
+Then it prints the original and new values for field three.
+(Someone in the warehouse made a consistent mistake while inventorying
+the red boxes.)
+
+For this to work, the text in field @code{$3} must make sense
+as a number; the string of characters must be converted to a number
+for the computer to do arithmetic on it. The number resulting
+from the subtraction is converted back to a string of characters that
+then becomes field three.
+@xref{Conversion}.
+
+When the value of a field is changed (as perceived by @command{awk}), the
+text of the input record is recalculated to contain the new field where
+the old one was. In other words, @code{$0} changes to reflect the altered
+field. Thus, this program
+prints a copy of the input file, with 10 subtracted from the second
+field of each line:
+
+@example
+$ 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
+
+It is also possible to also assign contents to fields that are out
+of range. For example:
+
+@example
+$ awk '@{ $6 = ($5 + $4 + $3 + $2)
+> print $6 @}' inventory-shipped
+@print{} 168
+@print{} 297
+@print{} 301
+@dots{}
+@end example
+
+@cindex adding, fields
+@cindex fields, adding
+@noindent
+We've just created @code{$6}, whose value is the sum of fields
+@code{$2}, @code{$3}, @code{$4}, and @code{$5}. The @samp{+} sign
+represents addition. For the file @file{inventory-shipped}, @code{$6}
+represents the total number of parcels shipped for a particular month.
+
+Creating a new field changes @command{awk}'s internal copy of the current
+input record, which is the value of @code{$0}. Thus, if you do @samp{print $0}
+after adding a field, the record printed includes the new field, with
+the appropriate number of field separators between it and the previously
+existing fields.
+
+@cindex @code{OFS} variable
+@cindex output field separator, See @code{OFS} variable
+@cindex field separators, See Also @code{OFS}
+This recomputation affects and is affected by
+@code{NF} (the number of fields; @pxref{Fields}).
+For example, the value of @code{NF} is set to the number of the highest
+field you create.
+The exact format of @code{$0} is also affected by a feature that has not been discussed yet:
+the @dfn{output field separator}, @code{OFS},
+used to separate the fields (@pxref{Output Separators}).
+
+Note, however, that merely @emph{referencing} an out-of-range field
+does @emph{not} change the value of either @code{$0} or @code{NF}.
+Referencing an out-of-range field only produces an empty string. For
+example:
+
+@example
+if ($(NF+1) != "")
+ print "can't happen"
+else
+ print "everything is normal"
+@end example
+
+@noindent
+should print @samp{everything is normal}, because @code{NF+1} is certain
+to be out of range. (@xref{If Statement},
+for more information about @command{awk}'s @code{if-else} statements.
+@xref{Typing and Comparison},
+for more information about the @samp{!=} operator.)
+
+It is important to note that making an assignment to an existing field
+changes the
+value of @code{$0} but does not change the value of @code{NF},
+even when you assign the empty string to a field. For example:
+
+@example
+$ echo a b c d | awk '@{ OFS = ":"; $2 = ""
+> print $0; print NF @}'
+@print{} a::c:d
+@print{} 4
+@end example
+
+@noindent
+The field is still there; it just has an empty value, denoted by
+the two colons between @samp{a} and @samp{c}.
+This example shows what happens if you create a new field:
+
+@example
+$ echo a b c d | awk '@{ OFS = ":"; $2 = ""; $6 = "new"
+> print $0; print NF @}'
+@print{} a::c:d::new
+@print{} 6
+@end example
+
+@noindent
+The intervening field, @code{$5}, is created with an empty value
+(indicated by the second pair of adjacent colons),
+and @code{NF} is updated with the value six.
+
+@c FIXME: Verify that this is in POSIX
+@cindex dark corner, @code{NF} variable, decrementing
+@cindex @code{NF} variable, decrementing
+Decrementing @code{NF} throws away the values of the fields
+after the new value of @code{NF} and recomputes @code{$0}.
+@value{DARKCORNER}
+Here is an example:
+
+@example
+$ echo a b c d e f | awk '@{ print "NF =", NF;
+> NF = 3; print $0 @}'
+@print{} NF = 6
+@print{} a b c
+@end example
+
+@cindex portability, @code{NF} variable@comma{} decrementing
+@strong{Caution:} Some versions of @command{awk} don't
+rebuild @code{$0} when @code{NF} is decremented. Caveat emptor.
+
+Finally, there are times when it is convenient to force
+@command{awk} to rebuild the entire record, using the current
+value of the fields and @code{OFS}. To do this, use the
+seemingly innocuous assignment:
+
+@example
+$1 = $1 # force record to be reconstituted
+print $0 # or whatever else with $0
+@end example
+
+@noindent
+This forces @command{awk} rebuild the record. It does help
+to add a comment, as we've shown here.
+
+There is a flip side to the relationship between @code{$0} and
+the fields. Any assignment to @code{$0} causes the record to be
+reparsed into fields using the @emph{current} value of @code{FS}.
+This also applies to any built-in function that updates @code{$0},
+such as @code{sub} and @code{gsub}
+(@pxref{String Functions}).
+@c ENDOFRANGE ficon
+
+@node Field Separators
+@section Specifying How Fields Are Separated
+
+@menu
+* Regexp Field Splitting:: Using regexps as the field separator.
+* Single Character Fields:: Making each character a separate field.
+* Command Line Field Separator:: Setting @code{FS} from the command-line.
+* Field Splitting Summary:: Some final points and a summary table.
+@end menu
+
+@cindex @code{FS} variable
+@cindex fields, separating
+@c STARTOFRANGE fisepr
+@cindex field separators
+@c STARTOFRANGE fisepg
+@cindex fields, separating
+The @dfn{field separator}, which is either a single character or a regular
+expression, controls the way @command{awk} splits an input record into fields.
+@command{awk} scans the input record for character sequences that
+match the separator; the fields themselves are the text between the matches.
+
+In the examples that follow, we use the bullet symbol (@bullet{}) to
+represent spaces in the output.
+If the field separator is @samp{oo}, then the following line:
+
+@example
+moo goo gai pan
+@end example
+
+@noindent
+is split into three fields: @samp{m}, @samp{@bullet{}g}, and
+@samp{@bullet{}gai@bullet{}pan}.
+Note the leading spaces in the values of the second and third fields.
+
+@cindex troubleshooting, @command{awk} uses @code{FS} not @code{IFS}
+The field separator is represented by the built-in variable @code{FS}.
+Shell programmers take note: @command{awk} does @emph{not} use the
+name @code{IFS} that is used by the POSIX-compliant shells (such as
+the Unix Bourne shell, @command{sh}, or @command{bash}).
+
+@cindex @code{FS} variable, changing value of
+The value of @code{FS} can be changed in the @command{awk} program with the
+assignment operator, @samp{=} (@pxref{Assignment Ops}).
+Often the right time to do this is at the beginning of execution
+before any input has been processed, so that the very first record
+is read with the proper separator. To do this, use the special
+@code{BEGIN} pattern
+(@pxref{BEGIN/END}).
+For example, here we set the value of @code{FS} to the string
+@code{","}:
+
+@example
+awk 'BEGIN @{ FS = "," @} ; @{ print $2 @}'
+@end example
+
+@cindex @code{BEGIN} pattern
+@noindent
+Given the input line:
+
+@example
+John Q. Smith, 29 Oak St., Walamazoo, MI 42139
+@end example
+
+@noindent
+this @command{awk} program extracts and prints the string
+@samp{@bullet{}29@bullet{}Oak@bullet{}St.}.
+
+@cindex field separators, choice of
+@cindex regular expressions as field separators
+@cindex field separators, regular expressions as
+Sometimes the input data contains separator characters that don't
+separate fields the way you thought they would. For instance, the
+person's name in the example we just used might have a title or
+suffix attached, such as:
+
+@example
+John Q. Smith, LXIX, 29 Oak St., Walamazoo, MI 42139
+@end example
+
+@noindent
+The same program would extract @samp{@bullet{}LXIX}, instead of
+@samp{@bullet{}29@bullet{}Oak@bullet{}St.}.
+If you were expecting the program to print the
+address, you would be surprised. The moral is to choose your data layout and
+separator characters carefully to prevent such problems.
+(If the data is not in a form that is easy to process, perhaps you
+can massage it first with a separate @command{awk} program.)
+
+@cindex newlines, as field separators
+@cindex whitespace, as field separators
+Fields are normally separated by whitespace sequences
+(spaces, tabs, and newlines), not by single spaces. Two spaces in a row do not
+delimit an empty field. The default value of the field separator @code{FS}
+is a string containing a single space, @w{@code{" "}}. If @command{awk}
+interpreted this value in the usual way, each space character would separate
+fields, so two spaces in a row would make an empty field between them.
+The reason this does not happen is that a single space as the value of
+@code{FS} is a special case---it is taken to specify the default manner
+of delimiting fields.
+
+If @code{FS} is any other single character, such as @code{","}, then
+each occurrence of that character separates two fields. Two consecutive
+occurrences delimit an empty field. If the character occurs at the
+beginning or the end of the line, that too delimits an empty field. The
+space character is the only single character that does not follow these
+rules.
+
+@node Regexp Field Splitting
+@subsection Using Regular Expressions to Separate Fields
+
+@c STARTOFRANGE regexpfs
+@cindex regular expressions, as field separators
+@c STARTOFRANGE fsregexp
+@cindex field separators, regular expressions as
+The previous @value{SUBSECTION}
+discussed the use of single characters or simple strings as the
+value of @code{FS}.
+More generally, the value of @code{FS} may be a string containing any
+regular expression. In this case, each match in the record for the regular
+expression separates fields. For example, the assignment:
+
+@example
+FS = ", \t"
+@end example
+
+@noindent
+makes every area of an input line that consists of a comma followed by a
+space and a TAB into a field separator.
+@ifinfo
+(@samp{\t}
+is an @dfn{escape sequence} that stands for a TAB;
+@pxref{Escape Sequences},
+for the complete list of similar escape sequences.)
+@end ifinfo
+
+For a less trivial example of a regular expression, try using
+single spaces to separate fields the way single commas are used.
+@code{FS} can be set to @w{@code{"[@ ]"}} (left bracket, space, right
+bracket). This regular expression matches a single space and nothing else
+(@pxref{Regexp}).
+
+There is an important difference between the two cases of @samp{FS = @w{" "}}
+(a single space) and @samp{FS = @w{"[ \t\n]+"}}
+(a regular expression matching one or more spaces, tabs, or newlines).
+For both values of @code{FS}, fields are separated by @dfn{runs}
+(multiple adjacent occurrences) of spaces, tabs,
+and/or newlines. However, when the value of @code{FS} is @w{@code{" "}},
+@command{awk} first strips leading and trailing whitespace from
+the record and then decides where the fields are.
+For example, the following pipeline prints @samp{b}:
+
+@example
+$ echo ' a b c d ' | awk '@{ print $2 @}'
+@print{} b
+@end example
+
+@noindent
+However, this pipeline prints @samp{a} (note the extra spaces around
+each letter):
+
+@example
+$ echo ' a b c d ' | awk 'BEGIN @{ FS = "[ \t\n]+" @}
+> @{ print $2 @}'
+@print{} a
+@end example
+
+@noindent
+@cindex null strings
+@cindex strings, null
+@cindex empty strings, See null strings
+In this case, the first field is @dfn{null} or empty.
+
+The stripping of leading and trailing whitespace also comes into
+play whenever @code{$0} is recomputed. For instance, study this pipeline:
+
+@example
+$ echo ' a b c d' | awk '@{ print; $2 = $2; print @}'
+@print{} a b c d
+@print{} a b c d
+@end example
+
+@noindent
+The first @code{print} statement prints the record as it was read,
+with leading whitespace intact. The assignment to @code{$2} rebuilds
+@code{$0} by concatenating @code{$1} through @code{$NF} together,
+separated by the value of @code{OFS}. Because the leading whitespace
+was ignored when finding @code{$1}, it is not part of the new @code{$0}.
+Finally, the last @code{print} statement prints the new @code{$0}.
+@c ENDOFRANGE regexpfs
+@c ENDOFRANGE fsregexp
+
+@node Single Character Fields
+@subsection Making Each Character a Separate Field
+
+@cindex differences in @command{awk} and @command{gawk}, single-character fields
+@cindex single-character fields
+@cindex fields, single-character
+There are times when you may want to examine each character
+of a record separately. This can be done in @command{gawk} by
+simply assigning the null string (@code{""}) to @code{FS}. In this case,
+each individual character in the record becomes a separate field.
+For example:
+
+@example
+$ echo a b | gawk 'BEGIN @{ FS = "" @}
+> @{
+> for (i = 1; i <= NF; i = i + 1)
+> print "Field", i, "is", $i
+> @}'
+@print{} Field 1 is a
+@print{} Field 2 is
+@print{} Field 3 is b
+@end example
+
+@cindex dark corner, @code{FS} as null string
+@cindex FS variable, as null string
+Traditionally, the behavior of @code{FS} equal to @code{""} was not defined.
+In this case, most versions of Unix @command{awk} simply treat the entire record
+as only having one field.
+@value{DARKCORNER}
+In compatibility mode
+(@pxref{Options}),
+if @code{FS} is the null string, then @command{gawk} also
+behaves this way.
+
+@node Command Line Field Separator
+@subsection Setting @code{FS} from the Command Line
+@cindex @code{-F} option
+@cindex options, command-line
+@cindex command line, options
+@cindex field separators, on command line
+@cindex command line, @code{FS} on@comma{} setting
+@cindex @code{FS} variable, setting from command line
+
+@code{FS} can be set on the command line. Use the @option{-F} option to
+do so. For example:
+
+@example
+awk -F, '@var{program}' @var{input-files}
+@end example
+
+@noindent
+sets @code{FS} to the @samp{,} character. Notice that the option uses
+an uppercase @samp{F} instead of a lowercase @samp{f}. The latter
+option (@option{-f}) specifies a file
+containing an @command{awk} program. Case is significant in command-line
+options:
+the @option{-F} and @option{-f} options have nothing to do with each other.
+You can use both options at the same time to set the @code{FS} variable
+@emph{and} get an @command{awk} program from a file.
+
+The value used for the argument to @option{-F} is processed in exactly the
+same way as assignments to the built-in variable @code{FS}.
+Any special characters in the field separator must be escaped
+appropriately. For example, to use a @samp{\} as the field separator
+on the command line, you would have to type:
+
+@example
+# same as FS = "\\"
+awk -F\\\\ '@dots{}' files @dots{}
+@end example
+
+@noindent
+@cindex @code{\} (backslash), as field separators
+@cindex backslash (@code{\}), as field separators
+Because @samp{\} is used for quoting in the shell, @command{awk} sees
+@samp{-F\\}. Then @command{awk} processes the @samp{\\} for escape
+characters (@pxref{Escape Sequences}), finally yielding
+a single @samp{\} to use for the field separator.
+
+@c @cindex historical features
+As a special case, in compatibility mode
+(@pxref{Options}),
+if the argument to @option{-F} is @samp{t}, then @code{FS} is set to
+the TAB character. If you type @samp{-F\t} at the
+shell, without any quotes, the @samp{\} gets deleted, so @command{awk}
+figures that you really want your fields to be separated with tabs and
+not @samp{t}s. Use @samp{-v FS="t"} or @samp{-F"[t]"} on the command line
+if you really do want to separate your fields with @samp{t}s.
+
+For example, let's use an @command{awk} program file called @file{baud.awk}
+that contains the pattern @code{/300/} and the action @samp{print $1}:
+
+@example
+/300/ @{ print $1 @}
+@end example
+
+Let's also set @code{FS} to be the @samp{-} character and run the
+program on the file @file{BBS-list}. The following command prints a
+list of the names of the bulletin boards that operate at 300 baud and
+the first three digits of their phone numbers:
+
+@c tweaked to make the tex output look better in @smallbook
+@example
+$ awk -F- -f baud.awk BBS-list
+@print{} aardvark 555
+@print{} alpo
+@print{} barfly 555
+@print{} bites 555
+@print{} camelot 555
+@print{} core 555
+@print{} fooey 555
+@print{} foot 555
+@print{} macfoo 555
+@print{} sdace 555
+@print{} sabafoo 555
+@end example
+
+@noindent
+Note the second line of output. The second line
+in the original file looked like this:
+
+@example
+alpo-net 555-3412 2400/1200/300 A
+@end example
+
+The @samp{-} as part of the system's name was used as the field
+separator, instead of the @samp{-} in the phone number that was
+originally intended. This demonstrates why you have to be careful in
+choosing your field and record separators.
+
+@cindex Unix @command{awk}, password files@comma{} field separators and
+Perhaps the most common use of a single character as the field
+separator occurs when processing the Unix system password file.
+On many Unix systems, each user has a separate entry in the system password
+file, one line per user. The information in these lines is separated
+by colons. The first field is the user's logon name and the second is
+the user's (encrypted or shadow) password. A password file entry might look
+like this:
+
+@cindex Robbins, Arnold
+@example
+arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/bash
+@end example
+
+The following program searches the system password file and prints
+the entries for users who have no password:
+
+@example
+awk -F: '$2 == ""' /etc/passwd
+@end example
+
+@node Field Splitting Summary
+@subsection Field-Splitting Summary
+
+It is important to remember that when you assign a string constant
+as the value of @code{FS}, it undergoes normal @command{awk} string
+processing. For example, with Unix @command{awk} and @command{gawk},
+the assignment @samp{FS = "\.."} assigns the character string @code{".."}
+to @code{FS} (the backslash is stripped). This creates a regexp meaning
+``fields are separated by occurrences of any two characters.''
+If instead you want fields to be separated by a literal period followed
+by any single character, use @samp{FS = "\\.."}.
+
+The following table summarizes how fields are split, based on the value
+of @code{FS} (@samp{==} means ``is equal to''):
+
+@table @code
+@item FS == " "
+Fields are separated by runs of whitespace. Leading and trailing
+whitespace are ignored. This is the default.
+
+@item FS == @var{any other single character}
+Fields are separated by each occurrence of the character. Multiple
+successive occurrences delimit empty fields, as do leading and
+trailing occurrences.
+The character can even be a regexp metacharacter; it does not need
+to be escaped.
+
+@item FS == @var{regexp}
+Fields are separated by occurrences of characters that match @var{regexp}.
+Leading and trailing matches of @var{regexp} delimit empty fields.
+
+@item FS == ""
+Each individual character in the record becomes a separate field.
+(This is a @command{gawk} extension; it is not specified by the
+POSIX standard.)
+@end table
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Changing @code{FS} Does Not Affect the Fields
+
+@cindex POSIX @command{awk}, field separators and
+@cindex field separators, POSIX and
+According to the POSIX standard, @command{awk} is supposed to behave
+as if each record is split into fields at the time it is read.
+In particular, this means that if you change the value of @code{FS}
+after a record is read, the value of the fields (i.e., how they were split)
+should reflect the old value of @code{FS}, not the new one.
+
+@cindex dark corner, field separators
+@cindex @command{sed} utility
+@cindex stream editors
+However, many implementations of @command{awk} do not work this way. Instead,
+they defer splitting the fields until a field is actually
+referenced. The fields are split
+using the @emph{current} value of @code{FS}!
+@value{DARKCORNER}
+This behavior can be difficult
+to diagnose. The following example illustrates the difference
+between the two methods.
+(The @command{sed}@footnote{The @command{sed} utility is a ``stream editor.''
+Its behavior is also defined by the POSIX standard.}
+command prints just the first line of @file{/etc/passwd}.)
+
+@example
+sed 1q /etc/passwd | awk '@{ FS = ":" ; print $1 @}'
+@end example
+
+@noindent
+which usually prints:
+
+@example
+root
+@end example
+
+@noindent
+on an incorrect implementation of @command{awk}, while @command{gawk}
+prints something like:
+
+@example
+root:nSijPlPhZZwgE:0:0:Root:/:
+@end example
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: @code{FS} and @code{IGNORECASE}
+
+The @code{IGNORECASE} variable
+(@pxref{User-modified})
+affects field splitting @emph{only} when the value of @code{FS} is a regexp.
+It has no effect when @code{FS} is a single character, even if
+that character is a letter. Thus, in the following code:
+
+@example
+FS = "c"
+IGNORECASE = 1
+$0 = "aCa"
+print $1
+@end example
+
+@noindent
+The output is @samp{aCa}. If you really want to split fields on an
+alphabetic character while ignoring case, use a regexp that will
+do it for you. E.g., @samp{FS = "[c]"}. In this case, @code{IGNORECASE}
+will take effect.
+
+@c ENDOFRANGE fisepr
+@c ENDOFRANGE fisepg
+
+@node Constant Size
+@section Reading Fixed-Width Data
+
+@ifnotinfo
+@quotation NOTE
+This @value{SECTION} discusses an advanced
+feature of @command{gawk}. If you are a novice @command{awk} user,
+you might want to skip it on the first reading.
+@end quotation
+@end ifnotinfo
+
+@ifinfo
+(This @value{SECTION} discusses an advanced feature of @command{awk}.
+If you are a novice @command{awk} user, you might want to skip it on
+the first reading.)
+@end ifinfo
+
+@cindex data, fixed-width
+@cindex fixed-width data
+@cindex advanced features, fixed-width data
+@command{gawk} @value{PVERSION} 2.13 introduced a facility for dealing with
+fixed-width fields with no distinctive field separator. For example,
+data of this nature arises in the input for old Fortran programs where
+numbers are run together, or in the output of programs that did not
+anticipate the use of their output as input for other programs.
+
+An example of the latter is a table where all the columns are lined up by
+the use of a variable number of spaces and @emph{empty fields are just
+spaces}. Clearly, @command{awk}'s normal field splitting based on @code{FS}
+does not work well in this case. Although a portable @command{awk} program
+can use a series of @code{substr} calls on @code{$0}
+(@pxref{String Functions}),
+this is awkward and inefficient for a large number of fields.
+
+@cindex troubleshooting, fatal errors, field widths@comma{} specifying
+@cindex @command{w} utility
+@cindex @code{FIELDWIDTHS} variable
+The splitting of an input record into fixed-width fields is specified by
+assigning a string containing space-separated numbers to the built-in
+variable @code{FIELDWIDTHS}. Each number specifies the width of the field,
+@emph{including} columns between fields. If you want to ignore the columns
+between fields, you can specify the width as a separate field that is
+subsequently ignored.
+It is a fatal error to supply a field width that is not a positive number.
+The following data is the output of the Unix @command{w} utility. It is useful
+to illustrate the use of @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
+
+The following program takes the above input, converts the idle time to
+number of seconds, and prints out the first two fields and the calculated
+idle time:
+
+@quotation NOTE
+This program uses a number of @command{awk} features that
+haven't been introduced yet.
+@end quotation
+
+@example
+BEGIN @{ FIELDWIDTHS = "9 6 10 6 7 7 35" @}
+NR > 2 @{
+ idle = $4
+ sub(/^ */, "", idle) # strip leading spaces
+ if (idle == "")
+ idle = 0
+ if (idle ~ /:/) @{
+ split(idle, t, ":")
+ idle = t[1] * 60 + t[2]
+ @}
+ if (idle ~ /days/)
+ idle *= 24 * 60 * 60
+
+ print $1, $2, idle
+@}
+@end example
+
+Running the program on the data produces the following results:
+
+@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
+
+Another (possibly more practical) example of fixed-width input data
+is the input from a deck of balloting cards. In some parts of
+the United States, voters mark their choices by punching holes in computer
+cards. These cards are then processed to count the votes for any particular
+candidate or on any particular issue. Because a voter may choose not to
+vote on some issue, any column on the card may be empty. An @command{awk}
+program for processing such data could use the @code{FIELDWIDTHS} feature
+to simplify reading the data. (Of course, getting @command{gawk} to run on
+a system with card readers is another story!)
+
+@ignore
+Exercise: Write a ballot card reading program
+@end ignore
+
+@cindex @command{gawk}, splitting fields and
+Assigning a value to @code{FS} causes @command{gawk} to use
+@code{FS} for field splitting again. Use @samp{FS = FS} to make this happen,
+without having to know the current value of @code{FS}.
+In order to tell which kind of field splitting is in effect,
+use @code{PROCINFO["FS"]}
+(@pxref{Auto-set}).
+The value is @code{"FS"} if regular field splitting is being used,
+or it is @code{"FIELDWIDTHS"} if fixed-width field splitting is being used:
+
+@example
+if (PROCINFO["FS"] == "FS")
+ @var{regular field splitting} @dots{}
+else
+ @var{fixed-width field splitting} @dots{}
+@end example
+
+This information is useful when writing a function
+that needs to temporarily change @code{FS} or @code{FIELDWIDTHS},
+read some records, and then restore the original settings
+(@pxref{Passwd Functions},
+for an example of such a function).
+
+@node Multiple Line
+@section Multiple-Line Records
+
+@c STARTOFRANGE recm
+@cindex records, multiline
+@c STARTOFRANGE imr
+@cindex input, multiline records
+@c STARTOFRANGE frm
+@cindex files, reading, multiline records
+@cindex input, files, See input files
+In some databases, a single line cannot conveniently hold all the
+information in one entry. In such cases, you can use multiline
+records. The first step in doing this is to choose your data format.
+
+@cindex record separators, with multiline records
+One technique is to use an unusual character or string to separate
+records. For example, you could use the formfeed character (written
+@samp{\f} in @command{awk}, as in C) to separate them, making each record
+a page of the file. To do this, just set the variable @code{RS} to
+@code{"\f"} (a string containing the formfeed character). Any
+other character could equally well be used, as long as it won't be part
+of the data in a record.
+
+@cindex @code{RS} variable, multiline records and
+Another technique is to have blank lines separate records. By a special
+dispensation, an empty string as the value of @code{RS} indicates that
+records are separated by one or more blank lines. When @code{RS} is set
+to the empty string, each record always ends at the first blank line
+encountered. The next record doesn't start until the first nonblank
+line that follows. No matter how many blank lines appear in a row, they
+all act as one record separator.
+(Blank lines must be completely empty; lines that contain only
+whitespace do not count.)
+
+@cindex leftmost longest match
+@cindex matching, leftmost longest
+You can achieve the same effect as @samp{RS = ""} by assigning the
+string @code{"\n\n+"} to @code{RS}. This regexp matches the newline
+at the end of the record and one or more blank lines after the record.
+In addition, a regular expression always matches the longest possible
+sequence when there is a choice
+(@pxref{Leftmost Longest}).
+So the next record doesn't start until
+the first nonblank line that follows---no matter how many blank lines
+appear in a row, they are considered one record separator.
+
+@cindex dark corner, multiline records
+There is an important difference between @samp{RS = ""} and
+@samp{RS = "\n\n+"}. In the first case, leading newlines in the input
+@value{DF} are ignored, and if a file ends without extra blank lines
+after the last record, the final newline is removed from the record.
+In the second case, this special processing is not done.
+@value{DARKCORNER}
+
+@cindex field separators, in multiline records
+Now that the input is separated into records, the second step is to
+separate the fields in the record. One way to do this is to divide each
+of the lines into fields in the normal manner. This happens by default
+as the result of a special feature. When @code{RS} is set to the empty
+string, @emph{and} @code{FS} is a set to a single character,
+the newline character @emph{always} acts as a field separator.
+This is in addition to whatever field separations result from
+@code{FS}.@footnote{When @code{FS} is the null string (@code{""})
+or a regexp, this special feature of @code{RS} does not apply.
+It does apply to the default field separator of a single space:
+@samp{FS = " "}.}
+
+The original motivation for this special exception was probably to provide
+useful behavior in the default case (i.e., @code{FS} is equal
+to @w{@code{" "}}). This feature can be a problem if you really don't
+want the newline character to separate fields, because there is no way to
+prevent it. However, you can work around this by using the @code{split}
+function to break up the record manually
+(@pxref{String Functions}).
+If you have a single character field separator, you can work around
+the special feature in a different way, by making @code{FS} into a
+regexp for that single character. For example, if the field
+separator is a percent character, instead of
+@samp{FS = "%"}, use @samp{FS = "[%]"}.
+
+Another way to separate fields is to
+put each field on a separate line: to do this, just set the
+variable @code{FS} to the string @code{"\n"}. (This single
+character seperator matches a single newline.)
+A practical example of a @value{DF} organized this way might be a mailing
+list, where each entry is separated by blank lines. Consider a mailing
+list in a file named @file{addresses}, which looks like this:
+
+@example
+Jane Doe
+123 Main Street
+Anywhere, SE 12345-6789
+
+John Smith
+456 Tree-lined Avenue
+Smallville, MW 98765-4321
+@dots{}
+@end example
+
+@noindent
+A simple program to process this file is as follows:
+
+@example
+# addrs.awk --- simple mailing list program
+
+# Records are separated by blank lines.
+# Each line is one field.
+BEGIN @{ RS = "" ; FS = "\n" @}
+
+@{
+ print "Name is:", $1
+ print "Address is:", $2
+ print "City and State are:", $3
+ print ""
+@}
+@end example
+
+Running the program produces the following output:
+
+@example
+$ awk -f addrs.awk addresses
+@print{} Name is: Jane Doe
+@print{} Address is: 123 Main Street
+@print{} City and State are: Anywhere, SE 12345-6789
+@print{}
+@print{} Name is: John Smith
+@print{} Address is: 456 Tree-lined Avenue
+@print{} City and State are: Smallville, MW 98765-4321
+@print{}
+@dots{}
+@end example
+
+@xref{Labels Program}, for a more realistic
+program that deals with address lists.
+The following
+table
+summarizes how records are split, based on the
+value of
+@ifinfo
+@code{RS}.
+(@samp{==} means ``is equal to.'')
+@end ifinfo
+@ifnotinfo
+@code{RS}:
+@end ifnotinfo
+
+@table @code
+@item RS == "\n"
+Records are separated by the newline character (@samp{\n}). In effect,
+every line in the @value{DF} is a separate record, including blank lines.
+This is the default.
+
+@item RS == @var{any single character}
+Records are separated by each occurrence of the character. Multiple
+successive occurrences delimit empty records.
+
+@item RS == ""
+Records are separated by runs of blank lines. The newline character
+always serves as a field separator, in addition to whatever value
+@code{FS} may have. Leading and trailing newlines in a file are ignored.
+
+@item RS == @var{regexp}
+Records are separated by occurrences of characters that match @var{regexp}.
+Leading and trailing matches of @var{regexp} delimit empty records.
+(This is a @command{gawk} extension; it is not specified by the
+POSIX standard.)
+@end table
+
+@cindex @code{RT} variable
+In all cases, @command{gawk} sets @code{RT} to the input text that matched the
+value specified by @code{RS}.
+@c ENDOFRANGE recm
+@c ENDOFRANGE imr
+@c ENDOFRANGE frm
+
+@node Getline
+@section Explicit Input with @code{getline}
+
+@c STARTOFRANGE getl
+@cindex @code{getline} command, explicit input with
+@cindex input, explicit
+So far we have been getting our input data from @command{awk}'s main
+input stream---either the standard input (usually your terminal, sometimes
+the output from another program) or from the
+files specified on the command line. The @command{awk} language has a
+special built-in command called @code{getline} that
+can be used to read input under your explicit control.
+
+The @code{getline} command is used in several different ways and should
+@emph{not} be used by beginners.
+The examples that follow the explanation of the @code{getline} command
+include material that has not been covered yet. Therefore, come back
+and study the @code{getline} command @emph{after} you have reviewed the
+rest of this @value{DOCUMENT} and have a good knowledge of how @command{awk} works.
+
+@cindex @code{ERRNO} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{getline} command
+@cindex @code{getline} command, return values
+The @code{getline} command returns one if it finds a record and zero if
+it encounters the end of the file. If there is some error in getting
+a record, such as a file that cannot be opened, then @code{getline}
+returns @minus{}1. In this case, @command{gawk} sets the variable
+@code{ERRNO} to a string describing the error that occurred.
+
+In the following examples, @var{command} stands for a string value that
+represents a shell command.
+
+@menu
+* Plain Getline:: Using @code{getline} with no arguments.
+* Getline/Variable:: Using @code{getline} into a variable.
+* Getline/File:: Using @code{getline} from a file.
+* Getline/Variable/File:: Using @code{getline} into a variable from a
+ file.
+* Getline/Pipe:: Using @code{getline} from a pipe.
+* Getline/Variable/Pipe:: Using @code{getline} into a variable from a
+ pipe.
+* Getline/Coprocess:: Using @code{getline} from a coprocess.
+* Getline/Variable/Coprocess:: Using @code{getline} into a variable from a
+ coprocess.
+* Getline Notes:: Important things to know about @code{getline}.
+* Getline Summary:: Summary of @code{getline} Variants.
+@end menu
+
+@node Plain Getline
+@subsection Using @code{getline} with No Arguments
+
+The @code{getline} command can be used without arguments to read input
+from the current input file. All it does in this case is read the next
+input record and split it up into fields. This is useful if you've
+finished processing the current record, but want to do some special
+processing on the next record @emph{right now}. For example:
+
+@example
+@{
+ if ((t = index($0, "/*")) != 0) @{
+ # value of `tmp' will be "" if t is 1
+ tmp = substr($0, 1, t - 1)
+ u = index(substr($0, t + 2), "*/")
+ while (u == 0) @{
+ if (getline <= 0) @{
+ m = "unexpected EOF or error"
+ m = (m ": " ERRNO)
+ print m > "/dev/stderr"
+ exit
+ @}
+ t = -1
+ u = index($0, "*/")
+ @}
+ # substr expression will be "" if */
+ # occurred at end of line
+ $0 = tmp substr($0, u + 2)
+ @}
+ print $0
+@}
+@end example
+
+This @command{awk} program deletes all C-style comments (@samp{/* @dots{}
+*/}) from the input. By replacing the @samp{print $0} with other
+statements, you could perform more complicated processing on the
+decommented input, such as searching for matches of a regular
+expression. (This program has a subtle problem---it does not work if one
+comment ends and another begins on the same line.)
+
+@ignore
+Exercise,
+write a program that does handle multiple comments on the line.
+@end ignore
+
+This form of the @code{getline} command sets @code{NF},
+@code{NR}, @code{FNR}, and the value of @code{$0}.
+
+@quotation NOTE
+The new value of @code{$0} is used to test
+the patterns of any subsequent rules. The original value
+of @code{$0} that triggered the rule that executed @code{getline}
+is lost.
+By contrast, the @code{next} statement reads a new record
+but immediately begins processing it normally, starting with the first
+rule in the program. @xref{Next Statement}.
+@end quotation
+
+@node Getline/Variable
+@subsection Using @code{getline} into a Variable
+@cindex variables, @code{getline} command into@comma{} using
+
+You can use @samp{getline @var{var}} to read the next record from
+@command{awk}'s input into the variable @var{var}. No other processing is
+done.
+For example, suppose the next line is a comment or a special string,
+and you want to read it without triggering
+any rules. This form of @code{getline} allows you to read that line
+and store it in a variable so that the main
+read-a-line-and-check-each-rule loop of @command{awk} never sees it.
+The following example swaps every two lines of input:
+
+@example
+@{
+ if ((getline tmp) > 0) @{
+ print tmp
+ print $0
+ @} else
+ print $0
+@}
+@end example
+
+@noindent
+It takes the following list:
+
+@example
+wan
+tew
+free
+phore
+@end example
+
+@noindent
+and produces these results:
+
+@example
+tew
+wan
+phore
+free
+@end example
+
+The @code{getline} command used in this way sets only the variables
+@code{NR} and @code{FNR} (and of course, @var{var}). The record is not
+split into fields, so the values of the fields (including @code{$0}) and
+the value of @code{NF} do not change.
+
+@node Getline/File
+@subsection Using @code{getline} from a File
+
+@cindex input redirection
+@cindex redirection of input
+@cindex @code{<} (left angle bracket), @code{<} operator (I/O)
+@cindex left angle bracket (@code{<}), @code{<} operator (I/O)
+@cindex operators, input/output
+Use @samp{getline < @var{file}} to read the next record from @var{file}.
+Here @var{file} is a string-valued expression that
+specifies the @value{FN}. @samp{< @var{file}} is called a @dfn{redirection}
+because it directs input to come from a different place.
+For example, the following
+program reads its input record from the file @file{secondary.input} when it
+encounters a first field with a value equal to 10 in the current input
+file:
+
+@example
+@{
+ if ($1 == 10) @{
+ getline < "secondary.input"
+ print
+ @} else
+ print
+@}
+@end example
+
+Because the main input stream is not used, the values of @code{NR} and
+@code{FNR} are not changed. However, the record it reads is split into fields in
+the normal manner, so the values of @code{$0} and the other fields are
+changed, resulting in a new value of @code{NF}.
+
+@cindex POSIX @command{awk}, @code{<} operator and
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{getline < @var{expression}} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{getline < dir "/" file} is ambiguous
+because the concatenation operator is not parenthesized. You should
+write it as @samp{getline < (dir "/" file)} if you want your program
+to be portable to other @command{awk} implementations.
+
+@node Getline/Variable/File
+@subsection Using @code{getline} into a Variable from a File
+@cindex variables, @code{getline} command into@comma{} using
+
+Use @samp{getline @var{var} < @var{file}} to read input
+from the file
+@var{file}, and put it in the variable @var{var}. As above, @var{file}
+is a string-valued expression that specifies the file from which to read.
+
+In this version of @code{getline}, none of the built-in variables are
+changed and the record is not split into fields. The only variable
+changed is @var{var}.
+For example, the following program copies all the input files to the
+output, except for records that say @w{@samp{@@include @var{filename}}}.
+Such a record is replaced by the contents of the file
+@var{filename}:
+
+@example
+@{
+ if (NF == 2 && $1 == "@@include") @{
+ while ((getline line < $2) > 0)
+ print line
+ close($2)
+ @} else
+ print
+@}
+@end example
+
+Note here how the name of the extra input file is not built into
+the program; it is taken directly from the data, specifically from the second field on
+the @samp{@@include} line.
+
+@cindex @code{close} function
+The @code{close} function is called to ensure that if two identical
+@samp{@@include} lines appear in the input, the entire specified file is
+included twice.
+@xref{Close Files And Pipes}.
+
+One deficiency of this program is that it does not process nested
+@samp{@@include} statements
+(i.e., @samp{@@include} statements in included files)
+the way a true macro preprocessor would.
+@xref{Igawk Program}, for a program
+that does handle nested @samp{@@include} statements.
+
+@node Getline/Pipe
+@subsection Using @code{getline} from a Pipe
+
+@cindex @code{|} (vertical bar), @code{|} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|} operator (I/O)
+@cindex input pipeline
+@cindex pipes, input
+@cindex operators, input/output
+The output of a command can also be piped into @code{getline}, using
+@samp{@var{command} | getline}. In
+this case, the string @var{command} is run as a shell command and its output
+is piped into @command{awk} to be used as input. This form of @code{getline}
+reads one record at a time from the pipe.
+For example, the following program copies its input to its output, except for
+lines that begin with @samp{@@execute}, which are replaced by the output
+produced by running the rest of the line as a shell command:
+
+@example
+@{
+ if ($1 == "@@execute") @{
+ tmp = substr($0, 10)
+ while ((tmp | getline) > 0)
+ print
+ close(tmp)
+ @} else
+ print
+@}
+@end example
+
+@noindent
+@cindex @code{close} function
+The @code{close} function is called to ensure that if two identical
+@samp{@@execute} lines appear in the input, the command is run for
+each one.
+@ifnottex
+@xref{Close Files And Pipes}.
+@end ifnottex
+@c Exercise!!
+@c This example is unrealistic, since you could just use system
+Given the input:
+
+@example
+foo
+bar
+baz
+@@execute who
+bletch
+@end example
+
+@noindent
+the program might produce:
+
+@cindex Robbins, Bill
+@cindex Robbins, Miriam
+@cindex Robbins, Arnold
+@example
+foo
+bar
+baz
+arnold ttyv0 Jul 13 14:22
+miriam ttyp0 Jul 13 14:23 (murphy:0)
+bill ttyp1 Jul 13 14:23 (murphy:0)
+bletch
+@end example
+
+@noindent
+Notice that this program ran the command @command{who} and printed the previous result.
+(If you try this program yourself, you will of course get different results,
+depending upon who is logged in on your system.)
+
+This variation of @code{getline} splits the record into fields, sets the
+value of @code{NF}, and recomputes the value of @code{$0}. The values of
+@code{NR} and @code{FNR} are not changed.
+
+@cindex POSIX @command{awk}, @code{|} I/O operator and
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{@var{expression} | getline} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}---for example, @samp{@w{"echo "} "date" | getline} is ambiguous
+because the concatenation operator is not parenthesized. You should
+write it as @samp{(@w{"echo "} "date") | getline} if you want your program
+to be portable to other @command{awk} implementations.
+
+@node Getline/Variable/Pipe
+@subsection Using @code{getline} into a Variable from a Pipe
+@cindex variables, @code{getline} command into@comma{} using
+
+When you use @samp{@var{command} | getline @var{var}}, the
+output of @var{command} is sent through a pipe to
+@code{getline} and into the variable @var{var}. For example, the
+following program reads the current date and time into the variable
+@code{current_time}, using the @command{date} utility, and then
+prints it:
+
+@example
+BEGIN @{
+ "date" | getline current_time
+ close("date")
+ print "Report printed on " current_time
+@}
+@end example
+
+In this version of @code{getline}, none of the built-in variables are
+changed and the record is not split into fields.
+
+@ifinfo
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{@var{expression} | getline @var{var}} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{@w{"echo "} "date" | getline @var{var}} is ambiguous
+because the concatenation operator is not parenthesized. You should
+write it as @samp{(@w{"echo "} "date") | getline @var{var}} if you want your
+program to be portable to other @command{awk} implementations.
+@end ifinfo
+
+@node Getline/Coprocess
+@subsection Using @code{getline} from a Coprocess
+@cindex coprocesses, @code{getline} from
+@cindex @code{getline} command, coprocesses@comma{} using from
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
+@cindex operators, input/output
+@cindex differences in @command{awk} and @command{gawk}, input/output operators
+
+Input into @code{getline} from a pipe is a one-way operation.
+The command that is started with @samp{@var{command} | getline} only
+sends data @emph{to} your @command{awk} program.
+
+On occasion, you might want to send data to another program
+for processing and then read the results back.
+@command{gawk} allows you start a @dfn{coprocess}, with which two-way
+communications are possible. This is done with the @samp{|&}
+operator.
+Typically, you write data to the coprocess first and then
+read results back, as shown in the following:
+
+@example
+print "@var{some query}" |& "db_server"
+"db_server" |& getline
+@end example
+
+@noindent
+which sends a query to @command{db_server} and then reads the results.
+
+The values of @code{NR} and
+@code{FNR} are not changed,
+because the main input stream is not used.
+However, the record is split into fields in
+the normal manner, thus changing the values of @code{$0}, of the other fields,
+and of @code{NF}.
+
+Coprocesses are an advanced feature. They are discussed here only because
+this is the @value{SECTION} on @code{getline}.
+@xref{Two-way I/O},
+where coprocesses are discussed in more detail.
+
+@node Getline/Variable/Coprocess
+@subsection Using @code{getline} into a Variable from a Coprocess
+@cindex variables, @code{getline} command into@comma{} using
+
+When you use @samp{@var{command} |& getline @var{var}}, the output from
+the coprocess @var{command} is sent through a two-way pipe to @code{getline}
+and into the variable @var{var}.
+
+In this version of @code{getline}, none of the built-in variables are
+changed and the record is not split into fields. The only variable
+changed is @var{var}.
+
+@ifinfo
+Coprocesses are an advanced feature. They are discussed here only because
+this is the @value{SECTION} on @code{getline}.
+@xref{Two-way I/O},
+where coprocesses are discussed in more detail.
+@end ifinfo
+
+@node Getline Notes
+@subsection Points to Remember About @code{getline}
+Here are some miscellaneous points about @code{getline} that
+you should bear in mind:
+
+@itemize @bullet
+@item
+When @code{getline} changes the value of @code{$0} and @code{NF},
+@command{awk} does @emph{not} automatically jump to the start of the
+program and start testing the new record against every pattern.
+However, the new record is tested against any subsequent rules.
+
+@cindex differences in @command{awk} and @command{gawk}, implementation limitations
+@cindex implementation issues, @command{gawk}, limits
+@cindex @command{awk}, implementations, limits
+@cindex @command{gawk}, implementation issues, limits
+@item
+Many @command{awk} implementations limit the number of pipelines that an @command{awk}
+program may have open to just one. In @command{gawk}, there is no such limit.
+You can open as many pipelines (and coprocesses) as the underlying operating
+system permits.
+
+@cindex side effects, @code{FILENAME} variable
+@cindex @code{FILENAME} variable, @code{getline}@comma{} setting with
+@cindex dark corner, @code{FILENAME} variable
+@cindex @code{getline} command, @code{FILENAME} variable and
+@cindex @code{BEGIN} pattern, @code{getline} and
+@item
+An interesting side effect occurs if you use @code{getline} without a
+redirection inside a @code{BEGIN} rule. Because an unredirected @code{getline}
+reads from the command-line @value{DF}s, the first @code{getline} command
+causes @command{awk} to set the value of @code{FILENAME}. Normally,
+@code{FILENAME} does not have a value inside @code{BEGIN} rules, because you
+have not yet started to process the command-line @value{DF}s.
+@value{DARKCORNER}
+(@xref{BEGIN/END},
+also @pxref{Auto-set}.)
+
+@item
+Using @code{FILENAME} with @code{getline}
+(@samp{getline < FILENAME})
+is likely to be a source for
+confusion. @command{awk} opens a separate input stream from the
+current input file. However, by not using a variable, @code{$0}
+and @code{NR} are still updated. If you're doing this, it's
+probably by accident, and you should reconsider what it is you're
+trying to accomplish.
+@end itemize
+
+@node Getline Summary
+@subsection Summary of @code{getline} Variants
+@cindex @code{getline} command, variants
+
+@ref{table-getline-variants}
+summarizes the eight variants of @code{getline},
+listing which built-in variables are set by each one.
+
+@float Table,table-getline-variants
+@caption{getline Variants and What They Set}
+@multitable @columnfractions .35 .65
+@headitem Variant @tab Effect
+@item @code{getline} @tab Sets @code{$0}, @code{NF}, @code{FNR}, and @code{NR}
+@item @code{getline} @var{var} @tab Sets @var{var}, @code{FNR}, and @code{NR}
+@item @code{getline <} @var{file} @tab Sets @code{$0} and @code{NF}
+@item @code{getline @var{var} < @var{file}} @tab Sets @var{var}
+@item @var{command} @code{| getline} @tab Sets @code{$0} and @code{NF}
+@item @var{command} @code{| getline} @var{var} @tab Sets @var{var}
+@item @var{command} @code{|& getline} @tab Sets @code{$0} and @code{NF}. This is a @command{gawk} extension
+@item @var{command} @code{|& getline} @var{var} @tab Sets @var{var}. This is a @command{gawk} extension
+@end multitable
+@end float
+@c ENDOFRANGE getl
+@c ENDOFRANGE inex
+@c ENDOFRANGE infir
+
+@node Printing
+@chapter Printing Output
+
+@c STARTOFRANGE prnt
+@cindex printing
+@cindex output, printing, See printing
+One of the most common programming actions is to @dfn{print}, or output,
+some or all of the input. Use the @code{print} statement
+for simple output, and the @code{printf} statement
+for fancier formatting.
+The @code{print} statement is not limited when
+computing @emph{which} values to print. However, with two exceptions,
+you cannot specify @emph{how} to print them---how many
+columns, whether to use exponential notation or not, and so on.
+(For the exceptions, @pxref{Output Separators}, and
+@ref{OFMT}.)
+For printing with specifications, you need the @code{printf} statement
+(@pxref{Printf}).
+
+@c STARTOFRANGE prnts
+@cindex @code{print} statement
+@cindex @code{printf} statement
+Besides basic and formatted printing, this @value{CHAPTER}
+also covers I/O redirections to files and pipes, introduces
+the special @value{FN}s that @command{gawk} processes internally,
+and discusses the @code{close} built-in function.
+
+@menu
+* Print:: The @code{print} statement.
+* Print Examples:: Simple examples of @code{print} statements.
+* Output Separators:: The output separators and how to change them.
+* OFMT:: Controlling Numeric Output With @code{print}.
+* Printf:: The @code{printf} statement.
+* Redirection:: How to redirect output to multiple files and
+ pipes.
+* Special Files:: File name interpretation in @command{gawk}.
+ @command{gawk} allows access to inherited file
+ descriptors.
+* Close Files And Pipes:: Closing Input and Output Files and Pipes.
+@end menu
+
+@node Print
+@section The @code{print} Statement
+
+The @code{print} statement is used to produce output with simple, standardized
+formatting. Specify only the strings or numbers to print, in a
+list separated by commas. They are output, separated by single spaces,
+followed by a newline. The statement looks like this:
+
+@example
+print @var{item1}, @var{item2}, @dots{}
+@end example
+
+@noindent
+The entire list of items may be optionally enclosed in parentheses. The
+parentheses are necessary if any of the item expressions uses the @samp{>}
+relational operator; otherwise it could be confused with a redirection
+(@pxref{Redirection}).
+
+The items to print can be constant strings or numbers, fields of the
+current record (such as @code{$1}), variables, or any @command{awk}
+expression. Numeric values are converted to strings and then printed.
+
+@cindex records, printing
+@cindex lines, blank, printing
+@cindex text, printing
+The simple statement @samp{print} with no items is equivalent to
+@samp{print $0}: it prints the entire current record. To print a blank
+line, use @samp{print ""}, where @code{""} is the empty string.
+To print a fixed piece of text, use a string constant, such as
+@w{@code{"Don't Panic"}}, as one item. If you forget to use the
+double-quote characters, your text is taken as an @command{awk}
+expression, and you will probably get an error. Keep in mind that a
+space is printed between any two items.
+
+@node Print Examples
+@section Examples of @code{print} Statements
+
+Each @code{print} statement makes at least one line of output. However, it
+isn't limited to only one line. If an item value is a string that contains a
+newline, the newline is output along with the rest of the string. A
+single @code{print} statement can make any number of lines this way.
+
+@cindex newlines, printing
+The following is an example of printing a string that contains embedded newlines
+(the @samp{\n} is an escape sequence, used to represent the newline
+character; @pxref{Escape Sequences}):
+
+@example
+$ awk 'BEGIN @{ print "line one\nline two\nline three" @}'
+@print{} line one
+@print{} line two
+@print{} line three
+@end example
+
+@cindex fields, printing
+The next example, which is run on the @file{inventory-shipped} file,
+prints the first two fields of each input record, with a space between
+them:
+
+@example
+$ awk '@{ print $1, $2 @}' inventory-shipped
+@print{} Jan 13
+@print{} Feb 15
+@print{} Mar 15
+@dots{}
+@end example
+
+@cindex @code{print} statement, commas, omitting
+@cindex troubleshooting, @code{print} statement@comma{} omitting commas
+A common mistake in using the @code{print} statement is to omit the comma
+between two items. This often has the effect of making the items run
+together in the output, with no space. The reason for this is that
+juxtaposing two string expressions in @command{awk} means to concatenate
+them. Here is the same program, without the comma:
+
+@example
+$ awk '@{ print $1 $2 @}' inventory-shipped
+@print{} Jan13
+@print{} Feb15
+@print{} Mar15
+@dots{}
+@end example
+
+@cindex @code{BEGIN} pattern, headings@comma{} adding
+To someone unfamiliar with the @file{inventory-shipped} file, neither
+example's output makes much sense. A heading line at the beginning
+would make it clearer. Let's add some headings to our table of months
+(@code{$1}) and green crates shipped (@code{$2}). We do this using the
+@code{BEGIN} pattern
+(@pxref{BEGIN/END})
+so that the headings are only printed once:
+
+@example
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, $2 @}' inventory-shipped
+@end example
+
+@noindent
+When run, the program prints the following:
+
+@example
+Month Crates
+----- ------
+Jan 13
+Feb 15
+Mar 15
+@dots{}
+@end example
+
+@noindent
+The only problem, however, is that the headings and the table data
+don't line up! We can fix this by printing some spaces between the
+two fields:
+
+@example
+@group
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, " ", $2 @}' inventory-shipped
+@end group
+@end example
+
+@cindex @code{printf} statement, columns@comma{} aligning
+@cindex columns, aligning
+Lining up columns this way can get pretty
+complicated when there are many columns to fix. Counting spaces for two
+or three columns is simple, but any more than this can take up
+a lot of time. This is why the @code{printf} statement was
+created (@pxref{Printf});
+one of its specialties is lining up columns of data.
+
+@cindex line continuations, in @code{print} statement
+@cindex @code{print} statement, line continuations and
+@quotation NOTE
+You can continue either a @code{print} or
+@code{printf} statement simply by putting a newline after any comma
+(@pxref{Statements/Lines}).
+@end quotation
+@c ENDOFRANGE prnts
+
+@node Output Separators
+@section Output Separators
+
+@cindex @code{OFS} variable
+As mentioned previously, a @code{print} statement contains a list
+of items separated by commas. In the output, the items are normally
+separated by single spaces. However, this doesn't need to be the case;
+a single space is only the default. Any string of
+characters may be used as the @dfn{output field separator} by setting the
+built-in variable @code{OFS}. The initial value of this variable
+is the string @w{@code{" "}}---that is, a single space.
+
+The output from an entire @code{print} statement is called an
+@dfn{output record}. Each @code{print} statement outputs one output
+record, and then outputs a string called the @dfn{output record separator}
+(or @code{ORS}). The initial
+value of @code{ORS} is the string @code{"\n"}; i.e., a newline
+character. Thus, each @code{print} statement normally makes a separate line.
+
+@cindex output, records
+@cindex output record separator, See @code{ORS} variable
+@cindex @code{ORS} variable
+@cindex @code{BEGIN} pattern, @code{OFS}/@code{ORS} variables, assigning values to
+In order to change how output fields and records are separated, assign
+new values to the variables @code{OFS} and @code{ORS}. The usual
+place to do this is in the @code{BEGIN} rule
+(@pxref{BEGIN/END}), so
+that it happens before any input is processed. It can also be done
+with assignments on the command line, before the names of the input
+files, or using the @option{-v} command-line option
+(@pxref{Options}).
+The following example prints the first and second fields of each input
+record, separated by a semicolon, with a blank line added after each
+newline:
+
+@ignore
+Exercise,
+Rewrite the
+@example
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, " ", $2 @}' inventory-shipped
+@end example
+program by using a new value of @code{OFS}.
+@end ignore
+
+@example
+$ awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}
+> @{ print $1, $2 @}' BBS-list
+@print{} aardvark;555-5553
+@print{}
+@print{} alpo-net;555-3412
+@print{}
+@print{} barfly;555-7685
+@dots{}
+@end example
+
+If the value of @code{ORS} does not contain a newline, the program's output
+is run together on a single line.
+
+@node OFMT
+@section Controlling Numeric Output with @code{print}
+@cindex numeric, output format
+@cindex formats@comma{} numeric output
+When the @code{print} statement is used to print numeric values,
+@command{awk} internally converts the number to a string of characters
+and prints that string. @command{awk} uses the @code{sprintf} function
+to do this conversion
+(@pxref{String Functions}).
+For now, it suffices to say that the @code{sprintf}
+function accepts a @dfn{format specification} that tells it how to format
+numbers (or strings), and that there are a number of different ways in which
+numbers can be formatted. The different format specifications are discussed
+more fully in
+@ref{Control Letters}.
+
+@cindex @code{sprintf} function
+@cindex @code{OFMT} variable
+@cindex output, format specifier@comma{} @code{OFMT}
+The built-in variable @code{OFMT} contains the default format specification
+that @code{print} uses with @code{sprintf} when it wants to convert a
+number to a string for printing.
+The default value of @code{OFMT} is @code{"%.6g"}.
+The way @code{print} prints numbers can be changed
+by supplying different format specifications
+as the value of @code{OFMT}, as shown in the following example:
+
+@example
+$ awk 'BEGIN @{
+> OFMT = "%.0f" # print numbers as integers (rounds)
+> print 17.23, 17.54 @}'
+@print{} 17 18
+@end example
+
+@noindent
+@cindex dark corner, @code{OFMT} variable
+@cindex POSIX @command{awk}, @code{OFMT} variable and
+@cindex @code{OFMT} variable, POSIX @command{awk} and
+According to the POSIX standard, @command{awk}'s behavior is undefined
+if @code{OFMT} contains anything but a floating-point conversion specification.
+@value{DARKCORNER}
+
+@node Printf
+@section Using @code{printf} Statements for Fancier Printing
+
+@c STARTOFRANGE printfs
+@cindex @code{printf} statement
+@cindex output, formatted
+@cindex formatting output
+For more precise control over the output format than what is
+normally provided by @code{print}, use @code{printf}.
+@code{printf} can be used to
+specify the width to use for each item, as well as various
+formatting choices for numbers (such as what output base to use, whether to
+print an exponent, whether to print a sign, and how many digits to print
+after the decimal point). This is done by supplying a string, called
+the @dfn{format string}, that controls how and where to print the other
+arguments.
+
+@menu
+* Basic Printf:: Syntax of the @code{printf} statement.
+* Control Letters:: Format-control letters.
+* Format Modifiers:: Format-specification modifiers.
+* Printf Examples:: Several examples.
+@end menu
+
+@node Basic Printf
+@subsection Introduction to the @code{printf} Statement
+
+@cindex @code{printf} statement, syntax of
+A simple @code{printf} statement looks like this:
+
+@example
+printf @var{format}, @var{item1}, @var{item2}, @dots{}
+@end example
+
+@noindent
+The entire list of arguments may optionally be enclosed in parentheses. The
+parentheses are necessary if any of the item expressions use the @samp{>}
+relational operator; otherwise, it can be confused with a redirection
+(@pxref{Redirection}).
+
+@cindex format strings
+The difference between @code{printf} and @code{print} is the @var{format}
+argument. This is an expression whose value is taken as a string; it
+specifies how to output each of the other arguments. It is called the
+@dfn{format string}.
+
+The format string is very similar to that in the ISO C library function
+@code{printf}. Most of @var{format} is text to output verbatim.
+Scattered among this text are @dfn{format specifiers}---one per item.
+Each format specifier says to output the next item in the argument list
+at that place in the format.
+
+The @code{printf} statement does not automatically append a newline
+to its output. It outputs only what the format string specifies.
+So if a newline is needed, you must include one in the format string.
+The output separator variables @code{OFS} and @code{ORS} have no effect
+on @code{printf} statements. For example:
+
+@example
+$ awk 'BEGIN @{
+> ORS = "\nOUCH!\n"; OFS = "+"
+> msg = "Dont Panic!"
+> printf "%s\n", msg
+> @}'
+@print{} Dont Panic!
+@end example
+
+@noindent
+Here, neither the @samp{+} nor the @samp{OUCH} appear when
+the message is printed.
+
+@node Control Letters
+@subsection Format-Control Letters
+@cindex @code{printf} statement, format-control characters
+@cindex format specifiers, @code{printf} statement
+
+A format specifier starts with the character @samp{%} and ends with
+a @dfn{format-control letter}---it tells the @code{printf} statement
+how to output one item. The format-control letter specifies what @emph{kind}
+of value to print. The rest of the format specifier is made up of
+optional @dfn{modifiers} that control @emph{how} to print the value, such as
+the field width. Here is a list of the format-control letters:
+
+@table @code
+@item %c
+This prints a number as an ASCII character; thus, @samp{printf "%c",
+65} outputs the letter @samp{A}. (The output for a string value is
+the first character of the string.)
+
+@item %d@r{,} %i
+These are equivalent; they both print a decimal integer.
+(The @samp{%i} specification is for compatibility with ISO C.)
+
+@item %e@r{,} %E
+These print a number in scientific (exponential) notation;
+for example:
+
+@example
+printf "%4.3e\n", 1950
+@end example
+
+@noindent
+prints @samp{1.950e+03}, with a total of four significant figures, three of
+which follow the decimal point.
+(The @samp{4.3} represents two modifiers,
+discussed in the next @value{SUBSECTION}.)
+@samp{%E} uses @samp{E} instead of @samp{e} in the output.
+
+@item %f
+This prints a number in floating-point notation.
+For example:
+
+@example
+printf "%4.3f", 1950
+@end example
+
+@noindent
+prints @samp{1950.000}, with a total of four significant figures, three of
+which follow the decimal point.
+(The @samp{4.3} represents two modifiers,
+discussed in the next @value{SUBSECTION}.)
+
+On systems supporting IEEE 754 floating point format, values
+representing negative
+infinity are formatted as
+@samp{-inf} or @samp{-infinity},
+and positive infinity as
+@samp{inf} and @samp{-infinity}.
+The special ``not a number'' value formats as @samp{-nan} or @samp{nan}.
+
+@item %F
+Like @code{%f} but the infinity and ``not a number'' values are spelled
+using uppercase letters.
+
+The @code{%F} format is a POSIX extension to ISO C; not all systems
+support. On those that don't, @command{gawk} uses @code{%f} instead.
+
+@item %g@r{,} %G
+These print a number in either scientific notation or in floating-point
+notation, whichever uses fewer characters; if the result is printed in
+scientific notation, @samp{%G} uses @samp{E} instead of @samp{e}.
+
+@item %o
+This prints an unsigned octal integer.
+
+@item %s
+This prints a string.
+
+@item %u
+This prints an unsigned decimal integer.
+(This format is of marginal use, because all numbers in @command{awk}
+are floating-point; it is provided primarily for compatibility with C.)
+
+@item %x@r{,} %X
+These print an unsigned hexadecimal integer;
+@samp{%X} uses the letters @samp{A} through @samp{F}
+instead of @samp{a} through @samp{f}.
+
+@item %%
+This isn't a format-control letter, but it does have meaning---the
+sequence @samp{%%} outputs one @samp{%}; it does not consume an
+argument and it ignores any modifiers.
+@end table
+
+@cindex dark corner, format-control characters
+@cindex @command{gawk}, format-control characters
+@quotation NOTE
+When using the integer format-control letters for values that are
+outside the range of the widest C integer type, @command{gawk} switches to the
+the @samp{%g} format specifier. If @option{--lint} is provided on the
+command line (@pxref{Options}), @command{gawk}
+warns about this. Other versions of @command{awk} may print invalid
+values or do something else entirely.
+@value{DARKCORNER}
+@end quotation
+
+@node Format Modifiers
+@subsection Modifiers for @code{printf} Formats
+
+@c STARTOFRANGE pfm
+@cindex @code{printf} statement, modifiers
+@cindex modifiers@comma{} in format specifiers
+A format specification can also include @dfn{modifiers} that can control
+how much of the item's value is printed, as well as how much space it gets.
+The modifiers come between the @samp{%} and the format-control letter.
+We will use the bullet symbol ``@bullet{}'' in the following examples to
+represent
+spaces in the output. Here are the possible modifiers, in the order in
+which they may appear:
+
+@table @code
+@cindex differences in @command{awk} and @command{gawk}, @code{print}/@code{printf} statements
+@cindex @code{printf} statement, positional specifiers
+@c the command does NOT start a secondary
+@cindex positional specifiers, @code{printf} statement
+@item @var{N}$
+An integer constant followed by a @samp{$} is a @dfn{positional specifier}.
+Normally, format specifications are applied to arguments in the order
+given in the format string. With a positional specifier, the format
+specification is applied to a specific argument, instead of what
+would be the next argument in the list. Positional specifiers begin
+counting with one. Thus:
+
+@example
+printf "%s %s\n", "don't", "panic"
+printf "%2$s %1$s\n", "panic", "don't"
+@end example
+
+@noindent
+prints the famous friendly message twice.
+
+At first glance, this feature doesn't seem to be of much use.
+It is in fact a @command{gawk} extension, intended for use in translating
+messages at runtime.
+@xref{Printf Ordering},
+which describes how and why to use positional specifiers.
+For now, we will not use them.
+
+@item -
+The minus sign, used before the width modifier (see later on in
+this table),
+says to left-justify
+the argument within its specified width. Normally, the argument
+is printed right-justified in the specified width. Thus:
+
+@example
+printf "%-4s", "foo"
+@end example
+
+@noindent
+prints @samp{foo@bullet{}}.
+
+@item @var{space}
+For numeric conversions, prefix positive values with a space and
+negative values with a minus sign.
+
+@item +
+The plus sign, used before the width modifier (see later on in
+this table),
+says to always supply a sign for numeric conversions, even if the data
+to format is positive. The @samp{+} overrides the space modifier.
+
+@item #
+Use an ``alternate form'' for certain control letters.
+For @samp{%o}, supply a leading zero.
+For @samp{%x} and @samp{%X}, supply a leading @samp{0x} or @samp{0X} for
+a nonzero result.
+For @samp{%e}, @samp{%E}, and @samp{%f}, the result always contains a
+decimal point.
+For @samp{%g} and @samp{%G}, trailing zeros are not removed from the result.
+
+@cindex dark corner
+@item 0
+A leading @samp{0} (zero) acts as a flag that indicates that output should be
+padded with zeros instead of spaces.
+This applies even to non-numeric output formats.
+@value{DARKCORNER}
+This flag only has an effect when the field width is wider than the
+value to print.
+
+@item '
+A single quote or apostrohe character is a POSIX extension to ISO C.
+It indicates that the integer part of a floating point value, or the
+entire part of an integer decimal value, should have a thousands-separator
+character in it. This only works in locales that support such characters.
+For example:
+
+@example
+$ @kbd{cat thousands.awk} @i{Show source program}
+@print{} BEGIN @{ printf "%'d\n", 1234567 @}
+$ @kbd{LC_ALL=C gawk -f thousands.awk} @i{Run it in "C" locale}
+@print{} 1234567
+$ @kbd{LC_ALL=en_US.UTF-8 gawk -f thousands.awk} @i{Run in US English UTF locale}
+@print{} 1,234,567
+@end example
+
+@noindent
+For more information about locales and internationalization issues,
+see @ref{Locales}.
+
+@quotation NOTE
+The @samp{'} flag is a nice feature, but its use complicates things: it
+now becomes difficult to use it in command-line programs. For information
+on appropriate quoting tricks, see @ref{Quoting}.
+@end quotation
+
+@item @var{width}
+This is a number specifying the desired minimum width of a field. Inserting any
+number between the @samp{%} sign and the format-control character forces the
+field to expand to this width. The default way to do this is to
+pad with spaces on the left. For example:
+
+@example
+printf "%4s", "foo"
+@end example
+
+@noindent
+prints @samp{@bullet{}foo}.
+
+The value of @var{width} is a minimum width, not a maximum. If the item
+value requires more than @var{width} characters, it can be as wide as
+necessary. Thus, the following:
+
+@example
+printf "%4s", "foobar"
+@end example
+
+@noindent
+prints @samp{foobar}.
+
+Preceding the @var{width} with a minus sign causes the output to be
+padded with spaces on the right, instead of on the left.
+
+@item .@var{prec}
+A period followed by an integer constant
+specifies the precision to use when printing.
+The meaning of the precision varies by control letter:
+
+@table @asis
+@item @code{%e}, @code{%E}, @code{%f}
+Number of digits to the right of the decimal point.
+
+@item @code{%g}, @code{%G}
+Maximum number of significant digits.
+
+@item @code{%d}, @code{%i}, @code{%o}, @code{%u}, @code{%x}, @code{%X}
+Minimum number of digits to print.
+
+@item @code{%s}
+Maximum number of characters from the string that should print.
+@end table
+
+Thus, the following:
+
+@example
+printf "%.4s", "foobar"
+@end example
+
+@noindent
+prints @samp{foob}.
+@end table
+
+The C library @code{printf}'s dynamic @var{width} and @var{prec}
+capability (for example, @code{"%*.*s"}) is supported. Instead of
+supplying explicit @var{width} and/or @var{prec} values in the format
+string, they are passed in the argument list. For example:
+
+@example
+w = 5
+p = 3
+s = "abcdefg"
+printf "%*.*s\n", w, p, s
+@end example
+
+@noindent
+is exactly equivalent to:
+
+@example
+s = "abcdefg"
+printf "%5.3s\n", s
+@end example
+
+@noindent
+Both programs output @samp{@w{@bullet{}@bullet{}abc}}.
+Earlier versions of @command{awk} did not support this capability.
+If you must use such a version, you may simulate this feature by using
+concatenation to build up the format string, like so:
+
+@example
+w = 5
+p = 3
+s = "abcdefg"
+printf "%" w "." p "s\n", s
+@end example
+
+@noindent
+This is not particularly easy to read but it does work.
+
+@c @cindex lint checks
+@cindex troubleshooting, fatal errors, @code{printf} format strings
+@cindex POSIX @command{awk}, @code{printf} format strings and
+C programmers may be used to supplying additional
+@samp{l}, @samp{L}, and @samp{h}
+modifiers in @code{printf} format strings. These are not valid in @command{awk}.
+Most @command{awk} implementations silently ignore these modifiers.
+If @option{--lint} is provided on the command line
+(@pxref{Options}),
+@command{gawk} warns about their use. If @option{--posix} is supplied,
+their use is a fatal error.
+@c ENDOFRANGE pfm
+
+@node Printf Examples
+@subsection Examples Using @code{printf}
+
+The following is a simple example of
+how to use @code{printf} to make an aligned table:
+
+@example
+awk '@{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+@end example
+
+@noindent
+This command
+prints the names of the bulletin boards (@code{$1}) in the file
+@file{BBS-list} as a string of 10 characters that are left-justified. It also
+prints the phone numbers (@code{$2}) next on the line. This
+produces an aligned two-column table of names and phone numbers,
+as shown here:
+
+@example
+$ awk '@{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+@print{} aardvark 555-5553
+@print{} alpo-net 555-3412
+@print{} barfly 555-7685
+@print{} bites 555-1675
+@print{} camelot 555-0542
+@print{} core 555-2912
+@print{} fooey 555-1234
+@print{} foot 555-6699
+@print{} macfoo 555-6480
+@print{} sdace 555-3430
+@print{} sabafoo 555-2127
+@end example
+
+In this case, the phone numbers had to be printed as strings because
+the numbers are separated by a dash. Printing the phone numbers as
+numbers would have produced just the first three digits: @samp{555}.
+This would have been pretty confusing.
+
+It wasn't necessary to specify a width for the phone numbers because
+they are last on their lines. They don't need to have spaces
+after them.
+
+The table could be made to look even nicer by adding headings to the
+tops of the columns. This is done using the @code{BEGIN} pattern
+(@pxref{BEGIN/END})
+so that the headers are only printed once, at the beginning of
+the @command{awk} program:
+
+@example
+awk 'BEGIN @{ print "Name Number"
+ print "---- ------" @}
+ @{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+@end example
+
+The above example mixed @code{print} and @code{printf} statements in
+the same program. Using just @code{printf} statements can produce the
+same results:
+
+@example
+awk 'BEGIN @{ printf "%-10s %s\n", "Name", "Number"
+ printf "%-10s %s\n", "----", "------" @}
+ @{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+@end example
+
+@noindent
+Printing each column heading with the same format specification
+used for the column elements ensures that the headings
+are aligned just like the columns.
+
+The fact that the same format specification is used three times can be
+emphasized by storing it in a variable, like this:
+
+@example
+awk 'BEGIN @{ format = "%-10s %s\n"
+ printf format, "Name", "Number"
+ printf format, "----", "------" @}
+ @{ printf format, $1, $2 @}' BBS-list
+@end example
+
+@c !!! exercise
+At this point, it would be a worthwhile exercise to use the
+@code{printf} statement to line up the headings and table data for the
+@file{inventory-shipped} example that was covered earlier in the @value{SECTION}
+on the @code{print} statement
+(@pxref{Print}).
+@c ENDOFRANGE printfs
+
+@node Redirection
+@section Redirecting Output of @code{print} and @code{printf}
+
+@cindex output redirection
+@cindex redirection of output
+So far, the output from @code{print} and @code{printf} has gone
+to the standard
+output, usually the terminal. Both @code{print} and @code{printf} can
+also send their output to other places.
+This is called @dfn{redirection}.
+
+A redirection appears after the @code{print} or @code{printf} statement.
+Redirections in @command{awk} are written just like redirections in shell
+commands, except that they are written inside the @command{awk} program.
+
+@c the commas here are part of the see also
+@cindex @code{print} statement, See Also redirection, of output
+@cindex @code{printf} statement, See Also redirection, of output
+There are four forms of output redirection: output to a file, output
+appended to a file, output through a pipe to another command, and output
+to a coprocess. They are all shown for the @code{print} statement,
+but they work identically for @code{printf}:
+
+@table @code
+@cindex @code{>} (right angle bracket), @code{>} operator (I/O)
+@cindex right angle bracket (@code{>}), @code{>} operator (I/O)
+@cindex operators, input/output
+@item print @var{items} > @var{output-file}
+This type of redirection prints the items into the output file named
+@var{output-file}. The @value{FN} @var{output-file} can be any
+expression. Its value is changed to a string and then used as a
+@value{FN} (@pxref{Expressions}).
+
+When this type of redirection is used, the @var{output-file} is erased
+before the first output is written to it. Subsequent writes to the same
+@var{output-file} do not erase @var{output-file}, but append to it.
+(This is different from how you use redirections in shell scripts.)
+If @var{output-file} does not exist, it is created. For example, here
+is how an @command{awk} program can write a list of BBS names to one
+file named @file{name-list}, and a list of phone numbers to another file
+named @file{phone-list}:
+
+@example
+$ awk '@{ print $2 > "phone-list"
+> print $1 > "name-list" @}' BBS-list
+$ cat phone-list
+@print{} 555-5553
+@print{} 555-3412
+@dots{}
+$ cat name-list
+@print{} aardvark
+@print{} alpo-net
+@dots{}
+@end example
+
+@noindent
+Each output file contains one name or number per line.
+
+@cindex @code{>} (right angle bracket), @code{>>} operator (I/O)
+@cindex right angle bracket (@code{>}), @code{>>} operator (I/O)
+@item print @var{items} >> @var{output-file}
+This type of redirection prints the items into the pre-existing output file
+named @var{output-file}. The difference between this and the
+single-@samp{>} redirection is that the old contents (if any) of
+@var{output-file} are not erased. Instead, the @command{awk} output is
+appended to the file.
+If @var{output-file} does not exist, then it is created.
+
+@cindex @code{|} (vertical bar), @code{|} operator (I/O)
+@cindex pipes, output
+@cindex output, pipes
+@item print @var{items} | @var{command}
+It is also possible to send output to another program through a pipe
+instead of into a file. This type of redirection opens a pipe to
+@var{command}, and writes the values of @var{items} through this pipe
+to another process created to execute @var{command}.
+
+The redirection argument @var{command} is actually an @command{awk}
+expression. Its value is converted to a string whose contents give
+the shell command to be run. For example, the following produces two
+files, one unsorted list of BBS names, and one list sorted in reverse
+alphabetical order:
+
+@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 > "names.unsorted"
+ command = "sort -r > names.sorted"
+ print $1 | command @}' BBS-list
+@end example
+
+The unsorted list is written with an ordinary redirection, while
+the sorted list is written by piping through the @command{sort} utility.
+
+The next example uses redirection to mail a message to the mailing
+list @samp{bug-system}. This might be useful when trouble is encountered
+in an @command{awk} script run periodically for system maintenance:
+
+@example
+report = "mail bug-system"
+print "Awk script failed:", $0 | report
+m = ("at record number " FNR " of " FILENAME)
+print m | report
+close(report)
+@end example
+
+The message is built using string concatenation and saved in the variable
+@code{m}. It's then sent down the pipeline to the @command{mail} program.
+(The parentheses group the items to concatenate---see
+@ref{Concatenation}.)
+
+The @code{close} function is called here because it's a good idea to close
+the pipe as soon as all the intended output has been sent to it.
+@xref{Close Files And Pipes},
+for more information.
+
+This example also illustrates the use of a variable to represent
+a @var{file} or @var{command}---it is not necessary to always
+use a string constant. Using a variable is generally a good idea,
+because @command{awk} requires that the string value be spelled identically
+every time.
+
+@cindex coprocesses
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex operators, input/output
+@cindex differences in @command{awk} and @command{gawk}, input/output operators
+@item print @var{items} |& @var{command}
+This type of redirection prints the items to the input of @var{command}.
+The difference between this and the
+single-@samp{|} redirection is that the output from @var{command}
+can be read with @code{getline}.
+Thus @var{command} is a @dfn{coprocess}, which works together with,
+but subsidiary to, the @command{awk} program.
+
+This feature is a @command{gawk} extension, and is not available in
+POSIX @command{awk}.
+@xref{Two-way I/O},
+for a more complete discussion.
+@end table
+
+Redirecting output using @samp{>}, @samp{>>}, @samp{|}, or @samp{|&}
+asks the system to open a file, pipe, or coprocess only if the particular
+@var{file} or @var{command} you specify has not already been written
+to by your program or if it has been closed since it was last written to.
+
+@cindex troubleshooting, printing
+It is a common error to use @samp{>} redirection for the first @code{print}
+to a file, and then to use @samp{>>} for subsequent output:
+
+@example
+# clear the file
+print "Don't panic" > "guide.txt"
+@dots{}
+# append
+print "Avoid improbability generators" >> "guide.txt"
+@end example
+
+@noindent
+This is indeed how redirections must be used from the shell. But in
+@command{awk}, it isn't necessary. In this kind of case, a program should
+use @samp{>} for all the @code{print} statements, since the output file
+is only opened once.
+
+@cindex differences in @command{awk} and @command{gawk}, implementation limitations
+@cindex implementation issues@comma{} @command{gawk}, limits
+@cindex @command{awk}, implementation issues, pipes
+@cindex @command{gawk}, implementation issues, pipes
+@ifnotinfo
+As mentioned earlier
+(@pxref{Getline Notes}),
+many
+@end ifnotinfo
+@ifnottex
+Many
+@end ifnottex
+@command{awk} implementations limit the number of pipelines that an @command{awk}
+program may have open to just one! In @command{gawk}, there is no such limit.
+@command{gawk} allows a program to
+open as many pipelines as the underlying operating system permits.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Piping into @command{sh}
+@cindex advanced features, piping into @command{sh}
+@cindex shells, piping commands into
+
+A particularly powerful way to use redirection is to build command lines
+and pipe them into the shell, @command{sh}. For example, suppose you
+have a list of files brought over from a system where all the @value{FN}s
+are stored in uppercase, and you wish to rename them to have names in
+all lowercase. The following program is both simple and efficient:
+
+@c @cindex @command{mv} utility
+@example
+@{ printf("mv %s %s\n", $0, tolower($0)) | "sh" @}
+
+END @{ close("sh") @}
+@end example
+
+The @code{tolower} function returns its argument string with all
+uppercase characters converted to lowercase
+(@pxref{String Functions}).
+The program builds up a list of command lines,
+using the @command{mv} utility to rename the files.
+It then sends the list to the shell for execution.
+@c ENDOFRANGE outre
+@c ENDOFRANGE reout
+
+@node Special Files
+@section Special @value{FFN}s in @command{gawk}
+@c STARTOFRANGE gfn
+@cindex @command{gawk}, @value{FN}s in
+
+@command{gawk} provides a number of special @value{FN}s that it interprets
+internally. These @value{FN}s provide access to standard file descriptors,
+process-related information, and TCP/IP networking.
+
+@menu
+* Special FD:: Special files for I/O.
+* Special Process:: Special files for process information.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+@end menu
+
+@node Special FD
+@subsection Special Files for Standard Descriptors
+@cindex standard input
+@cindex input, standard
+@cindex standard output
+@cindex output, standard
+@cindex error output
+@cindex file descriptors
+@cindex files, descriptors, See file descriptors
+
+Running programs conventionally have three input and output streams
+already available to them for reading and writing. These are known as
+the @dfn{standard input}, @dfn{standard output}, and @dfn{standard error
+output}. These streams are, by default, connected to your terminal, but
+they are often redirected with the shell, via the @samp{<}, @samp{<<},
+@samp{>}, @samp{>>}, @samp{>&}, and @samp{|} operators. Standard error
+is typically used for writing error messages; the reason there are two separate
+streams, standard output and standard error, is so that they can be
+redirected separately.
+
+@cindex differences in @command{awk} and @command{gawk}, error messages
+@cindex error handling
+In other implementations of @command{awk}, the only way to write an error
+message to standard error in an @command{awk} program is as follows:
+
+@example
+print "Serious error detected!" | "cat 1>&2"
+@end example
+
+@noindent
+This works by opening a pipeline to a shell command that can access the
+standard error stream that it inherits from the @command{awk} process.
+This is far from elegant, and it is also inefficient, because it requires a
+separate process. So people writing @command{awk} programs often
+don't do this. Instead, they send the error messages to the
+terminal, like this:
+
+@example
+print "Serious error detected!" > "/dev/tty"
+@end example
+
+@noindent
+This usually has the same effect but not always: although the
+standard error stream is usually the terminal, it can be redirected; when
+that happens, writing to the terminal is not correct. In fact, if
+@command{awk} is run from a background job, it may not have a terminal at all.
+Then opening @file{/dev/tty} fails.
+
+@command{gawk} provides special @value{FN}s for accessing the three standard
+streams, as well as any other inherited open files. If the @value{FN} matches
+one of these special names when @command{gawk} redirects input or output,
+then it directly uses the stream that the @value{FN} stands for.
+These special @value{FN}s work for all operating systems that @command{gawk}
+has been ported to, not just those that are POSIX-compliant:
+
+@cindex @value{FN}s, standard streams in @command{gawk}
+@cindex @code{/dev/@dots{}} special files (@command{gawk})
+@cindex files, @code{/dev/@dots{}} special files
+@c @cindex @code{/dev/stdin} special file
+@c @cindex @code{/dev/stdout} special file
+@c @cindex @code{/dev/stderr} special file
+@c @cindex @code{/dev/fd} special files
+@table @file
+@item /dev/stdin
+The standard input (file descriptor 0).
+
+@item /dev/stdout
+The standard output (file descriptor 1).
+
+@item /dev/stderr
+The standard error output (file descriptor 2).
+
+@item /dev/fd/@var{N}
+The file associated with file descriptor @var{N}. Such a file must
+be opened by the program initiating the @command{awk} execution (typically
+the shell). Unless special pains are taken in the shell from which
+@command{gawk} is invoked, only descriptors 0, 1, and 2 are available.
+@end table
+
+The @value{FN}s @file{/dev/stdin}, @file{/dev/stdout}, and @file{/dev/stderr}
+are aliases for @file{/dev/fd/0}, @file{/dev/fd/1}, and @file{/dev/fd/2},
+respectively. However, they are more self-explanatory.
+The proper way to write an error message in a @command{gawk} program
+is to use @file{/dev/stderr}, like this:
+
+@example
+print "Serious error detected!" > "/dev/stderr"
+@end example
+
+@cindex troubleshooting, quotes with @value{FN}s
+Note the use of quotes around the @value{FN}.
+Like any other redirection, the value must be a string.
+It is a common error to omit the quotes, which leads
+to confusing results.
+@c Exercise: What does it do? :-)
+
+@node Special Process
+@subsection Special Files for Process-Related Information
+
+@cindex files, for process information
+@cindex process information, files for
+@command{gawk} also provides special @value{FN}s that give access to information
+about the running @command{gawk} process. Each of these ``files'' provides
+a single record of information. To read them more than once, they must
+first be closed with the @code{close} function
+(@pxref{Close Files And Pipes}).
+The @value{FN}s are:
+
+@c @cindex @code{/dev/pid} special file
+@c @cindex @code{/dev/pgrpid} special file
+@c @cindex @code{/dev/ppid} special file
+@c @cindex @code{/dev/user} special file
+@table @file
+@item /dev/pid
+Reading this file returns the process ID of the current process,
+in decimal form, terminated with a newline.
+
+@item /dev/ppid
+Reading this file returns the parent process ID of the current process,
+in decimal form, terminated with a newline.
+
+@item /dev/pgrpid
+Reading this file returns the process group ID of the current process,
+in decimal form, terminated with a newline.
+
+@item /dev/user
+Reading this file returns a single record terminated with a newline.
+The fields are separated with spaces. The fields represent the
+following information:
+
+@table @code
+@item $1
+The return value of the @code{getuid} system call
+(the real user ID number).
+
+@item $2
+The return value of the @code{geteuid} system call
+(the effective user ID number).
+
+@item $3
+The return value of the @code{getgid} system call
+(the real group ID number).
+
+@item $4
+The return value of the @code{getegid} system call
+(the effective group ID number).
+@end table
+
+If there are any additional fields, they are the group IDs returned by
+the @code{getgroups} system call.
+(Multiple groups may not be supported on all systems.)
+@end table
+
+These special @value{FN}s may be used on the command line as @value{DF}s,
+as well as for I/O redirections within an @command{awk} program.
+They may not be used as source files with the @option{-f} option.
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@quotation NOTE
+The special files that provide process-related information are now considered
+obsolete and will disappear entirely
+in the next release of @command{gawk}.
+@command{gawk} prints a warning message every time you use one of
+these files.
+To obtain process-related information, use the @code{PROCINFO} array.
+@xref{Auto-set}.
+@end quotation
+
+@node Special Network
+@subsection Special Files for Network Communications
+@cindex networks, support for
+@cindex TCP/IP, support for
+
+Starting with @value{PVERSION} 3.1 of @command{gawk}, @command{awk} programs
+can open a two-way
+TCP/IP connection, acting as either a client or a server.
+This is done using a special @value{FN} of the form:
+
+@example
+@file{/inet/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}
+@end example
+
+The @var{protocol} is one of @samp{tcp}, @samp{udp}, or @samp{raw},
+and the other fields represent the other essential pieces of information
+for making a networking connection.
+These @value{FN}s are used with the @samp{|&} operator for communicating
+with a coprocess
+(@pxref{Two-way I/O}).
+This is an advanced feature, mentioned here only for completeness.
+Full discussion is delayed until
+@ref{TCP/IP Networking}.
+
+@node Special Caveats
+@subsection Special @value{FFN} Caveats
+
+Here is a list of things to bear in mind when using the
+special @value{FN}s that @command{gawk} provides:
+
+@itemize @bullet
+@cindex compatibility mode (@command{gawk}), @value{FN}s
+@cindex @value{FN}s, in compatibility mode
+@item
+Recognition of these special @value{FN}s is disabled if @command{gawk} is in
+compatibility mode (@pxref{Options}).
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@cindex @code{PROCINFO} array
+@item
+@ifnottex
+The
+@end ifnottex
+@ifnotinfo
+As mentioned earlier, the
+@end ifnotinfo
+special files that provide process-related information are now considered
+obsolete and will disappear entirely
+in the next release of @command{gawk}.
+@command{gawk} prints a warning message every time you use one of
+these files.
+@ifnottex
+To obtain process-related information, use the @code{PROCINFO} array.
+@xref{Built-in Variables}.
+@end ifnottex
+
+@item
+Starting with @value{PVERSION} 3.1, @command{gawk} @emph{always}
+interprets these special @value{FN}s.@footnote{Older versions of
+@command{gawk} would interpret these names internally only if the system
+did not actually have a @file{/dev/fd} directory or any of the other
+special files listed earlier. Usually this didn't make a difference,
+but sometimes it did; thus, it was decided to make @command{gawk}'s
+behavior consistent on all systems and to have it always interpret
+the special @value{FN}s itself.}
+For example, using @samp{/dev/fd/4}
+for output actually writes on file descriptor 4, and not on a new
+file descriptor that is @code{dup}'ed from file descriptor 4. Most of
+the time this does not matter; however, it is important to @emph{not}
+close any of the files related to file descriptors 0, 1, and 2.
+Doing so results in unpredictable behavior.
+@end itemize
+@c ENDOFRANGE gfn
+
+@node Close Files And Pipes
+@section Closing Input and Output Redirections
+@cindex files, output, See output files
+@c STARTOFRANGE ifc
+@cindex input files, closing
+@c STARTOFRANGE ofc
+@cindex output, files@comma{} closing
+@c STARTOFRANGE pc
+@cindex pipes, closing
+@c STARTOFRANGE cc
+@cindex coprocesses, closing
+@cindex @code{getline} command, coprocesses@comma{} using from
+
+If the same @value{FN} or the same shell command is used with @code{getline}
+more than once during the execution of an @command{awk} program
+(@pxref{Getline}),
+the file is opened (or the command is executed) the first time only.
+At that time, the first record of input is read from that file or command.
+The next time the same file or command is used with @code{getline},
+another record is read from it, and so on.
+
+Similarly, when a file or pipe is opened for output, the @value{FN} or
+command associated with it is remembered by @command{awk}, and subsequent
+writes to the same file or command are appended to the previous writes.
+The file or pipe stays open until @command{awk} exits.
+
+@cindex @code{close} function
+This implies that special steps are necessary in order to read the same
+file again from the beginning, or to rerun a shell command (rather than
+reading more output from the same command). The @code{close} function
+makes these things possible:
+
+@example
+close(@var{filename})
+@end example
+
+@noindent
+or:
+
+@example
+close(@var{command})
+@end example
+
+The argument @var{filename} or @var{command} can be any expression. Its
+value must @emph{exactly} match the string that was used to open the file or
+start the command (spaces and other ``irrelevant'' characters
+included). For example, if you open a pipe with this:
+
+@example
+"sort -r names" | getline foo
+@end example
+
+@noindent
+then you must close it with this:
+
+@example
+close("sort -r names")
+@end example
+
+Once this function call is executed, the next @code{getline} from that
+file or command, or the next @code{print} or @code{printf} to that
+file or command, reopens the file or reruns the command.
+Because the expression that you use to close a file or pipeline must
+exactly match the expression used to open the file or run the command,
+it is good practice to use a variable to store the @value{FN} or command.
+The previous example becomes the following:
+
+@example
+sortcom = "sort -r names"
+sortcom | getline foo
+@dots{}
+close(sortcom)
+@end example
+
+@noindent
+This helps avoid hard-to-find typographical errors in your @command{awk}
+programs. Here are some of the reasons for closing an output file:
+
+@itemize @bullet
+@item
+To write a file and read it back later on in the same @command{awk}
+program. Close the file after writing it, then
+begin reading it with @code{getline}.
+
+@item
+To write numerous files, successively, in the same @command{awk}
+program. If the files aren't closed, eventually @command{awk} may exceed a
+system limit on the number of open files in one process. It is best to
+close each one when the program has finished writing it.
+
+@item
+To make a command finish. When output is redirected through a pipe,
+the command reading the pipe normally continues to try to read input
+as long as the pipe is open. Often this means the command cannot
+really do its work until the pipe is closed. For example, if
+output is redirected to the @command{mail} program, the message is not
+actually sent until the pipe is closed.
+
+@item
+To run the same program a second time, with the same arguments.
+This is not the same thing as giving more input to the first run!
+
+For example, suppose a program pipes output to the @command{mail} program.
+If it outputs several lines redirected to this pipe without closing
+it, they make a single message of several lines. By contrast, if the
+program closes the pipe after each line of output, then each line makes
+a separate message.
+@end itemize
+
+@cindex differences in @command{awk} and @command{gawk}, @code{close} function
+@cindex portability, @code{close} function and
+If you use more files than the system allows you to have open,
+@command{gawk} attempts to multiplex the available open files among
+your @value{DF}s. @command{gawk}'s ability to do this depends upon the
+facilities of your operating system, so it may not always work. It is
+therefore both good practice and good portability advice to always
+use @code{close} on your files when you are done with them.
+In fact, if you are using a lot of pipes, it is essential that
+you close commands when done. For example, consider something like this:
+
+@example
+@{
+ @dots{}
+ command = ("grep " $1 " /some/file | my_prog -q " $3)
+ while ((command | getline) > 0) @{
+ @var{process output of} command
+ @}
+ # need close(command) here
+@}
+@end example
+
+This example creates a new pipeline based on data in @emph{each} record.
+Without the call to @code{close} indicated in the comment, @command{awk}
+creates child processes to run the commands, until it eventually
+runs out of file descriptors for more pipelines.
+
+Even though each command has finished (as indicated by the end-of-file
+return status from @code{getline}), the child process is not
+terminated;@footnote{The technical terminology is rather morbid.
+The finished child is called a ``zombie,'' and cleaning up after
+it is referred to as ``reaping.''}
+@c Good old UNIX: give the marketing guys fits, that's the ticket
+more importantly, the file descriptor for the pipe
+is not closed and released until @code{close} is called or
+@command{awk} exits.
+
+@code{close} will silently do nothing if given an argument that
+does not represent a file, pipe or coprocess that was opened with
+a redirection.
+
+Note also that @samp{close(FILENAME)} has no
+``magic'' effects on the implicit loop that reads through the
+files named on the command line. It is, more likely, a close
+of a file that was never opened, so @command{awk} silently
+does nothing.
+
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O), pipes@comma{} closing
+When using the @samp{|&} operator to communicate with a coprocess,
+it is occasionally useful to be able to close one end of the two-way
+pipe without closing the other.
+This is done by supplying a second argument to @code{close}.
+As in any other call to @code{close},
+the first argument is the name of the command or special file used
+to start the coprocess.
+The second argument should be a string, with either of the values
+@code{"to"} or @code{"from"}. Case does not matter.
+As this is an advanced feature, a more complete discussion is
+delayed until
+@ref{Two-way I/O},
+which discusses it in more detail and gives an example.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Using @code{close}'s Return Value
+@cindex advanced features, @code{close} function
+@cindex dark corner, @code{close} function
+@cindex @code{close} function, return values
+@cindex return values@comma{} @code{close} function
+@cindex differences in @command{awk} and @command{gawk}, @code{close} function
+@cindex Unix @command{awk}, @code{close} function and
+
+In many versions of Unix @command{awk}, the @code{close} function
+is actually a statement. It is a syntax error to try and use the return
+value from @code{close}:
+@value{DARKCORNER}
+
+@example
+command = "@dots{}"
+command | getline info
+retval = close(command) # syntax error in most Unix awks
+@end example
+
+@command{gawk} treats @code{close} as a function.
+The return value is @minus{}1 if the argument names something
+that was never opened with a redirection, or if there is
+a system problem closing the file or process.
+In these cases, @command{gawk} sets the built-in variable
+@code{ERRNO} to a string describing the problem.
+
+In @command{gawk},
+when closing a pipe or coprocess (input or output),
+the return value is the exit status of the command.@footnote{
+This is a full 16-bit value as returned by the @code{wait}
+system call. See the system manual pages for information on
+how to decode this value.}
+Otherwise, it is the return value from the system's @code{close} or
+@code{fclose} C functions when closing input or output
+files, respectively.
+This value is zero if the close succeeds, or @minus{}1 if
+it fails.
+
+The POSIX standard is very vague; it says that @code{close}
+returns zero on success and non-zero otherwise. In general,
+different implementations vary in what they report when closing
+pipes; thus the return value cannot be used portably.
+@value{DARKCORNER}
+
+@ignore
+@c 4/27/2003: Commenting this out for now, given the above
+@c return of 16-bit value
+The return value for closing a pipeline is particularly useful.
+It allows you to get the output from a command as well as its
+exit status.
+@c 8/21/2002, FIXME: Maybe the code and this doc should be adjusted to
+@c create values indicating death-by-signal? Sigh.
+
+@cindex pipes, closing
+@cindex POSIX @command{awk}, pipes@comma{} closing
+For POSIX-compliant systems,
+if the exit status is a number above 128, then the program
+was terminated by a signal. Subtract 128 to get the signal number:
+
+@example
+exit_val = close(command)
+if (exit_val > 128)
+ print command, "died with signal", exit_val - 128
+else
+ print command, "exited with code", exit_val
+@end example
+
+Currently, in @command{gawk}, this only works for commands
+piping into @code{getline}. For commands piped into
+from @code{print} or @code{printf}, the
+return value from @code{close} is that of the library's
+@code{pclose} function.
+@end ignore
+@c ENDOFRANGE ifc
+@c ENDOFRANGE ofc
+@c ENDOFRANGE pc
+@c ENDOFRANGE cc
+@c ENDOFRANGE prnt
+
+@node Expressions
+@chapter Expressions
+@c STARTOFRANGE exps
+@cindex expressions
+
+Expressions are the basic building blocks of @command{awk} patterns
+and actions. An expression evaluates to a value that you can print, test,
+or pass to a function. Additionally, an expression
+can assign a new value to a variable or a field by using an assignment operator.
+
+An expression can serve as a pattern or action statement on its own.
+Most other kinds of
+statements contain one or more expressions that specify the data on which to
+operate. As in other languages, expressions in @command{awk} include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+@menu
+* Constants:: String, numeric and regexp constants.
+* Using Constant Regexps:: When and how to use a regexp constant.
+* Variables:: Variables give names to values for later use.
+* Conversion:: The conversion of strings to numbers and vice
+ versa.
+* Arithmetic Ops:: Arithmetic operations (@samp{+}, @samp{-},
+ etc.)
+* Concatenation:: Concatenating strings.
+* Assignment Ops:: Changing the value of a variable or a field.
+* Increment Ops:: Incrementing the numeric value of a variable.
+* Truth Values:: What is ``true'' and what is ``false''.
+* Typing and Comparison:: How variables acquire types and how this
+ affects comparison of numbers and strings with
+ @samp{<}, etc.
+* Boolean Ops:: Combining comparison expressions using boolean
+ operators @samp{||} (``or''), @samp{&&}
+ (``and'') and @samp{!} (``not'').
+* Conditional Exp:: Conditional expressions select between two
+ subexpressions under control of a third
+ subexpression.
+* Function Calls:: A function call is an expression.
+* Precedence:: How various operators nest.
+@end menu
+
+@node Constants
+@section Constant Expressions
+@cindex constants, types of
+
+The simplest type of expression is the @dfn{constant}, which always has
+the same value. There are three types of constants: numeric,
+string, and regular expression.
+
+Each is used in the appropriate context when you need a data
+value that isn't going to change. Numeric constants can
+have different forms, but are stored identically internally.
+
+@menu
+* Scalar Constants:: Numeric and string constants.
+* Nondecimal-numbers:: What are octal and hex numbers.
+* Regexp Constants:: Regular Expression constants.
+@end menu
+
+@node Scalar Constants
+@subsection Numeric and String Constants
+
+@cindex numeric, constants
+A @dfn{numeric constant} stands for a number. This number can be an
+integer, a decimal fraction, or a number in scientific (exponential)
+notation.@footnote{The internal representation of all numbers,
+including integers, uses double-precision
+floating-point numbers.
+On most modern systems, these are in IEEE 754 standard format.}
+Here are some examples of numeric constants that all
+have the same value:
+
+@example
+105
+1.05e+2
+1050e-1
+@end example
+
+@cindex string constants
+A string constant consists of a sequence of characters enclosed in
+double-quotation marks. For example:
+
+@example
+"parrot"
+@end example
+
+@noindent
+@cindex differences in @command{awk} and @command{gawk}, strings
+@cindex strings, length of
+represents the string whose contents are @samp{parrot}. Strings in
+@command{gawk} can be of any length, and they can contain any of the possible
+eight-bit ASCII characters including ASCII @sc{nul} (character code zero).
+Other @command{awk}
+implementations may have difficulty with some character codes.
+
+@node Nondecimal-numbers
+@subsection Octal and Hexadecimal Numbers
+@cindex octal numbers
+@cindex hexadecimal numbers
+@cindex numbers, octal
+@cindex numbers, hexadecimal
+
+In @command{awk}, all numbers are in decimal; i.e., base 10. Many other
+programming languages allow you to specify numbers in other bases, often
+octal (base 8) and hexadecimal (base 16).
+In octal, the numbers go 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, etc.
+Just as @samp{11}, in decimal, is 1 times 10 plus 1, so
+@samp{11}, in octal, is 1 times 8, plus 1. This equals 9 in decimal.
+In hexadecimal, there are 16 digits. Since the everyday decimal
+number system only has ten digits (@samp{0}--@samp{9}), the letters
+@samp{a} through @samp{f} are used to represent the rest.
+(Case in the letters is usually irrelevant; hexadecimal @samp{a} and @samp{A}
+have the same value.)
+Thus, @samp{11}, in
+hexadecimal, is 1 times 16 plus 1, which equals 17 in decimal.
+
+Just by looking at plain @samp{11}, you can't tell what base it's in.
+So, in C, C++, and other languages derived from C,
+@c such as PERL, but we won't mention that....
+there is a special notation to help signify the base.
+Octal numbers start with a leading @samp{0},
+and hexadecimal numbers start with a leading @samp{0x} or @samp{0X}:
+
+@table @code
+@item 11
+Decimal value 11.
+
+@item 011
+Octal 11, decimal value 9.
+
+@item 0x11
+Hexadecimal 11, decimal value 17.
+@end table
+
+This example shows the difference:
+
+@example
+$ gawk 'BEGIN @{ printf "%d, %d, %d\n", 011, 11, 0x11 @}'
+@print{} 9, 11, 17
+@end example
+
+Being able to use octal and hexadecimal constants in your programs is most
+useful when working with data that cannot be represented conveniently as
+characters or as regular numbers, such as binary data of various sorts.
+
+@cindex @command{gawk}, octal numbers and
+@cindex @command{gawk}, hexadecimal numbers and
+@command{gawk} allows the use of octal and hexadecimal
+constants in your program text. However, such numbers in the input data
+are not treated differently; doing so by default would break old
+programs.
+(If you really need to do this, use the @option{--non-decimal-data}
+command-line option;
+@pxref{Nondecimal Data}.)
+If you have octal or hexadecimal data,
+you can use the @code{strtonum} function
+(@pxref{String Functions})
+to convert the data into a number.
+Most of the time, you will want to use octal or hexadecimal constants
+when working with the built-in bit manipulation functions;
+see @ref{Bitwise Functions},
+for more information.
+
+Unlike some early C implementations, @samp{8} and @samp{9} are not valid
+in octal constants; e.g., @command{gawk} treats @samp{018} as decimal 18:
+
+@example
+$ gawk 'BEGIN @{ print "021 is", 021 ; print 018 @}'
+@print{} 021 is 17
+@print{} 18
+@end example
+
+@cindex compatibility mode (@command{gawk}), octal numbers
+@cindex compatibility mode (@command{gawk}), hexadecimal numbers
+Octal and hexadecimal source code constants are a @command{gawk} extension.
+If @command{gawk} is in compatibility mode
+(@pxref{Options}),
+they are not available.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: A Constant's Base Does Not Affect Its Value
+@cindex advanced features, constants@comma{} values of
+
+Once a numeric constant has
+been converted internally into a number,
+@command{gawk} no longer remembers
+what the original form of the constant was; the internal value is
+always used. This has particular consequences for conversion of
+numbers to strings:
+
+@example
+$ gawk 'BEGIN @{ printf "0x11 is <%s>\n", 0x11 @}'
+@print{} 0x11 is <17>
+@end example
+
+@node Regexp Constants
+@subsection Regular Expression Constants
+
+@c STARTOFRANGE rec
+@cindex regexp constants
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+A regexp constant is a regular expression description enclosed in
+slashes, such as @code{@w{/^beginning and end$/}}. Most regexps used in
+@command{awk} programs are constant, but the @samp{~} and @samp{!~}
+matching operators can also match computed or ``dynamic'' regexps
+(which are just ordinary strings or variables that contain a regexp).
+@c ENDOFRANGE cnst
+
+@node Using Constant Regexps
+@section Using Regular Expression Constants
+
+@cindex dark corner, regexp constants
+When used on the righthand side of the @samp{~} or @samp{!~}
+operators, a regexp constant merely stands for the regexp that is to be
+matched.
+However, regexp constants (such as @code{/foo/}) may be used like simple expressions.
+When a
+regexp constant appears by itself, it has the same meaning as if it appeared
+in a pattern, i.e., @samp{($0 ~ /foo/)}
+@value{DARKCORNER}
+@xref{Expression Patterns}.
+This means that the following two code segments:
+
+@example
+if ($0 ~ /barfly/ || $0 ~ /camelot/)
+ print "found"
+@end example
+
+@noindent
+and:
+
+@example
+if (/barfly/ || /camelot/)
+ print "found"
+@end example
+
+@noindent
+are exactly equivalent.
+One rather bizarre consequence of this rule is that the following
+Boolean expression is valid, but does not do what the user probably
+intended:
+
+@example
+# note that /foo/ is on the left of the ~
+if (/foo/ ~ $1) print "found foo"
+@end example
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@cindex @command{gawk}, regexp constants and
+@cindex regexp constants, in @command{gawk}
+@noindent
+This code is ``obviously'' testing @code{$1} for a match against the regexp
+@code{/foo/}. But in fact, the expression @samp{/foo/ ~ $1} actually means
+@samp{($0 ~ /foo/) ~ $1}. In other words, first match the input record
+against the regexp @code{/foo/}. The result is either zero or one,
+depending upon the success or failure of the match. That result
+is then matched against the first field in the record.
+Because it is unlikely that you would ever really want to make this kind of
+test, @command{gawk} issues a warning when it sees this construct in
+a program.
+Another consequence of this rule is that the assignment statement:
+
+@example
+matches = /foo/
+@end example
+
+@noindent
+assigns either zero or one to the variable @code{matches}, depending
+upon the contents of the current input record.
+This feature of the language has never been well documented until the
+POSIX specification.
+
+@cindex differences in @command{awk} and @command{gawk}, regexp constants
+@cindex dark corner, regexp constants, as arguments to user-defined functions
+@cindex @code{gensub} function (@command{gawk})
+@cindex @code{sub} function
+@cindex @code{gsub} function
+Constant regular expressions are also used as the first argument for
+the @code{gensub}, @code{sub}, and @code{gsub} functions, and as the
+second argument of the @code{match} function
+(@pxref{String Functions}).
+Modern implementations of @command{awk}, including @command{gawk}, allow
+the third argument of @code{split} to be a regexp constant, but some
+older implementations do not.
+@value{DARKCORNER}
+This can lead to confusion when attempting to use regexp constants
+as arguments to user-defined functions
+(@pxref{User-defined}).
+For example:
+
+@example
+function mysub(pat, repl, str, global)
+@{
+ if (global)
+ gsub(pat, repl, str)
+ else
+ sub(pat, repl, str)
+ return str
+@}
+
+@{
+ @dots{}
+ text = "hi! hi yourself!"
+ mysub(/hi/, "howdy", text, 1)
+ @dots{}
+@}
+@end example
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+In this example, the programmer wants to pass a regexp constant to the
+user-defined function @code{mysub}, which in turn passes it on to
+either @code{sub} or @code{gsub}. However, what really happens is that
+the @code{pat} parameter is either one or zero, depending upon whether
+or not @code{$0} matches @code{/hi/}.
+@command{gawk} issues a warning when it sees a regexp constant used as
+a parameter to a user-defined function, since passing a truth value in
+this way is probably not what was intended.
+@c ENDOFRANGE rec
+
+@node Variables
+@section Variables
+
+@cindex variables, user-defined
+@cindex user-defined, variables
+Variables are ways of storing values at one point in your program for
+use later in another part of your program. They can be manipulated
+entirely within the program text, and they can also be assigned values
+on the @command{awk} command line.
+
+@menu
+* Using Variables:: Using variables in your programs.
+* Assignment Options:: Setting variables on the command-line and a
+ summary of command-line syntax. This is an
+ advanced method of input.
+@end menu
+
+@node Using Variables
+@subsection Using Variables in a Program
+
+Variables let you give names to values and refer to them later. Variables
+have already been used in many of the examples. The name of a variable
+must be a sequence of letters, digits, or underscores, and it may not begin
+with a digit. Case is significant in variable names; @code{a} and @code{A}
+are distinct variables.
+
+A variable name is a valid expression by itself; it represents the
+variable's current value. Variables are given new values with
+@dfn{assignment operators}, @dfn{increment operators}, and
+@dfn{decrement operators}.
+@xref{Assignment Ops}.
+@c NEXT ED: Can also be changed by sub, gsub, split
+
+@cindex variables, built-in
+@cindex variables, initializing
+A few variables have special built-in meanings, such as @code{FS} (the
+field separator), and @code{NF} (the number of fields in the current input
+record). @xref{Built-in Variables}, for a list of the built-in variables.
+These built-in variables can be used and assigned just like all other
+variables, but their values are also used or changed automatically by
+@command{awk}. All built-in variables' names are entirely uppercase.
+
+Variables in @command{awk} can be assigned either numeric or string values.
+The kind of value a variable holds can change over the life of a program.
+By default, variables are initialized to the empty string, which
+is zero if converted to a number. There is no need to
+``initialize'' each variable explicitly in @command{awk},
+which is what you would do in C and in most other traditional languages.
+
+@node Assignment Options
+@subsection Assigning Variables on the Command Line
+@cindex variables, assigning on command line
+@cindex command line, variables@comma{} assigning on
+
+Any @command{awk} variable can be set by including a @dfn{variable assignment}
+among the arguments on the command line when @command{awk} is invoked
+(@pxref{Other Arguments}).
+Such an assignment has the following form:
+
+@example
+@var{variable}=@var{text}
+@end example
+
+@cindex @code{-v} option, variables@comma{} assigning
+@noindent
+With it, a variable is set either at the beginning of the
+@command{awk} run or in between input files.
+When the assignment is preceded with the @option{-v} option,
+as in the following:
+
+@example
+-v @var{variable}=@var{text}
+@end example
+
+@noindent
+the variable is set at the very beginning, even before the
+@code{BEGIN} rules are run. The @option{-v} option and its assignment
+must precede all the @value{FN} arguments, as well as the program text.
+(@xref{Options}, for more information about
+the @option{-v} option.)
+Otherwise, the variable assignment is performed at a time determined by
+its position among the input file arguments---after the processing of the
+preceding input file argument. For example:
+
+@example
+awk '@{ print $n @}' n=4 inventory-shipped n=2 BBS-list
+@end example
+
+@noindent
+prints the value of field number @code{n} for all input records. Before
+the first file is read, the command line sets the variable @code{n}
+equal to four. This causes the fourth field to be printed in lines from
+the file @file{inventory-shipped}. After the first file has finished,
+but before the second file is started, @code{n} is set to two, so that the
+second field is printed in lines from @file{BBS-list}:
+
+@example
+$ awk '@{ print $n @}' n=4 inventory-shipped n=2 BBS-list
+@print{} 15
+@print{} 24
+@dots{}
+@print{} 555-5553
+@print{} 555-3412
+@dots{}
+@end example
+
+@cindex dark corner, command-line arguments
+Command-line arguments are made available for explicit examination by
+the @command{awk} program in the @code{ARGV} array
+(@pxref{ARGC and ARGV}).
+@command{awk} processes the values of command-line assignments for escape
+sequences
+(@pxref{Escape Sequences}).
+@value{DARKCORNER}
+
+@node Conversion
+@section Conversion of Strings and Numbers
+
+@cindex converting, strings to numbers
+@cindex strings, converting
+@cindex numbers, converting
+@cindex converting, numbers
+Strings are converted to numbers and numbers are converted to strings, if the context
+of the @command{awk} program demands it. For example, if the value of
+either @code{foo} or @code{bar} in the expression @samp{foo + bar}
+happens to be a string, it is converted to a number before the addition
+is performed. If numeric values appear in string concatenation, they
+are converted to strings. Consider the following:
+
+@example
+two = 2; three = 3
+print (two three) + 4
+@end example
+
+@noindent
+This prints the (numeric) value 27. The numeric values of
+the variables @code{two} and @code{three} are converted to strings and
+concatenated together. The resulting string is converted back to the
+number 23, to which 4 is then added.
+
+@cindex null strings, converting numbers to strings
+@cindex type conversion
+If, for some reason, you need to force a number to be converted to a
+string, concatenate the empty string, @code{""}, with that number.
+To force a string to be converted to a number, add zero to that string.
+A string is converted to a number by interpreting any numeric prefix
+of the string as numerals:
+@code{"2.5"} converts to 2.5, @code{"1e3"} converts to 1000, and @code{"25fix"}
+has a numeric value of 25.
+Strings that can't be interpreted as valid numbers convert to zero.
+
+@cindex @code{CONVFMT} variable
+The exact manner in which numbers are converted into strings is controlled
+by the @command{awk} built-in variable @code{CONVFMT} (@pxref{Built-in Variables}).
+Numbers are converted using the @code{sprintf} function
+with @code{CONVFMT} as the format
+specifier
+(@pxref{String Functions}).
+
+@code{CONVFMT}'s default value is @code{"%.6g"}, which prints a value with
+at least six significant digits. For some applications, you might want to
+change it to specify more precision.
+On most modern machines,
+17 digits is enough to capture a floating-point number's
+value exactly,
+most of the time.@footnote{Pathological cases can require up to
+752 digits (!), but we doubt that you need to worry about this.}
+
+@cindex dark corner, @code{CONVFMT} variable
+Strange results can occur if you set @code{CONVFMT} to a string that doesn't
+tell @code{sprintf} how to format floating-point numbers in a useful way.
+For example, if you forget the @samp{%} in the format, @command{awk} converts
+all numbers to the same constant string.
+As a special case, if a number is an integer, then the result of converting
+it to a string is @emph{always} an integer, no matter what the value of
+@code{CONVFMT} may be. Given the following code fragment:
+
+@example
+CONVFMT = "%2.2f"
+a = 12
+b = a ""
+@end example
+
+@noindent
+@code{b} has the value @code{"12"}, not @code{"12.00"}.
+@value{DARKCORNER}
+
+@cindex POSIX @command{awk}, @code{OFMT} variable and
+@cindex @code{OFMT} variable
+@cindex portability, new @command{awk} vs. old @command{awk}
+@cindex @command{awk}, new vs. old, @code{OFMT} variable
+Prior to the POSIX standard, @command{awk} used the value
+of @code{OFMT} for converting numbers to strings. @code{OFMT}
+specifies the output format to use when printing numbers with @code{print}.
+@code{CONVFMT} was introduced in order to separate the semantics of
+conversion from the semantics of printing. Both @code{CONVFMT} and
+@code{OFMT} have the same default value: @code{"%.6g"}. In the vast majority
+of cases, old @command{awk} programs do not change their behavior.
+However, these semantics for @code{OFMT} are something to keep in mind if you must
+port your new style program to older implementations of @command{awk}.
+We recommend
+that instead of changing your programs, just port @command{gawk} itself.
+@xref{Print},
+for more information on the @code{print} statement.
+
+Finally, once again, where you are can matter when it comes to
+converting between numbers and strings. In
+@ref{Locales}, we mentioned that the
+local character set and language (the locale) can affect how @command{gawk} matches
+characters. The locale also affects numeric formats. In particular, for @command{awk}
+programs, it affects the decimal point character. The @code{"C"} locale, and most
+English-language locales, use the period character (@samp{.}) as the decimal point.
+However, many (if not most) European and non-English locales use the comma (@samp{,})
+as the decimal point character.
+
+The POSIX standard says that @command{awk} always uses the period as the decimal
+point when reading the @command{awk} program source code, and for command-line
+variable assignments (@pxref{Other Arguments}).
+However, when interpreting input data, for @code{print} and @code{printf} output,
+and for number to string conversion, the local decimal point character is used.
+As of @value{PVERSION} 3.1.3, @command{gawk} fully complies with this aspect
+of the standard. Here are some examples indicating the difference in behavior,
+on a GNU/Linux system:
+
+@example
+$ gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'
+@print{} 3.14159
+$ LC_ALL=en_DK gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'
+@print{} 3,14159
+$ echo 4,321 | gawk '@{ print $1 + 1 @}'
+@print{} 5
+$ echo 4,321 | LC_ALL=en_DK gawk '@{ print $1 + 1 @}'
+@print{} 5,321
+@end example
+
+@noindent
+The @samp{en_DK} locale is for English in Denmark, where the comma acts as
+the decimal point separator. In the normal @code{"C"} locale, @command{gawk}
+treats @samp{4,321} as @samp{4}, while in the Danish locale, it's treated
+as the full number, @samp{4.321}.
+
+@node Arithmetic Ops
+@section Arithmetic Operators
+@cindex arithmetic operators
+@cindex operators, arithmetic
+@c @cindex addition
+@c @cindex subtraction
+@c @cindex multiplication
+@c @cindex division
+@c @cindex remainder
+@c @cindex quotient
+@c @cindex exponentiation
+
+The @command{awk} language uses the common arithmetic operators when
+evaluating expressions. All of these arithmetic operators follow normal
+precedence rules and work as you would expect them to.
+
+The following example uses a file named @file{grades}, which contains
+a list of student names as well as three test scores per student (it's
+a small class):
+
+@example
+Pat 100 97 58
+Sandy 84 72 93
+Chris 72 92 89
+@end example
+
+@noindent
+This programs takes the file @file{grades} and prints the average
+of the scores:
+
+@example
+$ awk '@{ sum = $2 + $3 + $4 ; avg = sum / 3
+> print $1, avg @}' grades
+@print{} Pat 85
+@print{} Sandy 83
+@print{} Chris 84.3333
+@end example
+
+The following list provides the arithmetic operators in @command{awk}, in order from
+the highest precedence to the lowest:
+
+@table @code
+@item - @var{x}
+Negation.
+
+@item + @var{x}
+Unary plus; the expression is converted to a number.
+
+@cindex POSIX @command{awk}, arithmetic operators and
+@item @var{x} ^ @var{y}
+@itemx @var{x} ** @var{y}
+Exponentiation; @var{x} raised to the @var{y} power. @samp{2 ^ 3} has
+the value eight; the character sequence @samp{**} is equivalent to
+@samp{^}.
+
+@item @var{x} * @var{y}
+Multiplication.
+
+@cindex troubleshooting, division
+@cindex division
+@item @var{x} / @var{y}
+Division; because all numbers in @command{awk} are floating-point
+numbers, the result is @emph{not} rounded to an integer---@samp{3 / 4} has
+the value 0.75. (It is a common mistake, especially for C programmers,
+to forget that @emph{all} numbers in @command{awk} are floating-point,
+and that division of integer-looking constants produces a real number,
+not an integer.)
+
+@item @var{x} % @var{y}
+Remainder; further discussion is provided in the text, just
+after this list.
+
+@item @var{x} + @var{y}
+Addition.
+
+@item @var{x} - @var{y}
+Subtraction.
+@end table
+
+Unary plus and minus have the same precedence,
+the multiplication operators all have the same precedence, and
+addition and subtraction have the same precedence.
+
+@cindex differences in @command{awk} and @command{gawk}, trunc-mod operation
+@cindex trunc-mod operation
+When computing the remainder of @code{@var{x} % @var{y}},
+the quotient is rounded toward zero to an integer and
+multiplied by @var{y}. This result is subtracted from @var{x};
+this operation is sometimes known as ``trunc-mod.'' The following
+relation always holds:
+
+@example
+b * int(a / b) + (a % b) == a
+@end example
+
+One possibly undesirable effect of this definition of remainder is that
+@code{@var{x} % @var{y}} is negative if @var{x} is negative. Thus:
+
+@example
+-17 % 8 = -1
+@end example
+
+In other @command{awk} implementations, the signedness of the remainder
+may be machine-dependent.
+@c !!! what does posix say?
+
+@cindex portability, @code{**} operator and
+@cindex @code{*} (asterisk), @code{**} operator
+@cindex asterisk (@code{*}), @code{**} operator
+@quotation NOTE
+The POSIX standard only specifies the use of @samp{^}
+for exponentiation.
+For maximum portability, do not use the @samp{**} operator.
+@end quotation
+
+@node Concatenation
+@section String Concatenation
+@cindex Kernighan, Brian
+@quotation
+@i{It seemed like a good idea at the time.}@*
+Brian Kernighan
+@end quotation
+
+@cindex string operators
+@cindex operators, string
+@cindex concatenating
+There is only one string operation: concatenation. It does not have a
+specific operator to represent it. Instead, concatenation is performed by
+writing expressions next to one another, with no operator. For example:
+
+@example
+$ awk '@{ print "Field number one: " $1 @}' BBS-list
+@print{} Field number one: aardvark
+@print{} Field number one: alpo-net
+@dots{}
+@end example
+
+Without the space in the string constant after the @samp{:}, the line
+runs together. For example:
+
+@example
+$ awk '@{ print "Field number one:" $1 @}' BBS-list
+@print{} Field number one:aardvark
+@print{} Field number one:alpo-net
+@dots{}
+@end example
+
+@cindex troubleshooting, string concatenation
+Because string concatenation does not have an explicit operator, it is
+often necessary to insure that it happens at the right time by using
+parentheses to enclose the items to concatenate. For example, the
+following code fragment does not concatenate @code{file} and @code{name}
+as you might expect:
+
+@example
+file = "file"
+name = "name"
+print "something meaningful" > file name
+@end example
+
+@noindent
+It is necessary to use the following:
+
+@example
+print "something meaningful" > (file name)
+@end example
+
+@cindex order of evaluation, concatenation
+@cindex evaluation order, concatenation
+@cindex side effects
+Parentheses should be used around concatenation in all but the
+most common contexts, such as on the righthand side of @samp{=}.
+Be careful about the kinds of expressions used in string concatenation.
+In particular, the order of evaluation of expressions used for concatenation
+is undefined in the @command{awk} language. Consider this example:
+
+@example
+BEGIN @{
+ a = "don't"
+ print (a " " (a = "panic"))
+@}
+@end example
+
+@noindent
+It is not defined whether the assignment to @code{a} happens
+before or after the value of @code{a} is retrieved for producing the
+concatenated value. The result could be either @samp{don't panic},
+or @samp{panic panic}.
+@c see test/nasty.awk for a worse example
+The precedence of concatenation, when mixed with other operators, is often
+counter-intuitive. Consider this example:
+
+@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
+$ awk 'BEGIN @{ print -12 " " -24 @}'
+@print{} -12-24
+@end example
+
+This ``obviously'' is concatenating @minus{}12, a space, and @minus{}24.
+But where did the space disappear to?
+The answer lies in the combination of operator precedences and
+@command{awk}'s automatic conversion rules. To get the desired result,
+write the program in the following manner:
+
+@example
+$ awk 'BEGIN @{ print -12 " " (-24) @}'
+@print{} -12 -24
+@end example
+
+This forces @command{awk} to treat the @samp{-} on the @samp{-24} as unary.
+Otherwise, it's parsed as follows:
+
+@display
+ @minus{}12 (@code{"@ "} @minus{} 24)
+@result{} @minus{}12 (0 @minus{} 24)
+@result{} @minus{}12 (@minus{}24)
+@result{} @minus{}12@minus{}24
+@end display
+
+As mentioned earlier,
+when doing concatenation, @emph{parenthesize}. Otherwise,
+you're never quite sure what you'll get.
+
+@node Assignment Ops
+@section Assignment Expressions
+@c STARTOFRANGE asop
+@cindex assignment operators
+@c STARTOFRANGE opas
+@cindex operators, assignment
+@c STARTOFRANGE exas
+@cindex expressions, assignment
+@cindex @code{=} (equals sign), @code{=} operator
+@cindex equals sign (@code{=}), @code{=} operator
+An @dfn{assignment} is an expression that stores a (usually different)
+value into a variable. For example, let's assign the value one to the variable
+@code{z}:
+
+@example
+z = 1
+@end example
+
+After this expression is executed, the variable @code{z} has the value one.
+Whatever old value @code{z} had before the assignment is forgotten.
+
+Assignments can also store string values. For example, the
+following stores
+the value @code{"this food is good"} in the variable @code{message}:
+
+@example
+thing = "food"
+predicate = "good"
+message = "this " thing " is " predicate
+@end example
+
+@noindent
+@cindex side effects, assignment expressions
+This also illustrates string concatenation.
+The @samp{=} sign is called an @dfn{assignment operator}. It is the
+simplest assignment operator because the value of the righthand
+operand is stored unchanged.
+Most operators (addition, concatenation, and so on) have no effect
+except to compute a value. If the value isn't used, there's no reason to
+use the operator. An assignment operator is different; it does
+produce a value, but even if you ignore it, the assignment still
+makes itself felt through the alteration of the variable. We call this
+a @dfn{side effect}.
+
+@cindex lvalues/rvalues
+@cindex rvalues/lvalues
+@cindex assignment operators, lvalues/rvalues
+@cindex operators, assignment
+The lefthand operand of an assignment need not be a variable
+(@pxref{Variables}); it can also be a field
+(@pxref{Changing Fields}) or
+an array element (@pxref{Arrays}).
+These are all called @dfn{lvalues},
+which means they can appear on the lefthand side of an assignment operator.
+The righthand operand may be any expression; it produces the new value
+that the assignment stores in the specified variable, field, or array
+element. (Such values are called @dfn{rvalues}.)
+
+@cindex variables, types of
+It is important to note that variables do @emph{not} have permanent types.
+A variable's type is simply the type of whatever value it happens
+to hold at the moment. In the following program fragment, the variable
+@code{foo} has a numeric value at first, and a string value later on:
+
+@example
+foo = 1
+print foo
+foo = "bar"
+print foo
+@end example
+
+@noindent
+When the second assignment gives @code{foo} a string value, the fact that
+it previously had a numeric value is forgotten.
+
+String values that do not begin with a digit have a numeric value of
+zero. After executing the following code, the value of @code{foo} is five:
+
+@example
+foo = "a string"
+foo = foo + 5
+@end example
+
+@quotation NOTE
+Using a variable as a number and then later as a string
+can be confusing and is poor programming style. The previous two examples
+illustrate how @command{awk} works, @emph{not} how you should write your
+programs!
+@end quotation
+
+An assignment is an expression, so it has a value---the same value that
+is assigned. Thus, @samp{z = 1} is an expression with the value one.
+One consequence of this is that you can write multiple assignments together,
+such as:
+
+@example
+x = y = z = 5
+@end example
+
+@noindent
+This example stores the value five in all three variables
+(@code{x}, @code{y}, and @code{z}).
+It does so because the
+value of @samp{z = 5}, which is five, is stored into @code{y} and then
+the value of @samp{y = z = 5}, which is five, is stored into @code{x}.
+
+Assignments may be used anywhere an expression is called for. For
+example, it is valid to write @samp{x != (y = 1)} to set @code{y} to one,
+and then test whether @code{x} equals one. But this style tends to make
+programs hard to read; such nesting of assignments should be avoided,
+except perhaps in a one-shot program.
+
+@cindex @code{+} (plus sign), @code{+=} operator
+@cindex plus sign (@code{+}), @code{+=} operator
+Aside from @samp{=}, there are several other assignment operators that
+do arithmetic with the old value of the variable. For example, the
+operator @samp{+=} computes a new value by adding the righthand value
+to the old value of the variable. Thus, the following assignment adds
+five to the value of @code{foo}:
+
+@example
+foo += 5
+@end example
+
+@noindent
+This is equivalent to the following:
+
+@example
+foo = foo + 5
+@end example
+
+@noindent
+Use whichever makes the meaning of your program clearer.
+
+There are situations where using @samp{+=} (or any assignment operator)
+is @emph{not} the same as simply repeating the lefthand operand in the
+righthand expression. For example:
+
+@cindex Rankin, Pat
+@example
+# Thanks to Pat Rankin for this example
+BEGIN @{
+ foo[rand()] += 5
+ for (x in foo)
+ print x, foo[x]
+
+ bar[rand()] = bar[rand()] + 5
+ for (x in bar)
+ print x, bar[x]
+@}
+@end example
+
+@cindex operators, assignment, evaluation order
+@cindex assignment operators, evaluation order
+@noindent
+The indices of @code{bar} are practically guaranteed to be different, because
+@code{rand} returns different values each time it is called.
+(Arrays and the @code{rand} function haven't been covered yet.
+@xref{Arrays},
+and see @ref{Numeric Functions}, for more information).
+This example illustrates an important fact about assignment
+operators: the lefthand expression is only evaluated @emph{once}.
+It is up to the implementation as to which expression is evaluated
+first, the lefthand or the righthand.
+Consider this example:
+
+@example
+i = 1
+a[i += 2] = i + 1
+@end example
+
+@noindent
+The value of @code{a[3]} could be either two or four.
+
+@ref{table-assign-ops} lists the arithmetic assignment operators. In each
+case, the righthand operand is an expression whose value is converted
+to a number.
+
+@cindex @code{-} (hyphen), @code{-=} operator
+@cindex hyphen (@code{-}), @code{-=} operator
+@cindex @code{*} (asterisk), @code{*=} operator
+@cindex asterisk (@code{*}), @code{*=} operator
+@cindex @code{/} (forward slash), @code{/=} operator
+@cindex forward slash (@code{/}), @code{/=} operator
+@cindex @code{%} (percent sign), @code{%=} operator
+@cindex percent sign (@code{%}), @code{%=} operator
+@cindex @code{^} (caret), @code{^=} operator
+@cindex caret (@code{^}), @code{^=} operator
+@cindex @code{*} (asterisk), @code{**=} operator
+@cindex asterisk (@code{*}), @code{**=} operator
+@float Table,table-assign-ops
+@caption{Arithmetic Assignment Operators}
+@multitable @columnfractions .30 .70
+@headitem Operator @tab Effect
+@item @var{lvalue} @code{+=} @var{increment} @tab Adds @var{increment} to the value of @var{lvalue}.
+@item @var{lvalue} @code{-=} @var{decrement} @tab Subtracts @var{decrement} from the value of @var{lvalue}.
+@item @var{lvalue} @code{*=} @var{coefficient} @tab Multiplies the value of @var{lvalue} by @var{coefficient}.
+@item @var{lvalue} @code{/=} @var{divisor} @tab Divides the value of @var{lvalue} by @var{divisor}.
+@item @var{lvalue} @code{%=} @var{modulus} @tab Sets @var{lvalue} to its remainder by @var{modulus}.
+@cindex @command{awk} language, POSIX version
+@cindex POSIX @command{awk}
+@item @var{lvalue} @code{^=} @var{power} @tab
+@item @var{lvalue} @code{**=} @var{power} @tab Raises @var{lvalue} to the power @var{power}.
+@end multitable
+@end float
+
+@cindex POSIX @command{awk}, @code{**=} operator and
+@cindex portability, @code{**=} operator and
+@quotation NOTE
+Only the @samp{^=} operator is specified by POSIX.
+For maximum portability, do not use the @samp{**=} operator.
+@end quotation
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Syntactic Ambiguities Between @samp{/=} and Regular Expressions
+@cindex advanced features, regexp constants
+@cindex dark corner, regexp constants, @code{/=} operator and
+@cindex @code{/} (forward slash), @code{/=} operator, vs. @code{/=@dots{}/} regexp constant
+@cindex forward slash (@code{/}), @code{/=} operator, vs. @code{/=@dots{}/} regexp constant
+@cindex regexp constants, @code{/=@dots{}/}, @code{/=} operator and
+
+@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 dark corner
+@cindex ambiguity, syntactic: @code{/=} operator vs. @code{/=@dots{}/} regexp constant
+@cindex syntactic ambiguity: @code{/=} operator vs. @code{/=@dots{}/} regexp constant
+@cindex @code{/=} operator vs. @code{/=@dots{}/} regexp constant
+There is a syntactic ambiguity between the @samp{/=} assignment
+operator and regexp constants whose first character is an @samp{=}.
+@value{DARKCORNER}
+This is most notable in commercial @command{awk} versions.
+For example:
+
+@example
+$ 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
+A workaround is:
+
+@example
+awk '/[=]=/' /dev/null
+@end example
+
+@command{gawk} does not have this problem,
+nor do the other
+freely available versions described in
+@ref{Other Versions}.
+@c ENDOFRANGE exas
+@c ENDOFRANGE opas
+@c ENDOFRANGE asop
+
+@node Increment Ops
+@section Increment and Decrement Operators
+
+@c STARTOFRANGE inop
+@cindex increment operators
+@c STARTOFRANGE opde
+@cindex operators, decrement/increment
+@dfn{Increment} and @dfn{decrement operators} increase or decrease the value of
+a variable by one. An assignment operator can do the same thing, so
+the increment operators add no power to the @command{awk} language; however, they
+are convenient abbreviations for very common operations.
+
+@cindex side effects
+@cindex @code{+} (plus sign), decrement/increment operators
+@cindex plus sign (@code{+}), decrement/increment operators
+@cindex side effects, decrement/increment operators
+The operator used for adding one is written @samp{++}. It can be used to increment
+a variable either before or after taking its value.
+To pre-increment a variable @code{v}, write @samp{++v}. This adds
+one to the value of @code{v}---that new value is also the value of the
+expression. (The assignment expression @samp{v += 1} is completely
+equivalent.)
+Writing the @samp{++} after the variable specifies post-increment. This
+increments the variable value just the same; the difference is that the
+value of the increment expression itself is the variable's @emph{old}
+value. Thus, if @code{foo} has the value four, then the expression @samp{foo++}
+has the value four, but it changes the value of @code{foo} to five.
+In other words, the operator returns the old value of the variable,
+but with the side effect of incrementing it.
+
+The post-increment @samp{foo++} is nearly the same as writing @samp{(foo
++= 1) - 1}. It is not perfectly equivalent because all numbers in
+@command{awk} are floating-point---in floating-point, @samp{foo + 1 - 1} does
+not necessarily equal @code{foo}. But the difference is minute as
+long as you stick to numbers that are fairly small (less than 10e12).
+
+@cindex @code{$} (dollar sign), incrementing fields and arrays
+@cindex dollar sign (@code{$}), incrementing fields and arrays
+Fields and array elements are incremented
+just like variables. (Use @samp{$(i++)} when you want to do a field reference
+and a variable increment at the same time. The parentheses are necessary
+because of the precedence of the field reference operator @samp{$}.)
+
+@cindex decrement operators
+The decrement operator @samp{--} works just like @samp{++}, except that
+it subtracts one instead of adding it. As with @samp{++}, it can be used before
+the lvalue to pre-decrement or after it to post-decrement.
+Following is a summary of increment and decrement expressions:
+
+@table @code
+@cindex @code{+} (plus sign), @code{++} operator
+@cindex plus sign (@code{+}), @code{++} operator
+@item ++@var{lvalue}
+This expression increments @var{lvalue}, and the new value becomes the
+value of the expression.
+
+@item @var{lvalue}++
+This expression increments @var{lvalue}, but
+the value of the expression is the @emph{old} value of @var{lvalue}.
+
+@cindex @code{-} (hyphen), @code{--} operator
+@cindex hyphen (@code{-}), @code{--} operator
+@item --@var{lvalue}
+This expression is
+like @samp{++@var{lvalue}}, but instead of adding, it subtracts. It
+decrements @var{lvalue} and delivers the value that is the result.
+
+@item @var{lvalue}--
+This expression is
+like @samp{@var{lvalue}++}, but instead of adding, it subtracts. It
+decrements @var{lvalue}. The value of the expression is the @emph{old}
+value of @var{lvalue}.
+@end table
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Operator Evaluation Order
+@cindex advanced features, operators@comma{} precedence
+@cindex precedence
+@cindex operators, precedence
+@cindex portability, operators
+@cindex evaluation order
+@cindex Marx, Groucho
+@quotation
+@i{Doctor, doctor! It hurts when I do this!@*
+So don't do that!}@*
+Groucho Marx
+@end quotation
+
+@noindent
+What happens for something like the following?
+
+@example
+b = 6
+print b += b++
+@end example
+
+@noindent
+Or something even stranger?
+
+@example
+b = 6
+b += ++b + b++
+print b
+@end example
+
+@cindex side effects
+In other words, when do the various side effects prescribed by the
+postfix operators (@samp{b++}) take effect?
+When side effects happen is @dfn{implementation defined}.
+In other words, it is up to the particular version of @command{awk}.
+The result for the first example may be 12 or 13, and for the second, it
+may be 22 or 23.
+
+In short, doing things like this is not recommended and definitely
+not anything that you can rely upon for portability.
+You should avoid such things in your own programs.
+@c You'll sleep better at night and be able to look at yourself
+@c in the mirror in the morning.
+@c ENDOFRANGE inop
+@c ENDOFRANGE opde
+@c ENDOFRANGE deop
+
+@node Truth Values
+@section True and False in @command{awk}
+@cindex truth values
+@cindex logical false/true
+@cindex false, logical
+@cindex true, logical
+
+@cindex null strings
+Many programming languages have a special representation for the concepts
+of ``true'' and ``false.'' Such languages usually use the special
+constants @code{true} and @code{false}, or perhaps their uppercase
+equivalents.
+However, @command{awk} is different.
+It borrows a very simple concept of true and
+false from C. In @command{awk}, any nonzero numeric value @emph{or} any
+nonempty string value is true. Any other value (zero or the null
+string @code{""}) is false. The following program prints @samp{A strange
+truth value} three times:
+
+@example
+BEGIN @{
+ if (3.1415927)
+ print "A strange truth value"
+ if ("Four Score And Seven Years Ago")
+ print "A strange truth value"
+ if (j = 57)
+ print "A strange truth value"
+@}
+@end example
+
+@cindex dark corner
+There is a surprising consequence of the ``nonzero or non-null'' rule:
+the string constant @code{"0"} is actually true, because it is non-null.
+@value{DARKCORNER}
+
+@node Typing and Comparison
+@section Variable Typing and Comparison Expressions
+@quotation
+@i{The Guide is definitive. Reality is frequently inaccurate.}@*
+The Hitchhiker's Guide to the Galaxy
+@end quotation
+
+@c STARTOFRANGE comex
+@cindex comparison expressions
+@c STARTOFRANGE excom
+@cindex expressions, comparison
+@cindex expressions, matching, See comparison expressions
+@cindex matching, expressions, See comparison expressions
+@cindex relational operators, See comparison operators
+@cindex operators, relational, See operators@comma{} comparison
+@c STARTOFRANGE varting
+@cindex variable typing
+@c STARTOFRANGE vartypc
+@cindex variables, types of, comparison expressions and
+Unlike other programming languages, @command{awk} variables do not have a
+fixed type. Instead, they can be either a number or a string, depending
+upon the value that is assigned to them.
+
+@cindex numeric, strings
+@cindex strings, numeric
+@cindex POSIX @command{awk}, numeric strings and
+The 1992 POSIX standard introduced
+the concept of a @dfn{numeric string}, which is simply a string that looks
+like a number---for example, @code{@w{" +2"}}. This concept is used
+for determining the type of a variable.
+The type of the variable is important because the types of two variables
+determine how they are compared.
+In @command{gawk}, variable typing follows these rules:
+
+@itemize @bullet
+@item
+A numeric constant or the result of a numeric operation has the @var{numeric}
+attribute.
+
+@item
+A string constant or the result of a string operation has the @var{string}
+attribute.
+
+@item
+Fields, @code{getline} input, @code{FILENAME}, @code{ARGV} elements,
+@code{ENVIRON} elements, and the
+elements of an array created by @code{split} that are numeric strings
+have the @var{strnum} attribute. Otherwise, they have the @var{string}
+attribute.
+Uninitialized variables also have the @var{strnum} attribute.
+
+@item
+Attributes propagate across assignments but are not changed by
+any use.
+@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
+
+The last rule is particularly important. In the following program,
+@code{a} has numeric type, even though it is later used in a string
+operation:
+
+@example
+BEGIN @{
+ a = 12.345
+ b = a " is a cute number"
+ print b
+@}
+@end example
+
+When two operands are compared, either string comparison or numeric comparison
+may be used. This depends upon the attributes of the operands, according to the
+following symmetric matrix:
+
+@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
+@display
+ +----------------------------------------------
+ | STRING NUMERIC STRNUM
+--------+----------------------------------------------
+ |
+STRING | string string string
+ |
+NUMERIC | string numeric numeric
+ |
+STRNUM | string numeric numeric
+--------+----------------------------------------------
+@end display
+@end ifnottex
+
+The basic idea is that user input that looks numeric---and @emph{only}
+user input---should be treated as numeric, even though it is actually
+made of characters and is therefore also a string.
+Thus, for example, the string constant @w{@code{" +3.14"}}
+is a string, even though it looks numeric,
+and is @emph{never} treated as number for comparison
+purposes.
+
+In short, when one operand is a ``pure'' string, such as a string
+constant, then a string comparison is performed. Otherwise, a
+numeric comparison is performed.@footnote{The POSIX standard is under
+revision. The revised standard's rules for typing and comparison are
+the same as just described for @command{gawk}.}
+
+@dfn{Comparison expressions} compare strings or numbers for
+relationships such as equality. They are written using @dfn{relational
+operators}, which are a superset of those in C.
+@ref{table-relational-ops} describes them.
+
+@cindex @code{<} (left angle bracket), @code{<} operator
+@cindex left angle bracket (@code{<}), @code{<} operator
+@cindex @code{<} (left angle bracket), @code{<=} operator
+@cindex left angle bracket (@code{<}), @code{<=} operator
+@cindex @code{>} (right angle bracket), @code{>=} operator
+@cindex right angle bracket (@code{>}), @code{>=} operator
+@cindex @code{>} (right angle bracket), @code{>} operator
+@cindex right angle bracket (@code{>}), @code{>} operator
+@cindex @code{=} (equals sign), @code{==} operator
+@cindex equals sign (@code{=}), @code{==} operator
+@cindex @code{!} (exclamation point), @code{!=} operator
+@cindex exclamation point (@code{!}), @code{!=} operator
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@cindex @code{in} operator
+@float Table,table-relational-ops
+@caption{Relational Operators}
+@multitable @columnfractions .25 .75
+@headitem Expression @tab Result
+@item @var{x} @code{<} @var{y} @tab True if @var{x} is less than @var{y}.
+@item @var{x} @code{<=} @var{y} @tab True if @var{x} is less than or equal to @var{y}.
+@item @var{x} @code{>} @var{y} @tab True if @var{x} is greater than @var{y}.
+@item @var{x} @code{>=} @var{y} @tab True if @var{x} is greater than or equal to @var{y}.
+@item @var{x} @code{==} @var{y} @tab True if @var{x} is equal to @var{y}.
+@item @var{x} @code{!=} @var{y} @tab True if @var{x} is not equal to @var{y}.
+@item @var{x} @code{~} @var{y} @tab True if the string @var{x} matches the regexp denoted by @var{y}.
+@item @var{x} @code{!~} @var{y} @tab True if the string @var{x} does not match the regexp denoted by @var{y}.
+@item @var{subscript} @code{in} @var{array} @tab True if the array @var{array} has an element with the subscript @var{subscript}.
+@end multitable
+@end float
+
+Comparison expressions have the value one if true and zero if false.
+When comparing operands of mixed types, numeric operands are converted
+to strings using the value of @code{CONVFMT}
+(@pxref{Conversion}).
+
+Strings are compared
+by comparing the first character of each, then the second character of each,
+and so on. Thus, @code{"10"} is less than @code{"9"}. If there are two
+strings where one is a prefix of the other, the shorter string is less than
+the longer one. Thus, @code{"abc"} is less than @code{"abcd"}.
+
+@cindex troubleshooting, @code{==} operator
+It is very easy to accidentally mistype the @samp{==} operator and
+leave off one of the @samp{=} characters. The result is still valid @command{awk}
+code, but the program does not do what is intended:
+
+@example
+if (a = b) # oops! should be a == b
+ @dots{}
+else
+ @dots{}
+@end example
+
+@noindent
+Unless @code{b} happens to be zero or the null string, the @code{if}
+part of the test always succeeds. Because the operators are
+so similar, this kind of error is very difficult to spot when
+scanning the source code.
+
+@cindex @command{gawk}, comparison operators and
+The following table of expressions illustrates the kind of comparison
+@command{gawk} performs, as well as what the result of the comparison is:
+
+@table @code
+@item 1.5 <= 2.0
+numeric comparison (true)
+
+@item "abc" >= "xyz"
+string comparison (false)
+
+@item 1.5 != " +2"
+string comparison (true)
+
+@item "1e2" < "3"
+string comparison (true)
+
+@item a = 2; b = "2"
+@itemx a == b
+string comparison (true)
+
+@item a = 2; b = " +2"
+@item a == b
+string comparison (false)
+@end table
+
+In the next example:
+
+@example
+$ echo 1e2 3 | awk '@{ print ($1 < $2) ? "true" : "false" @}'
+@print{} false
+@end example
+
+@cindex comparison expressions, string vs. regexp
+@c @cindex string comparison vs. regexp comparison
+@c @cindex regexp comparison vs. string comparison
+@noindent
+the result is @samp{false} because both @code{$1} and @code{$2}
+are user input. They are numeric strings---therefore both have
+the @var{strnum} attribute, dictating a numeric comparison.
+The purpose of the comparison rules and the use of numeric strings is
+to attempt to produce the behavior that is ``least surprising,'' while
+still ``doing the right thing.''
+String comparisons and regular expression comparisons are very different.
+For example:
+
+@example
+x == "foo"
+@end example
+
+@noindent
+has the value one, or is true if the variable @code{x}
+is precisely @samp{foo}. By contrast:
+
+@example
+x ~ /foo/
+@end example
+
+@noindent
+has the value one if @code{x} contains @samp{foo}, such as
+@code{"Oh, what a fool am I!"}.
+
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+The righthand operand of the @samp{~} and @samp{!~} operators may be
+either a regexp constant (@code{/@dots{}/}) or an ordinary
+expression. In the latter case, the value of the expression as a string is used as a
+dynamic regexp (@pxref{Regexp Usage}; also
+@pxref{Computed Regexps}).
+
+@cindex @command{awk}, regexp constants and
+@cindex regexp constants
+In modern implementations of @command{awk}, a constant regular
+expression in slashes by itself is also an expression. The regexp
+@code{/@var{regexp}/} is an abbreviation for the following comparison expression:
+
+@example
+$0 ~ /@var{regexp}/
+@end example
+
+One special place where @code{/foo/} is @emph{not} an abbreviation for
+@samp{$0 ~ /foo/} is when it is the righthand operand of @samp{~} or
+@samp{!~}.
+@xref{Using Constant Regexps},
+where this is discussed in more detail.
+@c ENDOFRANGE comex
+@c ENDOFRANGE excom
+@c ENDOFRANGE vartypc
+@c ENDOFRANGE varting
+
+@node Boolean Ops
+@section Boolean Expressions
+@cindex and Boolean-logic operator
+@cindex or Boolean-logic operator
+@cindex not Boolean-logic operator
+@c STARTOFRANGE exbo
+@cindex expressions, Boolean
+@c STARTOFRANGE boex
+@cindex Boolean expressions
+@cindex operators, Boolean, See Boolean expressions
+@cindex Boolean operators, See Boolean expressions
+@cindex logical operators, See Boolean expressions
+@cindex operators, logical, See Boolean expressions
+
+A @dfn{Boolean expression} is a combination of comparison expressions or
+matching expressions, using the Boolean operators ``or''
+(@samp{||}), ``and'' (@samp{&&}), and ``not'' (@samp{!}), along with
+parentheses to control nesting. The truth value of the Boolean expression is
+computed by combining the truth values of the component expressions.
+Boolean expressions are also referred to as @dfn{logical expressions}.
+The terms are equivalent.
+
+Boolean expressions can be used wherever comparison and matching
+expressions can be used. They can be used in @code{if}, @code{while},
+@code{do}, and @code{for} statements
+(@pxref{Statements}).
+They have numeric values (one if true, zero if false) that come into play
+if the result of the Boolean expression is stored in a variable or
+used in arithmetic.
+
+In addition, every Boolean expression is also a valid pattern, so
+you can use one as a pattern to control the execution of rules.
+The Boolean operators are:
+
+@table @code
+@item @var{boolean1} && @var{boolean2}
+True if both @var{boolean1} and @var{boolean2} are true. For example,
+the following statement prints the current input record if it contains
+both @samp{2400} and @samp{foo}:
+
+@example
+if ($0 ~ /2400/ && $0 ~ /foo/) print
+@end example
+
+@cindex side effects, Boolean operators
+The subexpression @var{boolean2} is evaluated only if @var{boolean1}
+is true. This can make a difference when @var{boolean2} contains
+expressions that have side effects. In the case of @samp{$0 ~ /foo/ &&
+($2 == bar++)}, the variable @code{bar} is not incremented if there is
+no substring @samp{foo} in the record.
+
+@item @var{boolean1} || @var{boolean2}
+True if at least one of @var{boolean1} or @var{boolean2} is true.
+For example, the following statement prints all records in the input
+that contain @emph{either} @samp{2400} or
+@samp{foo} or both:
+
+@example
+if ($0 ~ /2400/ || $0 ~ /foo/) print
+@end example
+
+The subexpression @var{boolean2} is evaluated only if @var{boolean1}
+is false. This can make a difference when @var{boolean2} contains
+expressions that have side effects.
+
+@item ! @var{boolean}
+True if @var{boolean} is false. For example,
+the following program prints @samp{no home!} in
+the unusual event that the @env{HOME} environment
+variable is not defined:
+
+@example
+BEGIN @{ if (! ("HOME" in ENVIRON))
+ print "no home!" @}
+@end example
+
+(The @code{in} operator is described in
+@ref{Reference to Elements}.)
+@end table
+
+@cindex short-circuit operators
+@cindex operators, short-circuit
+@cindex @code{&} (ampersand), @code{&&} operator
+@cindex ampersand (@code{&}), @code{&&} operator
+@cindex @code{|} (vertical bar), @code{||} operator
+@cindex vertical bar (@code{|}), @code{||} operator
+The @samp{&&} and @samp{||} operators are called @dfn{short-circuit}
+operators because of the way they work. Evaluation of the full expression
+is ``short-circuited'' if the result can be determined part way through
+its evaluation.
+
+@cindex line continuations
+Statements that use @samp{&&} or @samp{||} can be continued simply
+by putting a newline after them. But you cannot put a newline in front
+of either of these operators without using backslash continuation
+(@pxref{Statements/Lines}).
+
+@cindex @code{!} (exclamation point), @code{!} operator
+@cindex exclamation point (@code{!}), @code{!} operator
+@cindex newlines
+@cindex variables, flag
+@cindex flag variables
+The actual value of an expression using the @samp{!} operator is
+either one or zero, depending upon the truth value of the expression it
+is applied to.
+The @samp{!} operator is often useful for changing the sense of a flag
+variable from false to true and back again. For example, the following
+program is one way to print lines in between special bracketing lines:
+
+@example
+$1 == "START" @{ interested = ! interested; next @}
+interested == 1 @{ print @}
+$1 == "END" @{ interested = ! interested; next @}
+@end example
+
+@noindent
+The variable @code{interested}, as with all @command{awk} variables, starts
+out initialized to zero, which is also false. When a line is seen whose
+first field is @samp{START}, the value of @code{interested} is toggled
+to true, using @samp{!}. The next rule prints lines as long as
+@code{interested} is true. When a line is seen whose first field is
+@samp{END}, @code{interested} is toggled back to false.
+
+@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
+
+@cindex @code{next} statement
+@quotation NOTE
+The @code{next} statement is discussed in
+@ref{Next Statement}.
+@code{next} tells @command{awk} to skip the rest of the rules, get the
+next record, and start processing the rules over again at the top.
+The reason it's there is to avoid printing the bracketing
+@samp{START} and @samp{END} lines.
+@end quotation
+@c ENDOFRANGE exbo
+@c ENDOFRANGE boex
+
+@node Conditional Exp
+@section Conditional Expressions
+@cindex conditional expressions
+@cindex expressions, conditional
+@cindex expressions, selecting
+
+A @dfn{conditional expression} is a special kind of expression that has
+three operands. It allows you to use one expression's value to select
+one of two other expressions.
+The conditional expression is the same as in the C language,
+as shown here:
+
+@example
+@var{selector} ? @var{if-true-exp} : @var{if-false-exp}
+@end example
+
+@noindent
+There are three subexpressions. The first, @var{selector}, is always
+computed first. If it is ``true'' (not zero or not null), then
+@var{if-true-exp} is computed next and its value becomes the value of
+the whole expression. Otherwise, @var{if-false-exp} is computed next
+and its value becomes the value of the whole expression.
+For example, the following expression produces the absolute value of @code{x}:
+
+@example
+x >= 0 ? x : -x
+@end example
+
+@cindex side effects, conditional expressions
+Each time the conditional expression is computed, only one of
+@var{if-true-exp} and @var{if-false-exp} is used; the other is ignored.
+This is important when the expressions have side effects. For example,
+this conditional expression examines element @code{i} of either array
+@code{a} or array @code{b}, and increments @code{i}:
+
+@example
+x == y ? a[i++] : b[i++]
+@end example
+
+@noindent
+This is guaranteed to increment @code{i} exactly once, because each time
+only one of the two increment expressions is executed
+and the other is not.
+@xref{Arrays},
+for more information about arrays.
+
+@cindex differences in @command{awk} and @command{gawk}, line continuations
+@cindex line continuations, @command{gawk}
+@cindex @command{gawk}, line continuation in
+As a minor @command{gawk} extension,
+a statement that uses @samp{?:} can be continued simply
+by putting a newline after either character.
+However, putting a newline in front
+of either character does not work without using backslash continuation
+(@pxref{Statements/Lines}).
+If @option{--posix} is specified
+(@pxref{Options}), then this extension is disabled.
+
+@node Function Calls
+@section Function Calls
+@cindex function calls
+
+A @dfn{function} is a name for a particular calculation.
+This enables you to
+ask for it by name at any point in the program. For
+example, the function @code{sqrt} computes the square root of a number.
+
+@cindex functions, built-in
+A fixed set of functions are @dfn{built-in}, which means they are
+available in every @command{awk} program. The @code{sqrt} function is one
+of these. @xref{Built-in}, for a list of built-in
+functions and their descriptions. In addition, you can define
+functions for use in your program.
+@xref{User-defined},
+for instructions on how to do this.
+
+@cindex arguments, in function calls
+The way to use a function is with a @dfn{function call} expression,
+which consists of the function name followed immediately by a list of
+@dfn{arguments} in parentheses. The arguments are expressions that
+provide the raw materials for the function's calculations.
+When there is more than one argument, they are separated by commas. If
+there are no arguments, just write @samp{()} after the function name.
+The following examples show function calls with and without arguments:
+
+@example
+sqrt(x^2 + y^2) @i{one argument}
+atan2(y, x) @i{two arguments}
+rand() @i{no arguments}
+@end example
+
+@cindex troubleshooting, function call syntax
+@strong{Caution:}
+Do not put any space between the function name and the open-parenthesis!
+A user-defined function name looks just like the name of a
+variable---a space would make the expression look like concatenation of
+a variable with an expression inside parentheses.
+
+With built-in functions, space before the parenthesis is harmless, but
+it is best not to get into the habit of using space to avoid mistakes
+with user-defined functions. Each function expects a particular number
+of arguments. For example, the @code{sqrt} function must be called with
+a single argument, the number of which to take the square root:
+
+@example
+sqrt(@var{argument})
+@end example
+
+Some of the built-in functions have one or
+more optional arguments.
+If those arguments are not supplied, the functions
+use a reasonable default value.
+@xref{Built-in}, for full details. If arguments
+are omitted in calls to user-defined functions, then those arguments are
+treated as local variables and initialized to the empty string
+(@pxref{User-defined}).
+
+@cindex side effects, function calls
+Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it. In this
+example, the value of @samp{sqrt(@var{argument})} is the square root of
+@var{argument}. A function can also have side effects, such as assigning
+values to certain variables or doing I/O.
+The following program reads numbers, one number per line, and prints the
+square root of each one:
+
+@example
+$ awk '@{ print "The square root of", $1, "is", sqrt($1) @}'
+1
+@print{} The square root of 1 is 1
+3
+@print{} The square root of 3 is 1.73205
+5
+@print{} The square root of 5 is 2.23607
+@kbd{@value{CTL}-d}
+@end example
+
+@node Precedence
+@section Operator Precedence (How Operators Nest)
+@c STARTOFRANGE prec
+@cindex precedence
+@c STARTOFRANGE oppr
+@cindex operators, precedence
+
+@dfn{Operator precedence} determines how operators are grouped when
+different operators appear close by in one expression. For example,
+@samp{*} has higher precedence than @samp{+}; thus, @samp{a + b * c}
+means to multiply @code{b} and @code{c}, and then add @code{a} to the
+product (i.e., @samp{a + (b * c)}).
+
+The normal precedence of the operators can be overruled by using parentheses.
+Think of the precedence rules as saying where the
+parentheses are assumed to be. In
+fact, it is wise to always use parentheses whenever there is an unusual
+combination of operators, because other people who read the program may
+not remember what the precedence is in this case.
+Even experienced programmers occasionally forget the exact rules,
+which leads to mistakes.
+Explicit parentheses help prevent
+any such mistakes.
+
+When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment, conditional, and
+exponentiation operators, which group in the opposite order.
+Thus, @samp{a - b + c} groups as @samp{(a - b) + c} and
+@samp{a = b = c} groups as @samp{a = (b = c)}.
+
+The precedence of prefix unary operators does not matter as long as only
+unary operators are involved, because there is only one way to interpret
+them: innermost first. Thus, @samp{$++i} means @samp{$(++i)} and
+@samp{++$x} means @samp{++($x)}. However, when another operator follows
+the operand, then the precedence of the unary operators can matter.
+@samp{$x^2} means @samp{($x)^2}, but @samp{-x^2} means
+@samp{-(x^2)}, because @samp{-} has lower precedence than @samp{^},
+whereas @samp{$} has higher precedence.
+This table presents @command{awk}'s operators, in order of highest
+to lowest precedence:
+
+@c use @code in the items, looks better in TeX w/o all the quotes
+@table @code
+@item (@dots{})
+Grouping.
+
+@cindex @code{$} (dollar sign), @code{$} field operator
+@cindex dollar sign (@code{$}), @code{$} field operator
+@item $
+Field.
+
+@cindex @code{+} (plus sign), @code{++} operator
+@cindex plus sign (@code{+}), @code{++} operator
+@cindex @code{-} (hyphen), @code{--} (decrement/increment) operator
+@cindex hyphen (@code{-}), @code{--} (decrement/increment) operators
+@item ++ --
+Increment, decrement.
+
+@cindex @code{^} (caret), @code{^} operator
+@cindex caret (@code{^}), @code{^} operator
+@cindex @code{*} (asterisk), @code{**} operator
+@cindex asterisk (@code{*}), @code{**} operator
+@item ^ **
+Exponentiation. These operators group right-to-left.
+
+@cindex @code{+} (plus sign), @code{+} operator
+@cindex plus sign (@code{+}), @code{+} operator
+@cindex @code{-} (hyphen), @code{-} operator
+@cindex hyphen (@code{-}), @code{-} operator
+@cindex @code{!} (exclamation point), @code{!} operator
+@cindex exclamation point (@code{!}), @code{!} operator
+@item + - !
+Unary plus, minus, logical ``not.''
+
+@cindex @code{*} (asterisk), @code{*} operator, as multiplication operator
+@cindex asterisk (@code{*}), @code{*} operator, as multiplication operator
+@cindex @code{/} (forward slash), @code{/} operator
+@cindex forward slash (@code{/}), @code{/} operator
+@cindex @code{%} (percent sign), @code{%} operator
+@cindex percent sign (@code{%}), @code{%} operator
+@item * / %
+Multiplication, division, modulus.
+
+@cindex @code{+} (plus sign), @code{+} operator
+@cindex plus sign (@code{+}), @code{+} operator
+@cindex @code{-} (hyphen), @code{-} operator
+@cindex hyphen (@code{-}), @code{-} operator
+@item + -
+Addition, subtraction.
+
+@item @r{String Concatenation}
+No special symbol is used to indicate concatenation.
+The operands are simply written side by side
+(@pxref{Concatenation}).
+
+@cindex @code{<} (left angle bracket), @code{<} operator
+@cindex left angle bracket (@code{<}), @code{<} operator
+@cindex @code{<} (left angle bracket), @code{<=} operator
+@cindex left angle bracket (@code{<}), @code{<=} operator
+@cindex @code{>} (right angle bracket), @code{>=} operator
+@cindex right angle bracket (@code{>}), @code{>=} operator
+@cindex @code{>} (right angle bracket), @code{>} operator
+@cindex right angle bracket (@code{>}), @code{>} operator
+@cindex @code{=} (equals sign), @code{==} operator
+@cindex equals sign (@code{=}), @code{==} operator
+@cindex @code{!} (exclamation point), @code{!=} operator
+@cindex exclamation point (@code{!}), @code{!=} operator
+@cindex @code{>} (right angle bracket), @code{>>} operator (I/O)
+@cindex right angle bracket (@code{>}), @code{>>} operator (I/O)
+@cindex operators, input/output
+@cindex @code{|} (vertical bar), @code{|} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|} operator (I/O)
+@cindex operators, input/output
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
+@cindex operators, input/output
+@item < <= == !=
+@itemx > >= >> | |&
+Relational and redirection.
+The relational operators and the redirections have the same precedence
+level. Characters such as @samp{>} serve both as relationals and as
+redirections; the context distinguishes between the two meanings.
+
+@cindex @code{print} statement, I/O operators in
+@cindex @code{printf} statement, I/O operators in
+Note that the I/O redirection operators in @code{print} and @code{printf}
+statements belong to the statement level, not to expressions. The
+redirection does not produce an expression that could be the operand of
+another operator. As a result, it does not make sense to use a
+redirection operator near another operator of lower precedence without
+parentheses. Such combinations (for example, @samp{print foo > a ? b : c}),
+result in syntax errors.
+The correct way to write this statement is @samp{print foo > (a ? b : c)}.
+
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@item ~ !~
+Matching, nonmatching.
+
+@cindex @code{in} operator
+@item in
+Array membership.
+
+@cindex @code{&} (ampersand), @code{&&} operator
+@cindex ampersand (@code{&}), @code{&&}operator
+@item &&
+Logical ``and''.
+
+@cindex @code{|} (vertical bar), @code{||} operator
+@cindex vertical bar (@code{|}), @code{||} operator
+@item ||
+Logical ``or''.
+
+@cindex @code{?} (question mark), @code{?:} operator
+@cindex question mark (@code{?}), @code{?:} operator
+@item ?:
+Conditional. This operator groups right-to-left.
+
+@cindex @code{+} (plus sign), @code{+=} operator
+@cindex plus sign (@code{+}), @code{+=} operator
+@cindex @code{-} (hyphen), @code{-=} operator
+@cindex hyphen (@code{-}), @code{-=} operator
+@cindex @code{*} (asterisk), @code{*=} operator
+@cindex asterisk (@code{*}), @code{*=} operator
+@cindex @code{*} (asterisk), @code{**=} operator
+@cindex asterisk (@code{*}), @code{**=} operator
+@cindex @code{/} (forward slash), @code{/=} operator
+@cindex forward slash (@code{/}), @code{/=} operator
+@cindex @code{%} (percent sign), @code{%=} operator
+@cindex percent sign (@code{%}), @code{%=} operator
+@cindex @code{^} (caret), @code{^=} operator
+@cindex caret (@code{^}), @code{^=} operator
+@item = += -= *=
+@itemx /= %= ^= **=
+Assignment. These operators group right to left.
+@end table
+
+@cindex portability, operators, not in POSIX @command{awk}
+@quotation NOTE
+The @samp{|&}, @samp{**}, and @samp{**=} operators are not specified by POSIX.
+For maximum portability, do not use them.
+@end quotation
+@c ENDOFRANGE prec
+@c ENDOFRANGE oppr
+@c ENDOFRANGE exps
+
+@node Patterns and Actions
+@chapter Patterns, Actions, and Variables
+@c STARTOFRANGE pat
+@cindex patterns
+
+As you have already seen, each @command{awk} statement consists of
+a pattern with an associated action. This @value{CHAPTER} describes how
+you build patterns and actions, what kinds of things you can do within
+actions, and @command{awk}'s built-in variables.
+
+The pattern-action rules and the statements available for use
+within actions form the core of @command{awk} programming.
+In a sense, everything covered
+up to here has been the foundation
+that programs are built on top of. Now it's time to start
+building something useful.
+
+@menu
+* Pattern Overview:: What goes into a pattern.
+* Using Shell Variables:: How to use shell variables with @command{awk}.
+* Action Overview:: What goes into an action.
+* Statements:: Describes the various control statements in
+ detail.
+* Built-in Variables:: Summarizes the built-in variables.
+@end menu
+
+@node Pattern Overview
+@section Pattern Elements
+
+@menu
+* Regexp Patterns:: Using regexps as patterns.
+* Expression Patterns:: Any expression can be used as a pattern.
+* Ranges:: Pairs of patterns specify record ranges.
+* BEGIN/END:: Specifying initialization and cleanup rules.
+* Empty:: The empty pattern, which matches every record.
+@end menu
+
+@cindex patterns, types of
+Patterns in @command{awk} control the execution of rules---a rule is
+executed when its pattern matches the current input record.
+The following is a summary of the types of @command{awk} patterns:
+
+@table @code
+@item /@var{regular expression}/
+A regular expression. It matches when the text of the
+input record fits the regular expression.
+(@xref{Regexp}.)
+
+@item @var{expression}
+A single expression. It matches when its value
+is nonzero (if a number) or non-null (if a string).
+(@xref{Expression Patterns}.)
+
+@item @var{pat1}, @var{pat2}
+A pair of patterns separated by a comma, specifying a range of records.
+The range includes both the initial record that matches @var{pat1} and
+the final record that matches @var{pat2}.
+(@xref{Ranges}.)
+
+@item BEGIN
+@itemx END
+Special patterns for you to supply startup or cleanup actions for your
+@command{awk} program.
+(@xref{BEGIN/END}.)
+
+@item @var{empty}
+The empty pattern matches every input record.
+(@xref{Empty}.)
+@end table
+
+@node Regexp Patterns
+@subsection Regular Expressions as Patterns
+@cindex patterns, expressions as
+@cindex regular expressions, as patterns
+
+Regular expressions are one of the first kinds of patterns presented
+in this book.
+This kind of pattern is simply a regexp constant in the pattern part of
+a rule. Its meaning is @samp{$0 ~ /@var{pattern}/}.
+The pattern matches when the input record matches the regexp.
+For example:
+
+@example
+/foo|bar|baz/ @{ buzzwords++ @}
+END @{ print buzzwords, "buzzwords seen" @}
+@end example
+
+@node Expression Patterns
+@subsection Expressions as Patterns
+@cindex expressions, as patterns
+
+Any @command{awk} expression is valid as an @command{awk} pattern.
+The pattern matches if the expression's value is nonzero (if a
+number) or non-null (if a string).
+The expression is reevaluated each time the rule is tested against a new
+input record. If the expression uses fields such as @code{$1}, the
+value depends directly on the new input record's text; otherwise, it
+depends on only what has happened so far in the execution of the
+@command{awk} program.
+
+@cindex comparison expressions, as patterns
+@cindex patterns, comparison expressions as
+Comparison expressions, using the comparison operators described in
+@ref{Typing and Comparison},
+are a very common kind of pattern.
+Regexp matching and nonmatching are also very common expressions.
+The left operand of the @samp{~} and @samp{!~} operators is a string.
+The right operand is either a constant regular expression enclosed in
+slashes (@code{/@var{regexp}/}), or any expression whose string value
+is used as a dynamic regular expression
+(@pxref{Computed Regexps}).
+The following example prints the second field of each input record
+whose first field is precisely @samp{foo}:
+
+@cindex @code{/} (forward slash), patterns and
+@cindex forward slash (@code{/}), patterns and
+@cindex @code{~} (tilde), @code{~} operator
+@cindex tilde (@code{~}), @code{~} operator
+@cindex @code{!} (exclamation point), @code{!~} operator
+@cindex exclamation point (@code{!}), @code{!~} operator
+@example
+$ awk '$1 == "foo" @{ print $2 @}' BBS-list
+@end example
+
+@noindent
+(There is no output, because there is no BBS site with the exact name @samp{foo}.)
+Contrast this with the following regular expression match, which
+accepts any record with a first field that contains @samp{foo}:
+
+@example
+$ awk '$1 ~ /foo/ @{ print $2 @}' BBS-list
+@print{} 555-1234
+@print{} 555-6699
+@print{} 555-6480
+@print{} 555-2127
+@end example
+
+@cindex regexp constants, as patterns
+@cindex patterns, regexp constants as
+A regexp constant as a pattern is also a special case of an expression
+pattern. The expression @code{/foo/} has the value one if @samp{foo}
+appears in the current input record. Thus, as a pattern, @code{/foo/}
+matches any record containing @samp{foo}.
+
+@cindex Boolean expressions, as patterns
+Boolean expressions are also commonly used as patterns.
+Whether the pattern
+matches an input record depends on whether its subexpressions match.
+For example, the following command prints all the records in
+@file{BBS-list} that contain both @samp{2400} and @samp{foo}:
+
+@example
+$ awk '/2400/ && /foo/' BBS-list
+@print{} fooey 555-1234 2400/1200/300 B
+@end example
+
+The following command prints all records in
+@file{BBS-list} that contain @emph{either} @samp{2400} or @samp{foo}
+(or both, of course):
+
+@example
+$ awk '/2400/ || /foo/' BBS-list
+@print{} alpo-net 555-3412 2400/1200/300 A
+@print{} bites 555-1675 2400/1200/300 A
+@print{} fooey 555-1234 2400/1200/300 B
+@print{} foot 555-6699 1200/300 B
+@print{} macfoo 555-6480 1200/300 A
+@print{} sdace 555-3430 2400/1200/300 A
+@print{} sabafoo 555-2127 1200/300 C
+@end example
+
+The following command prints all records in
+@file{BBS-list} that do @emph{not} contain the string @samp{foo}:
+
+@example
+$ awk '! /foo/' BBS-list
+@print{} aardvark 555-5553 1200/300 B
+@print{} alpo-net 555-3412 2400/1200/300 A
+@print{} barfly 555-7685 1200/300 A
+@print{} bites 555-1675 2400/1200/300 A
+@print{} camelot 555-0542 300 C
+@print{} core 555-2912 1200/300 C
+@print{} sdace 555-3430 2400/1200/300 A
+@end example
+
+@cindex @code{BEGIN} pattern, Boolean patterns and
+@cindex @code{END} pattern, Boolean patterns and
+The subexpressions of a Boolean operator in a pattern can be constant regular
+expressions, comparisons, or any other @command{awk} expressions. Range
+patterns are not expressions, so they cannot appear inside Boolean
+patterns. Likewise, the special patterns @code{BEGIN} and @code{END},
+which never match any input record, are not expressions and cannot
+appear inside Boolean patterns.
+
+@node Ranges
+@subsection Specifying Record Ranges with Patterns
+
+@cindex range patterns
+@cindex patterns, ranges in
+@cindex lines, matching ranges of
+@cindex @code{,} (comma), in range patterns
+@cindex comma (@code{,}), in range patterns
+A @dfn{range pattern} is made of two patterns separated by a comma, in
+the form @samp{@var{begpat}, @var{endpat}}. It is used to match ranges of
+consecutive input records. The first pattern, @var{begpat}, controls
+where the range begins, while @var{endpat} controls where
+the pattern ends. For example, the following:
+
+@example
+awk '$1 == "on", $1 == "off"' myfile
+@end example
+
+@noindent
+prints every record in @file{myfile} between @samp{on}/@samp{off} pairs, inclusive.
+
+A range pattern starts out by matching @var{begpat} against every
+input record. When a record matches @var{begpat}, the range pattern is
+@dfn{turned on} and the range pattern matches this record as well. As long as
+the range pattern stays turned on, it automatically matches every input
+record read. The range pattern also matches @var{endpat} against every
+input record; when this succeeds, the range pattern is turned off again
+for the following record. Then the range pattern goes back to checking
+@var{begpat} against each record.
+
+@cindex @code{if} statement, actions@comma{} changing
+The record that turns on the range pattern and the one that turns it
+off both match the range pattern. If you don't want to operate on
+these records, you can write @code{if} statements in the rule's action
+to distinguish them from the records you are interested in.
+
+It is possible for a pattern to be turned on and off by the same
+record. If the record satisfies both conditions, then the action is
+executed for just that record.
+For example, suppose there is text between two identical markers (e.g.,
+the @samp{%} symbol), each on its own line, that should be ignored.
+A first attempt would be to
+combine a range pattern that describes the delimited text with the
+@code{next} statement
+(not discussed yet, @pxref{Next Statement}).
+This causes @command{awk} to skip any further processing of the current
+record and start over again with the next input record. Such a program
+looks like this:
+
+@example
+/^%$/,/^%$/ @{ next @}
+ @{ print @}
+@end example
+
+@noindent
+@cindex lines, skipping between markers
+@c @cindex flag variables
+This program fails because the range pattern is both turned on and turned off
+by the first line, which just has a @samp{%} on it. To accomplish this task,
+write the program in the following manner, using a flag:
+
+@cindex @code{!} operator
+@example
+/^%$/ @{ skip = ! skip; next @}
+skip == 1 @{ next @} # skip lines with `skip' set
+@end example
+
+In a range pattern, the comma (@samp{,}) has the lowest precedence of
+all the operators (i.e., it is evaluated last). Thus, the following
+program attempts to combine a range pattern with another, simpler test:
+
+@example
+echo Yes | awk '/1/,/2/ || /Yes/'
+@end example
+
+The intent of this program is @samp{(/1/,/2/) || /Yes/}.
+However, @command{awk} interprets this as @samp{/1/, (/2/ || /Yes/)}.
+This cannot be changed or worked around; range patterns do not combine
+with other patterns:
+
+@example
+$ echo Yes | gawk '(/1/,/2/) || /Yes/'
+@error{} gawk: cmd. line:1: (/1/,/2/) || /Yes/
+@error{} gawk: cmd. line:1: ^ parse error
+@error{} gawk: cmd. line:2: (/1/,/2/) || /Yes/
+@error{} gawk: cmd. line:2: ^ unexpected newline
+@end example
+
+@node BEGIN/END
+@subsection The @code{BEGIN} and @code{END} Special Patterns
+
+@c STARTOFRANGE beg
+@cindex @code{BEGIN} pattern
+@c STARTOFRANGE end
+@cindex @code{END} pattern
+All the patterns described so far are for matching input records.
+The @code{BEGIN} and @code{END} special patterns are different.
+They supply startup and cleanup actions for @command{awk} programs.
+@code{BEGIN} and @code{END} rules must have actions; there is no default
+action for these rules because there is no current record when they run.
+@code{BEGIN} and @code{END} rules are often referred to as
+``@code{BEGIN} and @code{END} blocks'' by long-time @command{awk}
+programmers.
+
+@menu
+* Using BEGIN/END:: How and why to use BEGIN/END rules.
+* I/O And BEGIN/END:: I/O issues in BEGIN/END rules.
+@end menu
+
+@node Using BEGIN/END
+@subsubsection Startup and Cleanup Actions
+
+A @code{BEGIN} rule is executed once only, before the first input record
+is read. Likewise, an @code{END} rule is executed once only, after all the
+input is read. For example:
+
+@example
+$ awk '
+> BEGIN @{ print "Analysis of \"foo\"" @}
+> /foo/ @{ ++n @}
+> END @{ print "\"foo\" appears", n, "times." @}' BBS-list
+@print{} Analysis of "foo"
+@print{} "foo" appears 4 times.
+@end example
+
+@cindex @code{BEGIN} pattern, operators and
+@cindex @code{END} pattern, operators and
+This program finds the number of records in the input file @file{BBS-list}
+that contain the string @samp{foo}. The @code{BEGIN} rule prints a title
+for the report. There is no need to use the @code{BEGIN} rule to
+initialize the counter @code{n} to zero, since @command{awk} does this
+automatically (@pxref{Variables}).
+The second rule increments the variable @code{n} every time a
+record containing the pattern @samp{foo} is read. The @code{END} rule
+prints the value of @code{n} at the end of the run.
+
+The special patterns @code{BEGIN} and @code{END} cannot be used in ranges
+or with Boolean operators (indeed, they cannot be used with any operators).
+An @command{awk} program may have multiple @code{BEGIN} and/or @code{END}
+rules. They are executed in the order in which they appear: all the @code{BEGIN}
+rules at startup and all the @code{END} rules at termination.
+@code{BEGIN} and @code{END} rules may be intermixed with other rules.
+This feature was added in the 1987 version of @command{awk} and is included
+in the POSIX standard.
+The original (1978) version of @command{awk}
+required the @code{BEGIN} rule to be placed at the beginning of the
+program, the @code{END} rule to be placed at the end, and only allowed one of
+each.
+This is no longer required, but it is a good idea to follow this template
+in terms of program organization and readability.
+
+Multiple @code{BEGIN} and @code{END} rules are useful for writing
+library functions, because each library file can have its own @code{BEGIN} and/or
+@code{END} rule to do its own initialization and/or cleanup.
+The order in which library functions are named on the command line
+controls the order in which their @code{BEGIN} and @code{END} rules are
+executed. Therefore, you have to be careful when writing such rules in
+library files so that the order in which they are executed doesn't matter.
+@xref{Options}, for more information on
+using library functions.
+@xref{Library Functions},
+for a number of useful library functions.
+
+If an @command{awk} program has only a @code{BEGIN} rule and no
+other rules, then the program exits after the @code{BEGIN} rule is
+run.@footnote{The original version of @command{awk} used to keep
+reading and ignoring input until the end of the file was seen.} However, if an
+@code{END} rule exists, then the input is read, even if there are
+no other rules in the program. This is necessary in case the @code{END}
+rule checks the @code{FNR} and @code{NR} variables.
+
+@node I/O And BEGIN/END
+@subsubsection Input/Output from @code{BEGIN} and @code{END} Rules
+
+@cindex input/output, from @code{BEGIN} and @code{END}
+There are several (sometimes subtle) points to remember when doing I/O
+from a @code{BEGIN} or @code{END} rule.
+The first has to do with the value of @code{$0} in a @code{BEGIN}
+rule. Because @code{BEGIN} rules are executed before any input is read,
+there simply is no input record, and therefore no fields, when
+executing @code{BEGIN} rules. References to @code{$0} and the fields
+yield a null string or zero, depending upon the context. One way
+to give @code{$0} a real value is to execute a @code{getline} command
+without a variable (@pxref{Getline}).
+Another way is simply to assign a value to @code{$0}.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{BEGIN}/@code{END} patterns
+@cindex POSIX @command{awk}, @code{BEGIN}/@code{END} patterns
+@cindex @code{print} statement, @code{BEGIN}/@code{END} patterns and
+@cindex @code{BEGIN} pattern, @code{print} statement and
+@cindex @code{END} pattern, @code{print} statement and
+The second point is similar to the first but from the other direction.
+Traditionally, due largely to implementation issues, @code{$0} and
+@code{NF} were @emph{undefined} inside an @code{END} rule.
+The POSIX standard specifies that @code{NF} is available in an @code{END}
+rule. It contains the number of fields from the last input record.
+Most probably due to an oversight, the standard does not say that @code{$0}
+is also preserved, although logically one would think that it should be.
+In fact, @command{gawk} does preserve the value of @code{$0} for use in
+@code{END} rules. Be aware, however, that Unix @command{awk}, and possibly
+other implementations, do not.
+
+The third point follows from the first two. The meaning of @samp{print}
+inside a @code{BEGIN} or @code{END} rule is the same as always:
+@samp{print $0}. If @code{$0} is the null string, then this prints an
+empty line. Many long time @command{awk} programmers use an unadorned
+@samp{print} in @code{BEGIN} and @code{END} rules, to mean @samp{@w{print ""}},
+relying on @code{$0} being null. Although one might generally get away with
+this in @code{BEGIN} rules, it is a very bad idea in @code{END} rules,
+at least in @command{gawk}. It is also poor style, since if an empty
+line is needed in the output, the program should print one explicitly.
+
+@cindex @code{next} statement, @code{BEGIN}/@code{END} patterns and
+@cindex @code{nextfile} statement, @code{BEGIN}/@code{END} patterns and
+@cindex @code{BEGIN} pattern, @code{next}/@code{nextfile} statements and
+@cindex @code{END} pattern, @code{next}/@code{nextfile} statements and
+Finally, the @code{next} and @code{nextfile} statements are not allowed
+in a @code{BEGIN} rule, because the implicit
+read-a-record-and-match-against-the-rules loop has not started yet. Similarly, those statements
+are not valid in an @code{END} rule, since all the input has been read.
+(@xref{Next Statement}, and see
+@ref{Nextfile Statement}.)
+@c ENDOFRANGE beg
+@c ENDOFRANGE end
+
+@node Empty
+@subsection The Empty Pattern
+
+@cindex empty pattern
+@cindex patterns, empty
+An empty (i.e., nonexistent) pattern is considered to match @emph{every}
+input record. For example, the program:
+
+@example
+awk '@{ print $1 @}' BBS-list
+@end example
+
+@noindent
+prints the first field of every record.
+@c ENDOFRANGE pat
+
+@node Using Shell Variables
+@section Using Shell Variables in Programs
+@cindex shells, variables
+@cindex @command{awk} programs, shell variables in
+@c @cindex shell and @command{awk} interaction
+
+@command{awk} programs are often used as components in larger
+programs written in shell.
+For example, it is very common to use a shell variable to
+hold a pattern that the @command{awk} program searches for.
+There are two ways to get the value of the shell variable
+into the body of the @command{awk} program.
+
+@cindex shells, quoting
+The most common method is to use shell quoting to substitute
+the variable's value into the program inside the script.
+For example, in the following program:
+
+@example
+echo -n "Enter search pattern: "
+read pattern
+awk "/$pattern/ "'@{ nmatches++ @}
+ END @{ print nmatches, "found" @}' /path/to/data
+@end example
+
+@noindent
+the @command{awk} program consists of two pieces of quoted text
+that are concatenated together to form the program.
+The first part is double-quoted, which allows substitution of
+the @code{pattern} variable inside the quotes.
+The second part is single-quoted.
+
+Variable substitution via quoting works, but can be potentially
+messy. It requires a good understanding of the shell's quoting rules
+(@pxref{Quoting}),
+and it's often difficult to correctly
+match up the quotes when reading the program.
+
+A better method is to use @command{awk}'s variable assignment feature
+(@pxref{Assignment Options})
+to assign the shell variable's value to an @command{awk} variable's
+value. Then use dynamic regexps to match the pattern
+(@pxref{Computed Regexps}).
+The following shows how to redo the
+previous example using this technique:
+
+@example
+echo -n "Enter search pattern: "
+read pattern
+awk -v pat="$pattern" '$0 ~ pat @{ nmatches++ @}
+ END @{ print nmatches, "found" @}' /path/to/data
+@end example
+
+@noindent
+Now, the @command{awk} program is just one single-quoted string.
+The assignment @samp{-v pat="$pattern"} still requires double quotes,
+in case there is whitespace in the value of @code{$pattern}.
+The @command{awk} variable @code{pat} could be named @code{pattern}
+too, but that would be more confusing. Using a variable also
+provides more flexibility, since the variable can be used anywhere inside
+the program---for printing, as an array subscript, or for any other
+use---without requiring the quoting tricks at every point in the program.
+
+@node Action Overview
+@section Actions
+@c @cindex action, definition of
+@c @cindex curly braces
+@c @cindex action, curly braces
+@c @cindex action, separating statements
+@cindex actions
+
+An @command{awk} program or script consists of a series of
+rules and function definitions interspersed. (Functions are
+described later. @xref{User-defined}.)
+A rule contains a pattern and an action, either of which (but not
+both) may be omitted. The purpose of the @dfn{action} is to tell
+@command{awk} what to do once a match for the pattern is found. Thus,
+in outline, an @command{awk} program generally looks like this:
+
+@example
+@r{[}@var{pattern}@r{]} @r{[}@{ @var{action} @}@r{]}
+@r{[}@var{pattern}@r{]} @r{[}@{ @var{action} @}@r{]}
+@dots{}
+function @var{name}(@var{args}) @{ @dots{} @}
+@dots{}
+@end example
+
+@cindex @code{@{@}} (braces), actions and
+@cindex braces (@code{@{@}}), actions and
+@cindex separators, for statements in actions
+@cindex newlines, separating statements in actions
+@cindex @code{;} (semicolon), separating statements in actions
+@cindex semicolon (@code{;}), separating statements in actions
+An action consists of one or more @command{awk} @dfn{statements}, enclosed
+in curly braces (@samp{@{@dots{}@}}). Each statement specifies one
+thing to do. The statements are separated by newlines or semicolons.
+The curly braces around an action must be used even if the action
+contains only one statement, or if it contains no statements at
+all. However, if you omit the action entirely, omit the curly braces as
+well. An omitted action is equivalent to @samp{@{ print $0 @}}:
+
+@example
+/foo/ @{ @} @i{match @code{foo}, do nothing --- empty action}
+/foo/ @i{match @code{foo}, print the record --- omitted action}
+@end example
+
+The following types of statements are supported in @command{awk}:
+
+@table @asis
+@cindex side effects, statements
+@item Expressions
+Call functions or assign values to variables
+(@pxref{Expressions}). Executing
+this kind of statement simply computes the value of the expression.
+This is useful when the expression has side effects
+(@pxref{Assignment Ops}).
+
+@item Control statements
+Specify the control flow of @command{awk}
+programs. The @command{awk} language gives you C-like constructs
+(@code{if}, @code{for}, @code{while}, and @code{do}) as well as a few
+special ones (@pxref{Statements}).
+
+@item Compound statements
+Consist of one or more statements enclosed in
+curly braces. A compound statement is used in order to put several
+statements together in the body of an @code{if}, @code{while}, @code{do},
+or @code{for} statement.
+
+@item Input statements
+Use the @code{getline} command
+(@pxref{Getline}).
+Also supplied in @command{awk} are the @code{next}
+statement (@pxref{Next Statement}),
+and the @code{nextfile} statement
+(@pxref{Nextfile Statement}).
+
+@item Output statements
+Such as @code{print} and @code{printf}.
+@xref{Printing}.
+
+@item Deletion statements
+For deleting array elements.
+@xref{Delete}.
+@end table
+
+@node Statements
+@section Control Statements in Actions
+@c STARTOFRANGE csta
+@cindex control statements
+@c STARTOFRANGE acs
+@cindex statements, control, in actions
+@c STARTOFRANGE accs
+@cindex actions, control statements in
+
+@dfn{Control statements}, such as @code{if}, @code{while}, and so on,
+control the flow of execution in @command{awk} programs. Most of the
+control statements in @command{awk} are patterned on similar statements in C.
+
+@cindex compound statements@comma{} control statements and
+@cindex statements, compound@comma{} control statements and
+@cindex body, in actions
+@cindex @code{@{@}} (braces), statements, grouping
+@cindex braces (@code{@{@}}), statements, grouping
+@cindex newlines, separating statements in actions
+@cindex @code{;} (semicolon), separating statements in actions
+@cindex semicolon (@code{;}), separating statements in actions
+All the control statements start with special keywords, such as @code{if}
+and @code{while}, to distinguish them from simple expressions.
+Many control statements contain other statements. For example, the
+@code{if} statement contains another statement that may or may not be
+executed. The contained statement is called the @dfn{body}.
+To include more than one statement in the body, group them into a
+single @dfn{compound statement} with curly braces, separating them with
+newlines or semicolons.
+
+@menu
+* If Statement:: Conditionally execute some @command{awk}
+ statements.
+* While Statement:: Loop until some condition is satisfied.
+* Do Statement:: Do specified action while looping until some
+ condition is satisfied.
+* For Statement:: Another looping statement, that provides
+ initialization and increment clauses.
+* Switch Statement:: Switch/case evaluation for conditional
+ execution of statements based on a value.
+* Break Statement:: Immediately exit the innermost enclosing loop.
+* Continue Statement:: Skip to the end of the innermost enclosing
+ loop.
+* Next Statement:: Stop processing the current input record.
+* Nextfile Statement:: Stop processing the current file.
+* Exit Statement:: Stop execution of @command{awk}.
+@end menu
+
+@node If Statement
+@subsection The @code{if}-@code{else} Statement
+
+@cindex @code{if} statement
+The @code{if}-@code{else} statement is @command{awk}'s decision-making
+statement. It looks like this:
+
+@example
+if (@var{condition}) @var{then-body} @r{[}else @var{else-body}@r{]}
+@end example
+
+@noindent
+The @var{condition} is an expression that controls what the rest of the
+statement does. If the @var{condition} is true, @var{then-body} is
+executed; otherwise, @var{else-body} is executed.
+The @code{else} part of the statement is
+optional. The condition is considered false if its value is zero or
+the null string; otherwise, the condition is true.
+Refer to the following:
+
+@example
+if (x % 2 == 0)
+ print "x is even"
+else
+ print "x is odd"
+@end example
+
+In this example, if the expression @samp{x % 2 == 0} is true (that is,
+if the value of @code{x} is evenly divisible by two), then the first
+@code{print} statement is executed; otherwise, the second @code{print}
+statement is executed.
+If the @code{else} keyword appears on the same line as @var{then-body} and
+@var{then-body} is not a compound statement (i.e., not surrounded by
+curly braces), then a semicolon must separate @var{then-body} from
+the @code{else}.
+To illustrate this, the previous example can be rewritten as:
+
+@example
+if (x % 2 == 0) print "x is even"; else
+ print "x is odd"
+@end example
+
+@noindent
+If the @samp{;} is left out, @command{awk} can't interpret the statement and
+it produces a syntax error. Don't actually write programs this way,
+because a human reader might fail to see the @code{else} if it is not
+the first thing on its line.
+
+@node While Statement
+@subsection The @code{while} Statement
+@cindex @code{while} statement
+@cindex loops
+@cindex loops, See Also @code{while} statement
+
+In programming, a @dfn{loop} is a part of a program that can
+be executed two or more times in succession.
+The @code{while} statement is the simplest looping statement in
+@command{awk}. It repeatedly executes a statement as long as a condition is
+true. For example:
+
+@example
+while (@var{condition})
+ @var{body}
+@end example
+
+@cindex body, in loops
+@noindent
+@var{body} is a statement called the @dfn{body} of the loop,
+and @var{condition} is an expression that controls how long the loop
+keeps running.
+The first thing the @code{while} statement does is test the @var{condition}.
+If the @var{condition} is true, it executes the statement @var{body}.
+@ifinfo
+(The @var{condition} is true when the value
+is not zero and not a null string.)
+@end ifinfo
+After @var{body} has been executed,
+@var{condition} is tested again, and if it is still true, @var{body} is
+executed again. This process repeats until the @var{condition} is no longer
+true. If the @var{condition} is initially false, the body of the loop is
+never executed and @command{awk} continues with the statement following
+the loop.
+This example prints the first three fields of each record, one per line:
+
+@example
+awk '@{ i = 1
+ while (i <= 3) @{
+ print $i
+ i++
+ @}
+@}' inventory-shipped
+@end example
+
+@noindent
+The body of this loop is a compound statement enclosed in braces,
+containing two statements.
+The loop works in the following manner: first, the value of @code{i} is set to one.
+Then, the @code{while} statement tests whether @code{i} is less than or equal to
+three. This is true when @code{i} equals one, so the @code{i}-th
+field is printed. Then the @samp{i++} increments the value of @code{i}
+and the loop repeats. The loop terminates when @code{i} reaches four.
+
+A newline is not required between the condition and the
+body; however using one makes the program clearer unless the body is a
+compound statement or else is very simple. The newline after the open-brace
+that begins the compound statement is not required either, but the
+program is harder to read without it.
+
+@node Do Statement
+@subsection The @code{do}-@code{while} Statement
+@cindex @code{do}-@code{while} statement
+
+The @code{do} loop is a variation of the @code{while} looping statement.
+The @code{do} loop executes the @var{body} once and then repeats the
+@var{body} as long as the @var{condition} is true. It looks like this:
+
+@example
+do
+ @var{body}
+while (@var{condition})
+@end example
+
+Even if the @var{condition} is false at the start, the @var{body} is
+executed at least once (and only once, unless executing @var{body}
+makes @var{condition} true). Contrast this with the corresponding
+@code{while} statement:
+
+@example
+while (@var{condition})
+ @var{body}
+@end example
+
+@noindent
+This statement does not execute @var{body} even once if the @var{condition}
+is false to begin with.
+The following is an example of a @code{do} statement:
+
+@example
+@{ i = 1
+ do @{
+ print $0
+ i++
+ @} while (i <= 10)
+@}
+@end example
+
+@noindent
+This program prints each input record 10 times. However, it isn't a very
+realistic example, since in this case an ordinary @code{while} would do
+just as well. This situation reflects actual experience; only
+occasionally is there a real use for a @code{do} statement.
+
+@node For Statement
+@subsection The @code{for} Statement
+@cindex @code{for} statement
+
+The @code{for} statement makes it more convenient to count iterations of a
+loop. The general form of the @code{for} statement looks like this:
+
+@example
+for (@var{initialization}; @var{condition}; @var{increment})
+ @var{body}
+@end example
+
+@noindent
+The @var{initialization}, @var{condition}, and @var{increment} parts are
+arbitrary @command{awk} expressions, and @var{body} stands for any
+@command{awk} statement.
+
+The @code{for} statement starts by executing @var{initialization}.
+Then, as long
+as the @var{condition} is true, it repeatedly executes @var{body} and then
+@var{increment}. Typically, @var{initialization} sets a variable to
+either zero or one, @var{increment} adds one to it, and @var{condition}
+compares it against the desired number of iterations.
+For example:
+
+@example
+awk '@{ for (i = 1; i <= 3; i++)
+ print $i
+@}' inventory-shipped
+@end example
+
+@noindent
+This prints the first three fields of each input record, with one field per
+line.
+
+It isn't possible to
+set more than one variable in the
+@var{initialization} part without using a multiple assignment statement
+such as @samp{x = y = 0}. This makes sense only if all the initial values
+are equal. (But it is possible to initialize additional variables by writing
+their assignments as separate statements preceding the @code{for} loop.)
+
+@c @cindex comma operator, not supported
+The same is true of the @var{increment} part. Incrementing additional
+variables requires separate statements at the end of the loop.
+The C compound expression, using C's comma operator, is useful in
+this context but it is not supported in @command{awk}.
+
+Most often, @var{increment} is an increment expression, as in the previous
+example. But this is not required; it can be any expression
+whatsoever. For example, the following statement prints all the powers of two
+between 1 and 100:
+
+@example
+for (i = 1; i <= 100; i *= 2)
+ print i
+@end example
+
+If there is nothing to be done, any of the three expressions in the
+parentheses following the @code{for} keyword may be omitted. Thus,
+@w{@samp{for (; x > 0;)}} is equivalent to @w{@samp{while (x > 0)}}. If the
+@var{condition} is omitted, it is treated as true, effectively
+yielding an @dfn{infinite loop} (i.e., a loop that never terminates).
+
+In most cases, a @code{for} loop is an abbreviation for a @code{while}
+loop, as shown here:
+
+@example
+@var{initialization}
+while (@var{condition}) @{
+ @var{body}
+ @var{increment}
+@}
+@end example
+
+@cindex loops, @code{continue} statements and
+@noindent
+The only exception is when the @code{continue} statement
+(@pxref{Continue Statement}) is used
+inside the loop. Changing a @code{for} statement to a @code{while}
+statement in this way can change the effect of the @code{continue}
+statement inside the loop.
+
+The @command{awk} language has a @code{for} statement in addition to a
+@code{while} statement because a @code{for} loop is often both less work to
+type and more natural to think of. Counting the number of iterations is
+very common in loops. It can be easier to think of this counting as part
+of looping rather than as something to do inside the loop.
+
+@ifinfo
+@cindex @code{in} operator
+There is an alternate version of the @code{for} loop, for iterating over
+all the indices of an array:
+
+@example
+for (i in array)
+ @var{do something with} array[i]
+@end example
+
+@noindent
+@xref{Scanning an Array},
+for more information on this version of the @code{for} loop.
+@end ifinfo
+
+@node Switch Statement
+@subsection The @code{switch} Statement
+@cindex @code{switch} statement
+@cindex @code{case} keyword
+@cindex @code{default} keyword
+
+@quotation NOTE
+This @value{SUBSECTION} describes an experimental feature
+added in @command{gawk} 3.1.3. It is @emph{not} enabled by default. To
+enable it, use the @option{--enable-switch} option to @command{configure}
+when @command{gawk} is being configured and built.
+@xref{Additional Configuration Options}, for more information.
+@end quotation
+
+The @code{switch} statement allows the evaluation of an expression and
+the execution of statements based on a @code{case} match. Case statements
+are checked for a match in the order they are defined. If no suitable
+@code{case} is found, the @code{default} section is executed, if supplied.
+
+Each @code{case} contains a single constant, be it numeric, string, or
+regexp. The @code{switch} expression is evaluated, and then each
+@code{case}'s constant is compared against the result in turn. The type of constant
+determines the comparison: numeric or string do the usual comparisons.
+A regexp constant does a regular expression match against the string
+value of the original expression. The general form of the @code{switch}
+statement looks like this:
+
+@example
+switch (@var{expression}) @{
+case @var{value or regular expression}:
+ @var{case-body}
+default:
+ @var{default-body}
+@}
+@end example
+
+Control flow in
+the @code{switch} statement works as it does in C. Once a match to a given
+case is made, case statement bodies are executed until a @code{break},
+@code{continue}, @code{next}, @code{nextfile} or @code{exit} is encountered,
+or the end of the @code{switch} statement itself. For example:
+
+@example
+switch (NR * 2 + 1) @{
+case 3:
+case "11":
+ print NR - 1
+ break
+
+case /2[[:digit:]]+/:
+ print NR
+
+default:
+ print NR + 1
+
+case -1:
+ print NR * -1
+@}
+@end example
+
+Note that if none of the statements specified above halt execution
+of a matched @code{case} statement, execution falls through to the
+next @code{case} until execution halts. In the above example, for
+any case value starting with @samp{2} followed by one or more digits,
+the @code{print} statement is executed and then falls through into the
+@code{default} section, executing its @code{print} statement. In turn,
+the @minus{}1 case will also be executed since the @code{default} does
+not halt execution.
+
+@node Break Statement
+@subsection The @code{break} Statement
+@cindex @code{break} statement
+@cindex loops, exiting
+
+The @code{break} statement jumps out of the innermost @code{for},
+@code{while}, or @code{do} loop that encloses it. The following example
+finds the smallest divisor of any integer, and also identifies prime
+numbers:
+
+@example
+# find smallest divisor of num
+@{
+ num = $1
+ for (div = 2; div*div <= num; div++)
+ if (num % div == 0)
+ break
+ if (num % div == 0)
+ printf "Smallest divisor of %d is %d\n", num, div
+ else
+ printf "%d is prime\n", num
+@}
+@end example
+
+When the remainder is zero in the first @code{if} statement, @command{awk}
+immediately @dfn{breaks out} of the containing @code{for} loop. This means
+that @command{awk} proceeds immediately to the statement following the loop
+and continues processing. (This is very different from the @code{exit}
+statement, which stops the entire @command{awk} program.
+@xref{Exit Statement}.)
+
+Th following program illustrates how the @var{condition} of a @code{for}
+or @code{while} statement could be replaced with a @code{break} inside
+an @code{if}:
+
+@example
+# find smallest divisor of num
+@{
+ num = $1
+ for (div = 2; ; div++) @{
+ if (num % div == 0) @{
+ printf "Smallest divisor of %d is %d\n", num, div
+ break
+ @}
+ if (div*div > num) @{
+ printf "%d is prime\n", num
+ break
+ @}
+ @}
+@}
+@end example
+
+@c @cindex @code{break}, outside of loops
+@c @cindex historical features
+@c @cindex @command{awk} language, POSIX version
+@cindex POSIX @command{awk}, @code{break} statement and
+@cindex dark corner, @code{break} statement
+@cindex @command{gawk}, @code{break} statement in
+The @code{break} statement has no meaning when
+used outside the body of a loop. However, although it was never documented,
+historical implementations of @command{awk} treated the @code{break}
+statement outside of a loop as if it were a @code{next} statement
+(@pxref{Next Statement}).
+Recent versions of Unix @command{awk} no longer allow this usage.
+@command{gawk} supports this use of @code{break} only
+if @option{--traditional}
+has been specified on the command line
+(@pxref{Options}).
+Otherwise, it is treated as an error, since the POSIX standard
+specifies that @code{break} should only be used inside the body of a
+loop.
+@value{DARKCORNER}
+
+@node Continue Statement
+@subsection The @code{continue} Statement
+
+@cindex @code{continue} statement
+As with @code{break}, the @code{continue} statement is used only inside
+@code{for}, @code{while}, and @code{do} loops. It skips
+over the rest of the loop body, causing the next cycle around the loop
+to begin immediately. Contrast this with @code{break}, which jumps out
+of the loop altogether.
+
+The @code{continue} statement in a @code{for} loop directs @command{awk} to
+skip the rest of the body of the loop and resume execution with the
+increment-expression of the @code{for} statement. The following program
+illustrates this fact:
+
+@example
+BEGIN @{
+ for (x = 0; x <= 20; x++) @{
+ if (x == 5)
+ continue
+ printf "%d ", x
+ @}
+ print ""
+@}
+@end example
+
+@noindent
+This program prints all the numbers from 0 to 20---except for 5, for
+which the @code{printf} is skipped. Because the increment @samp{x++}
+is not skipped, @code{x} does not remain stuck at 5. Contrast the
+@code{for} loop from the previous example with the following @code{while} loop:
+
+@example
+BEGIN @{
+ x = 0
+ while (x <= 20) @{
+ if (x == 5)
+ continue
+ printf "%d ", x
+ x++
+ @}
+ print ""
+@}
+@end example
+
+@noindent
+This program loops forever once @code{x} reaches 5.
+
+@c @cindex @code{continue}, outside of loops
+@c @cindex historical features
+@c @cindex @command{awk} language, POSIX version
+@cindex POSIX @command{awk}, @code{continue} statement and
+@cindex dark corner, @code{continue} statement
+@cindex @command{gawk}, @code{continue} statement in
+The @code{continue} statement has no meaning when used outside the body of
+a loop. Historical versions of @command{awk} treated a @code{continue}
+statement outside a loop the same way they treated a @code{break}
+statement outside a loop: as if it were a @code{next}
+statement
+(@pxref{Next Statement}).
+Recent versions of Unix @command{awk} no longer work this way, and
+@command{gawk} allows it only if @option{--traditional} is specified on
+the command line (@pxref{Options}). Just like the
+@code{break} statement, the POSIX standard specifies that @code{continue}
+should only be used inside the body of a loop.
+@value{DARKCORNER}
+
+@node Next Statement
+@subsection The @code{next} Statement
+@cindex @code{next} statement
+
+The @code{next} statement forces @command{awk} to immediately stop processing
+the current record and go on to the next record. This means that no
+further rules are executed for the current record, and the rest of the
+current rule's action isn't executed.
+
+Contrast this with the effect of the @code{getline} function
+(@pxref{Getline}). That also causes
+@command{awk} to read the next record immediately, but it does not alter the
+flow of control in any way (i.e., the rest of the current action executes
+with a new input record).
+
+@cindex @command{awk} programs, execution of
+At the highest level, @command{awk} program execution is a loop that reads
+an input record and then tests each rule's pattern against it. If you
+think of this loop as a @code{for} statement whose body contains the
+rules, then the @code{next} statement is analogous to a @code{continue}
+statement. It skips to the end of the body of this implicit loop and
+executes the increment (which reads another record).
+
+For example, suppose an @command{awk} program works only on records
+with four fields, and it shouldn't fail when given bad input. To avoid
+complicating the rest of the program, write a ``weed out'' rule near
+the beginning, in the following manner:
+
+@example
+NF != 4 @{
+ err = sprintf("%s:%d: skipped: NF != 4\n", FILENAME, FNR)
+ print err > "/dev/stderr"
+ next
+@}
+@end example
+
+@noindent
+Because of the @code{next} statement,
+the program's subsequent rules won't see the bad record. The error
+message is redirected to the standard error output stream, as error
+messages should be.
+For more detail see
+@ref{Special Files}.
+
+@c @cindex @command{awk} language, POSIX version
+@c @cindex @code{next}, inside a user-defined function
+@cindex @code{BEGIN} pattern, @code{next}/@code{nextfile} statements and
+@cindex @code{END} pattern, @code{next}/@code{nextfile} statements and
+@cindex POSIX @command{awk}, @code{next}/@code{nextfile} statements and
+@cindex @code{next} statement, user-defined functions and
+@cindex functions, user-defined, @code{next}/@code{nextfile} statements and
+According to the POSIX standard, the behavior is undefined if
+the @code{next} statement is used in a @code{BEGIN} or @code{END} rule.
+@command{gawk} treats it as a syntax error.
+Although POSIX permits it,
+some other @command{awk} implementations don't allow the @code{next}
+statement inside function bodies
+(@pxref{User-defined}).
+Just as with any other @code{next} statement, a @code{next} statement inside a
+function body reads the next record and starts processing it with the
+first rule in the program.
+If the @code{next} statement causes the end of the input to be reached,
+then the code in any @code{END} rules is executed.
+@xref{BEGIN/END}.
+
+@node Nextfile Statement
+@subsection Using @command{gawk}'s @code{nextfile} Statement
+@cindex @code{nextfile} statement
+@cindex differences in @command{awk} and @command{gawk}, @code{next}/@code{nextfile} statements
+
+@command{gawk} provides the @code{nextfile} statement,
+which is similar to the @code{next} statement.
+However, instead of abandoning processing of the current record, the
+@code{nextfile} statement instructs @command{gawk} to stop processing the
+current @value{DF}.
+
+The @code{nextfile} statement is a @command{gawk} extension.
+In most other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+@code{nextfile} is not special.
+
+Upon execution of the @code{nextfile} statement, @code{FILENAME} is
+updated to the name of the next @value{DF} listed on the command line,
+@code{FNR} is reset to one, @code{ARGIND} is incremented, and processing
+starts over with the first rule in the program.
+(@code{ARGIND} hasn't been introduced yet. @xref{Built-in Variables}.)
+If the @code{nextfile} statement causes the end of the input to be reached,
+then the code in any @code{END} rules is executed.
+@xref{BEGIN/END}.
+
+The @code{nextfile} statement is useful when there are many @value{DF}s
+to process but it isn't necessary to process every record in every file.
+Normally, in order to move on to the next @value{DF}, a program
+has to continue scanning the unwanted records. The @code{nextfile}
+statement accomplishes this much more efficiently.
+
+While one might think that @samp{close(FILENAME)} would accomplish
+the same as @code{nextfile}, this isn't true. @code{close} is
+reserved for closing files, pipes, and coprocesses that are
+opened with redirections. It is not related to the main processing that
+@command{awk} does with the files listed in @code{ARGV}.
+
+If it's necessary to use an @command{awk} version that doesn't support
+@code{nextfile}, see
+@ref{Nextfile Function},
+for a user-defined function that simulates the @code{nextfile}
+statement.
+
+@cindex functions, user-defined, @code{next}/@code{nextfile} statements and
+@cindex @code{nextfile} statement, user-defined functions and
+The current version of the Bell Laboratories @command{awk}
+(@pxref{Other Versions})
+also supports @code{nextfile}. However, it doesn't allow the @code{nextfile}
+statement inside function bodies
+(@pxref{User-defined}).
+@command{gawk} does; a @code{nextfile} inside a
+function body reads the next record and starts processing it with the
+first rule in the program, just as any other @code{nextfile} statement.
+
+@cindex @code{next file} statement, in @command{gawk}
+@cindex @command{gawk}, @code{next file} statement in
+@cindex @code{nextfile} statement, in @command{gawk}
+@cindex @command{gawk}, @code{nextfile} statement in
+@strong{Caution:} Versions of @command{gawk} prior to 3.0 used two
+words (@samp{next file}) for the @code{nextfile} statement.
+In @value{PVERSION} 3.0, this was changed
+to one word, because the treatment of @samp{file} was
+inconsistent. When it appeared after @code{next}, @samp{file} was a keyword;
+otherwise, it was a regular identifier. The old usage is no longer
+accepted; @samp{next file} generates a syntax error.
+
+@node Exit Statement
+@subsection The @code{exit} Statement
+
+@cindex @code{exit} statement
+The @code{exit} statement causes @command{awk} to immediately stop
+executing the current rule and to stop processing input; any remaining input
+is ignored. The @code{exit} statement is written as follows:
+
+@example
+exit @r{[}@var{return code}@r{]}
+@end example
+
+@cindex @code{BEGIN} pattern, @code{exit} statement and
+@cindex @code{END} pattern, @code{exit} statement and
+When an @code{exit} statement is executed from a @code{BEGIN} rule, the
+program stops processing everything immediately. No input records are
+read. However, if an @code{END} rule is present,
+as part of executing the @code{exit} statement,
+the @code{END} rule is executed
+(@pxref{BEGIN/END}).
+If @code{exit} is used as part of an @code{END} rule, it causes
+the program to stop immediately.
+
+An @code{exit} statement that is not part of a @code{BEGIN} or @code{END}
+rule stops the execution of any further automatic rules for the current
+record, skips reading any remaining input records, and executes the
+@code{END} rule if there is one.
+
+In such a case,
+if you don't want the @code{END} rule to do its job, set a variable
+to nonzero before the @code{exit} statement and check that variable in
+the @code{END} rule.
+@xref{Assert Function},
+for an example that does this.
+
+@cindex dark corner, @code{exit} statement
+If an argument is supplied to @code{exit}, its value is used as the exit
+status code for the @command{awk} process. If no argument is supplied,
+@code{exit} returns status zero (success). In the case where an argument
+is supplied to a first @code{exit} statement, and then @code{exit} is
+called a second time from an @code{END} rule with no argument,
+@command{awk} uses the previously supplied exit value.
+@value{DARKCORNER}
+
+@cindex programming conventions, @code{exit} statement
+For example, suppose an error condition occurs that is difficult or
+impossible to handle. Conventionally, programs report this by
+exiting with a nonzero status. An @command{awk} program can do this
+using an @code{exit} statement with a nonzero argument, as shown
+in the following example:
+
+@example
+BEGIN @{
+ if (("date" | getline date_now) <= 0) @{
+ print "Can't get system date" > "/dev/stderr"
+ exit 1
+ @}
+ print "current date is", date_now
+ close("date")
+@}
+@end example
+@c ENDOFRANGE csta
+@c ENDOFRANGE acs
+@c ENDOFRANGE accs
+
+@node Built-in Variables
+@section Built-in Variables
+@c STARTOFRANGE bvar
+@cindex built-in variables
+@c STARTOFRANGE varb
+@cindex variables, built-in
+
+Most @command{awk} variables are available to use for your own
+purposes; they never change unless your program assigns values to
+them, and they never affect anything unless your program examines them.
+However, a few variables in @command{awk} have special built-in meanings.
+@command{awk} examines some of these automatically, so that they enable you
+to tell @command{awk} how to do certain things. Others are set
+automatically by @command{awk}, so that they carry information from the
+internal workings of @command{awk} to your program.
+
+@cindex @command{gawk}, built-in variables and
+This @value{SECTION} documents all the built-in variables of
+@command{gawk}, most of which are also documented in the chapters
+describing their areas of activity.
+
+@menu
+* User-modified:: Built-in variables that you change to control
+ @command{awk}.
+* Auto-set:: Built-in variables where @command{awk} gives
+ you information.
+* ARGC and ARGV:: Ways to use @code{ARGC} and @code{ARGV}.
+@end menu
+
+@node User-modified
+@subsection Built-in Variables That Control @command{awk}
+@c STARTOFRANGE bvaru
+@cindex built-in variables, user-modifiable
+@c STARTOFRANGE nmbv
+@cindex user-modifiable variables
+
+The following is an alphabetical list of variables that you can change to
+control how @command{awk} does certain things. The variables that are
+specific to @command{gawk} are marked with a pound sign@w{ (@samp{#}).}
+
+@table @code
+@cindex @code{BINMODE} variable
+@cindex binary input/output
+@cindex input/output, binary
+@item BINMODE #
+On non-POSIX systems, this variable specifies use of binary mode for all I/O.
+Numeric values of one, two, or three specify that input files, output files, or
+all files, respectively, should use binary I/O.
+Alternatively,
+string values of @code{"r"} or @code{"w"} specify that input files and
+output files, respectively, should use binary I/O.
+A string value of @code{"rw"} or @code{"wr"} indicates that all
+files should use binary I/O.
+Any other string value is equivalent to @code{"rw"}, but @command{gawk}
+generates a warning message.
+@code{BINMODE} is described in more detail in
+@ref{PC Using}.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{BINMODE} variable
+This variable is a @command{gawk} extension.
+In other @command{awk} implementations
+(except @command{mawk},
+@pxref{Other Versions}),
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+
+@cindex @code{CONVFMT} variable
+@cindex POSIX @command{awk}, @code{CONVFMT} variable and
+@cindex numbers, converting, to strings
+@cindex strings, converting, numbers to
+@item CONVFMT
+This string controls conversion of numbers to
+strings (@pxref{Conversion}).
+It works by being passed, in effect, as the first argument to the
+@code{sprintf} function
+(@pxref{String Functions}).
+Its default value is @code{"%.6g"}.
+@code{CONVFMT} was introduced by the POSIX standard.
+
+@cindex @code{FIELDWIDTHS} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{FIELDWIDTHS} variable
+@cindex field separators, @code{FIELDWIDTHS} variable and
+@cindex separators, field, @code{FIELDWIDTHS} variable and
+@item FIELDWIDTHS #
+This is a space-separated list of columns that tells @command{gawk}
+how to split input with fixed columnar boundaries.
+Assigning a value to @code{FIELDWIDTHS}
+overrides the use of @code{FS} for field splitting.
+@xref{Constant Size}, for more information.
+
+@cindex @command{gawk}, @code{FIELDWIDTHS} variable in
+If @command{gawk} is in compatibility mode
+(@pxref{Options}), then @code{FIELDWIDTHS}
+has no special meaning, and field-splitting operations occur based
+exclusively on the value of @code{FS}.
+
+@cindex @code{FS} variable
+@cindex separators, field
+@cindex field separators
+@item FS
+This is the input field separator
+(@pxref{Field Separators}).
+The value is a single-character string or a multi-character regular
+expression that matches the separations between fields in an input
+record. If the value is the null string (@code{""}), then each
+character in the record becomes a separate field.
+(This behavior is a @command{gawk} extension. POSIX @command{awk} does not
+specify the behavior when @code{FS} is the null string.)
+@c NEXT ED: Mark as common extension
+
+@cindex POSIX @command{awk}, @code{FS} variable and
+The default value is @w{@code{" "}}, a string consisting of a single
+space. As a special exception, this value means that any
+sequence of spaces, tabs, and/or newlines is a single separator.@footnote{In
+POSIX @command{awk}, newline does not count as whitespace.} It also causes
+spaces, tabs, and newlines at the beginning and end of a record to be ignored.
+
+You can set the value of @code{FS} on the command line using the
+@option{-F} option:
+
+@example
+awk -F, '@var{program}' @var{input-files}
+@end example
+
+@cindex @command{gawk}, field separators and
+If @command{gawk} is using @code{FIELDWIDTHS} for field splitting,
+assigning a value to @code{FS} causes @command{gawk} to return to
+the normal, @code{FS}-based field splitting. An easy way to do this
+is to simply say @samp{FS = FS}, perhaps with an explanatory comment.
+
+@cindex @code{IGNORECASE} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{IGNORECASE} variable
+@cindex case sensitivity, string comparisons and
+@cindex case sensitivity, regexps and
+@cindex regular expressions, case sensitivity
+@item IGNORECASE #
+If @code{IGNORECASE} is nonzero or non-null, then all string comparisons
+and all regular expression matching are case independent. Thus, regexp
+matching with @samp{~} and @samp{!~}, as well as the @code{gensub},
+@code{gsub}, @code{index}, @code{match}, @code{split}, and @code{sub}
+functions, record termination with @code{RS}, and field splitting with
+@code{FS}, all ignore case when doing their particular regexp operations.
+However, the value of @code{IGNORECASE} does @emph{not} affect array subscripting
+and it does not affect field splitting when using a single-character
+field separator.
+@xref{Case-sensitivity}.
+
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+If @command{gawk} is in compatibility mode
+(@pxref{Options}),
+then @code{IGNORECASE} has no special meaning. Thus, string
+and regexp operations are always case-sensitive.
+
+@cindex @code{LINT} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{LINT} variable
+@cindex lint checking
+@item LINT #
+When this variable is true (nonzero or non-null), @command{gawk}
+behaves as if the @option{--lint} command-line option is in effect.
+(@pxref{Options}).
+With a value of @code{"fatal"}, lint warnings become fatal errors.
+With a value of @code{"invalid"}, only warnings about things that are
+actually invalid are issued. (This is not fully implemented yet.)
+Any other true value prints nonfatal warnings.
+Assigning a false value to @code{LINT} turns off the lint warnings.
+
+@cindex @command{gawk}, @code{LINT} variable in
+This variable is a @command{gawk} extension. It is not special
+in other @command{awk} implementations. Unlike the other special variables,
+changing @code{LINT} does affect the production of lint warnings,
+even if @command{gawk} is in compatibility mode. Much as
+the @option{--lint} and @option{--traditional} options independently
+control different aspects of @command{gawk}'s behavior, the control
+of lint warnings during program execution is independent of the flavor
+of @command{awk} being executed.
+
+@cindex @code{OFMT} variable
+@cindex numbers, converting, to strings
+@cindex strings, converting, numbers to
+@item OFMT
+This string controls conversion of numbers to
+strings (@pxref{Conversion}) for
+printing with the @code{print} statement. It works by being passed
+as the first argument to the @code{sprintf} function
+(@pxref{String Functions}).
+Its default value is @code{"%.6g"}. Earlier versions of @command{awk}
+also used @code{OFMT} to specify the format for converting numbers to
+strings in general expressions; this is now done by @code{CONVFMT}.
+
+@cindex @code{sprintf} function, @code{OFMT} variable and
+@cindex @code{print} statement, @code{OFMT} variable and
+@cindex @code{OFS} variable
+@cindex separators, field
+@cindex field separators
+@item OFS
+This is the output field separator (@pxref{Output Separators}). It is
+output between the fields printed by a @code{print} statement. Its
+default value is @w{@code{" "}}, a string consisting of a single space.
+
+@cindex @code{ORS} variable
+@item ORS
+This is the output record separator. It is output at the end of every
+@code{print} statement. Its default value is @code{"\n"}, the newline
+character. (@xref{Output Separators}.)
+
+@cindex @code{RS} variable
+@cindex separators, record
+@cindex record separators
+@item RS
+This is @command{awk}'s input record separator. Its default value is a string
+containing a single newline character, which means that an input record
+consists of a single line of text.
+It can also be the null string, in which case records are separated by
+runs of blank lines.
+If it is a regexp, records are separated by
+matches of the regexp in the input text.
+(@xref{Records}.)
+
+The ability for @code{RS} to be a regular expression
+is a @command{gawk} extension.
+In most other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+just the first character of @code{RS}'s value is used.
+
+@cindex @code{SUBSEP} variable
+@cindex separators, subscript
+@cindex subscript separators
+@item SUBSEP
+This is the subscript separator. It has the default value of
+@code{"\034"} and is used to separate the parts of the indices of a
+multidimensional array. Thus, the expression @code{@w{foo["A", "B"]}}
+really accesses @code{foo["A\034B"]}
+(@pxref{Multi-dimensional}).
+
+@cindex @code{TEXTDOMAIN} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{TEXTDOMAIN} variable
+@cindex internationalization, localization
+@item TEXTDOMAIN #
+This variable is used for internationalization of programs at the
+@command{awk} level. It sets the default text domain for specially
+marked string constants in the source text, as well as for the
+@code{dcgettext}, @code{dcngettext} and @code{bindtextdomain} functions
+(@pxref{Internationalization}).
+The default value of @code{TEXTDOMAIN} is @code{"messages"}.
+
+This variable is a @command{gawk} extension.
+In other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+@end table
+@c ENDOFRANGE bvar
+@c ENDOFRANGE varb
+@c ENDOFRANGE bvaru
+@c ENDOFRANGE nmbv
+
+@node Auto-set
+@subsection Built-in Variables That Convey Information
+
+@c STARTOFRANGE bvconi
+@cindex built-in variables, conveying information
+@c STARTOFRANGE vbconi
+@cindex variables, built-in, conveying information
+The following is an alphabetical list of variables that @command{awk}
+sets automatically on certain occasions in order to provide
+information to your program. The variables that are specific to
+@command{gawk} are marked with a pound sign@w{ (@samp{#}).}
+
+@table @code
+@cindex @code{ARGC}/@code{ARGV} variables
+@cindex arguments, command-line
+@cindex command line, arguments
+@item ARGC@r{,} ARGV
+The command-line arguments available to @command{awk} programs are stored in
+an array called @code{ARGV}. @code{ARGC} is the number of command-line
+arguments present. @xref{Other Arguments}.
+Unlike most @command{awk} arrays,
+@code{ARGV} is indexed from 0 to @code{ARGC} @minus{} 1.
+In the following example:
+
+@example
+$ awk 'BEGIN @{
+> for (i = 0; i < ARGC; i++)
+> print ARGV[i]
+> @}' inventory-shipped BBS-list
+@print{} awk
+@print{} inventory-shipped
+@print{} BBS-list
+@end example
+
+@noindent
+@code{ARGV[0]} contains @code{"awk"}, @code{ARGV[1]}
+contains @code{"inventory-shipped"}, and @code{ARGV[2]} contains
+@code{"BBS-list"}. The value of @code{ARGC} is three, one more than the
+index of the last element in @code{ARGV}, because the elements are numbered
+from zero.
+
+@cindex programming conventions, @code{ARGC}/@code{ARGV} variables
+The names @code{ARGC} and @code{ARGV}, as well as the convention of indexing
+the array from 0 to @code{ARGC} @minus{} 1, are derived from the C language's
+method of accessing command-line arguments.
+
+The value of @code{ARGV[0]} can vary from system to system.
+Also, you should note that the program text is @emph{not} included in
+@code{ARGV}, nor are any of @command{awk}'s command-line options.
+@xref{ARGC and ARGV}, for information
+about how @command{awk} uses these variables.
+
+@cindex @code{ARGIND} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{ARGIND} variable
+@item ARGIND #
+The index in @code{ARGV} of the current file being processed.
+Every time @command{gawk} opens a new @value{DF} for processing, it sets
+@code{ARGIND} to the index in @code{ARGV} of the @value{FN}.
+When @command{gawk} is processing the input files,
+@samp{FILENAME == ARGV[ARGIND]} is always true.
+
+@cindex files, processing@comma{} @code{ARGIND} variable and
+This variable is useful in file processing; it allows you to tell how far
+along you are in the list of @value{DF}s as well as to distinguish between
+successive instances of the same @value{FN} on the command line.
+
+@cindex @value{FN}s, distinguishing
+While you can change the value of @code{ARGIND} within your @command{awk}
+program, @command{gawk} automatically sets it to a new value when the
+next file is opened.
+
+This variable is a @command{gawk} extension.
+In other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+
+@cindex @code{ENVIRON} variable
+@cindex environment variables
+@item ENVIRON
+An associative array that contains the values of the environment. The array
+indices are the environment variable names; the elements are the values of
+the particular environment variables. For example,
+@code{ENVIRON["HOME"]} might be @file{/home/arnold}. Changing this array
+does not affect the environment passed on to any programs that
+@command{awk} may spawn via redirection or the @code{system} function.
+@c (In a future version of @command{gawk}, it may do so.)
+
+Some operating systems may not have environment variables.
+On such systems, the @code{ENVIRON} array is empty (except for
+@w{@code{ENVIRON["AWKPATH"]}},
+@pxref{AWKPATH Variable}).
+
+@cindex @code{ERRNO} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{ERRNO} variable
+@cindex error handling, @code{ERRNO} variable and
+@item ERRNO #
+If a system error occurs during a redirection for @code{getline},
+during a read for @code{getline}, or during a @code{close} operation,
+then @code{ERRNO} contains a string describing the error.
+
+@code{ERRNO} works similarly to the C variable @code{errno}.
+In particular @command{gawk} @emph{never} clears it (sets it
+to zero or @code{""}). Thus, you should only expect its value
+to be meaningful when an I/O operation returns a failure
+value, such as @code{getline} returning @minus{}1.
+You are, of course, free to clear it yourself before doing an
+I/O operation.
+
+This variable is a @command{gawk} extension.
+In other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+
+@cindex @code{FILENAME} variable
+@cindex dark corner, @code{FILENAME} variable
+@item FILENAME
+The name of the file that @command{awk} is currently reading.
+When no @value{DF}s are listed on the command line, @command{awk} reads
+from the standard input and @code{FILENAME} is set to @code{"-"}.
+@code{FILENAME} is changed each time a new file is read
+(@pxref{Reading Files}).
+Inside a @code{BEGIN} rule, the value of @code{FILENAME} is
+@code{""}, since there are no input files being processed
+yet.@footnote{Some early implementations of Unix @command{awk} initialized
+@code{FILENAME} to @code{"-"}, even if there were @value{DF}s to be
+processed. This behavior was incorrect and should not be relied
+upon in your programs.}
+@value{DARKCORNER}
+Note, though, that using @code{getline}
+(@pxref{Getline})
+inside a @code{BEGIN} rule can give
+@code{FILENAME} a value.
+
+@cindex @code{FNR} variable
+@item FNR
+The current record number in the current file. @code{FNR} is
+incremented each time a new record is read
+(@pxref{Getline}). It is reinitialized
+to zero each time a new input file is started.
+
+@cindex @code{NF} variable
+@item NF
+The number of fields in the current input record.
+@code{NF} is set each time a new record is read, when a new field is
+created or when @code{$0} changes (@pxref{Fields}).
+
+Unlike most of the variables described in this
+@ifnotinfo
+section,
+@end ifnotinfo
+@ifinfo
+node,
+@end ifinfo
+assigning a value to @code{NF} has the potential to affect
+@command{awk}'s internal workings. In particular, assignments
+to @code{NF} can be used to create or remove fields from the
+current record: @xref{Changing Fields}.
+
+@cindex @code{NR} variable
+@item NR
+The number of input records @command{awk} has processed since
+the beginning of the program's execution
+(@pxref{Records}).
+@code{NR} is incremented each time a new record is read.
+
+@cindex @code{PROCINFO} array
+@cindex differences in @command{awk} and @command{gawk}, @code{PROCINFO} array
+@item PROCINFO #
+The elements of this array provide access to information about the
+running @command{awk} program.
+The following elements (listed alphabetically)
+are guaranteed to be available:
+
+@table @code
+@item PROCINFO["egid"]
+The value of the @code{getegid} system call.
+
+@item PROCINFO["euid"]
+The value of the @code{geteuid} system call.
+
+@item PROCINFO["FS"]
+This is
+@code{"FS"} if field splitting with @code{FS} is in effect, or it is
+@code{"FIELDWIDTHS"} if field splitting with @code{FIELDWIDTHS} is in effect.
+
+@item PROCINFO["gid"]
+The value of the @code{getgid} system call.
+
+@item PROCINFO["pgrpid"]
+The process group ID of the current process.
+
+@item PROCINFO["pid"]
+The process ID of the current process.
+
+@item PROCINFO["ppid"]
+The parent process ID of the current process.
+
+@item PROCINFO["uid"]
+The value of the @code{getuid} system call.
+
+@item PROCINFO["version"]
+The version of @command{gawk}. This is available from
+version 3.1.4 and later.
+@end table
+
+On some systems, there may be elements in the array, @code{"group1"}
+through @code{"group@var{N}"} for some @var{N}. @var{N} is the number of
+supplementary groups that the process has. Use the @code{in} operator
+to test for these elements
+(@pxref{Reference to Elements}).
+
+This array is a @command{gawk} extension.
+In other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+
+@cindex @code{RLENGTH} variable
+@item RLENGTH
+The length of the substring matched by the
+@code{match} function
+(@pxref{String Functions}).
+@code{RLENGTH} is set by invoking the @code{match} function. Its value
+is the length of the matched string, or @minus{}1 if no match is found.
+
+@cindex @code{RSTART} variable
+@item RSTART
+The start-index in characters of the substring that is matched by the
+@code{match} function
+(@pxref{String Functions}).
+@code{RSTART} is set by invoking the @code{match} function. Its value
+is the position of the string where the matched substring starts, or zero
+if no match was found.
+
+@cindex @code{RT} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{RT} variable
+@item RT #
+This is set each time a record is read. It contains the input text
+that matched the text denoted by @code{RS}, the record separator.
+
+This variable is a @command{gawk} extension.
+In other @command{awk} implementations,
+or if @command{gawk} is in compatibility mode
+(@pxref{Options}),
+it is not special.
+@end table
+@c ENDOFRANGE bvconi
+@c ENDOFRANGE vbconi
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Changing @code{NR} and @code{FNR}
+@cindex @code{NR} variable, changing
+@cindex @code{FNR} variable, changing
+@cindex advanced features, @code{FNR}/@code{NR} variables
+@cindex dark corner, @code{FNR}/@code{NR} variables
+@command{awk} increments @code{NR} and @code{FNR}
+each time it reads a record, instead of setting them to the absolute
+value of the number of records read. This means that a program can
+change these variables and their new values are incremented for
+each record.
+@value{DARKCORNER}
+This is demonstrated in the following example:
+
+@example
+$ echo '1
+> 2
+> 3
+> 4' | awk 'NR == 2 @{ NR = 17 @}
+> @{ print NR @}'
+@print{} 1
+@print{} 17
+@print{} 18
+@print{} 19
+@end example
+
+@noindent
+Before @code{FNR} was added to the @command{awk} language
+(@pxref{V7/SVR3.1}),
+many @command{awk} programs used this feature to track the number of
+records in a file by resetting @code{NR} to zero when @code{FILENAME}
+changed.
+
+@node ARGC and ARGV
+@subsection Using @code{ARGC} and @code{ARGV}
+@cindex @code{ARGC}/@code{ARGV} variables
+@cindex arguments, command-line
+@cindex command line, arguments
+
+@ref{Auto-set},
+presented the following program describing the information contained in @code{ARGC}
+and @code{ARGV}:
+
+@example
+$ awk 'BEGIN @{
+> for (i = 0; i < ARGC; i++)
+> print ARGV[i]
+> @}' inventory-shipped BBS-list
+@print{} awk
+@print{} inventory-shipped
+@print{} BBS-list
+@end example
+
+@noindent
+In this example, @code{ARGV[0]} contains @samp{awk}, @code{ARGV[1]}
+contains @samp{inventory-shipped}, and @code{ARGV[2]} contains
+@samp{BBS-list}.
+Notice that the @command{awk} program is not entered in @code{ARGV}. The
+other special command-line options, with their arguments, are also not
+entered. This includes variable assignments done with the @option{-v}
+option (@pxref{Options}).
+Normal variable assignments on the command line @emph{are}
+treated as arguments and do show up in the @code{ARGV} array:
+
+@example
+$ cat showargs.awk
+@print{} BEGIN @{
+@print{} printf "A=%d, B=%d\n", A, B
+@print{} for (i = 0; i < ARGC; i++)
+@print{} printf "\tARGV[%d] = %s\n", i, ARGV[i]
+@print{} @}
+@print{} END @{ printf "A=%d, B=%d\n", A, B @}
+$ awk -v A=1 -f showargs.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
+
+A program can alter @code{ARGC} and the elements of @code{ARGV}.
+Each time @command{awk} reaches the end of an input file, it uses the next
+element of @code{ARGV} as the name of the next input file. By storing a
+different string there, a program can change which files are read.
+Use @code{"-"} to represent the standard input. Storing
+additional elements and incrementing @code{ARGC} causes
+additional files to be read.
+
+If the value of @code{ARGC} is decreased, that eliminates input files
+from the end of the list. By recording the old value of @code{ARGC}
+elsewhere, a program can treat the eliminated arguments as
+something other than @value{FN}s.
+
+To eliminate a file from the middle of the list, store the null string
+(@code{""}) into @code{ARGV} in place of the file's name. As a
+special feature, @command{awk} ignores @value{FN}s that have been
+replaced with the null string.
+Another option is to
+use the @code{delete} statement to remove elements from
+@code{ARGV} (@pxref{Delete}).
+
+All of these actions are typically done in the @code{BEGIN} rule,
+before actual processing of the input begins.
+@xref{Split Program}, and see
+@ref{Tee Program}, for examples
+of each way of removing elements from @code{ARGV}.
+The following fragment processes @code{ARGV} in order to examine, and
+then remove, command-line options:
+@c NEXT ED: Add xref to rewind() function
+
+@example
+BEGIN @{
+ for (i = 1; i < ARGC; i++) @{
+ if (ARGV[i] == "-v")
+ verbose = 1
+ else if (ARGV[i] == "-d")
+ debug = 1
+ else if (ARGV[i] ~ /^-?/) @{
+ e = sprintf("%s: unrecognized option -- %c",
+ ARGV[0], substr(ARGV[i], 1, ,1))
+ print e > "/dev/stderr"
+ @} else
+ break
+ delete ARGV[i]
+ @}
+@}
+@end example
+
+To actually get the options into the @command{awk} program,
+end the @command{awk} options with @option{--} and then supply
+the @command{awk} program's options, in the following manner:
+
+@example
+awk -f myprog -- -v -d file1 file2 @dots{}
+@end example
+
+@cindex differences in @command{awk} and @command{gawk}, @code{ARGC}/@code{ARGV} variables
+This is not necessary in @command{gawk}. Unless @option{--posix} has
+been specified, @command{gawk} silently puts any unrecognized options
+into @code{ARGV} for the @command{awk} program to deal with. As soon
+as it sees an unknown option, @command{gawk} stops looking for other
+options that it might otherwise recognize. The previous example with
+@command{gawk} would be:
+
+@example
+gawk -f myprog -d -v file1 file2 @dots{}
+@end example
+
+@noindent
+Because @option{-d} is not a valid @command{gawk} option,
+it and the following @option{-v}
+are passed on to the @command{awk} program.
+
+@node Arrays
+@chapter Arrays in @command{awk}
+@c STARTOFRANGE arrs
+@cindex arrays
+
+An @dfn{array} is a table of values called @dfn{elements}. The
+elements of an array are distinguished by their indices. @dfn{Indices}
+may be either numbers or strings.
+
+This @value{CHAPTER} describes how arrays work in @command{awk},
+how to use array elements, how to scan through every element in an array,
+and how to remove array elements.
+It also describes how @command{awk} simulates multidimensional
+arrays, as well as some of the less obvious points about array usage.
+The @value{CHAPTER} finishes with a discussion of @command{gawk}'s facility
+for sorting an array based on its indices.
+
+@cindex variables, names of
+@cindex functions, names of
+@cindex arrays, names of
+@cindex names, arrays/variables
+@cindex namespace issues
+@command{awk} maintains a single set
+of names that may be used for naming variables, arrays, and functions
+(@pxref{User-defined}).
+Thus, you cannot have a variable and an array with the same name in the
+same @command{awk} program.
+
+@menu
+* Array Intro:: Introduction to Arrays
+* Reference to Elements:: How to examine one element of an array.
+* Assigning Elements:: How to change an element of an array.
+* Array Example:: Basic Example of an Array
+* Scanning an Array:: A variation of the @code{for} statement. It
+ loops through the indices of an array's
+ existing elements.
+* Delete:: The @code{delete} statement removes an element
+ from an array.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ @command{awk}.
+* Uninitialized Subscripts:: Using Uninitialized variables as subscripts.
+* Multi-dimensional:: Emulating multidimensional arrays in
+ @command{awk}.
+* Multi-scanning:: Scanning multidimensional arrays.
+* Array Sorting:: Sorting array values and indices.
+@end menu
+
+@node Array Intro
+@section Introduction to Arrays
+
+The @command{awk} language provides one-dimensional arrays
+for storing groups of related strings or numbers.
+Every @command{awk} array must have a name. Array names have the same
+syntax as variable names; any valid variable name would also be a valid
+array name. But one name cannot be used in both ways (as an array and
+as a variable) in the same @command{awk} program.
+
+Arrays in @command{awk} superficially resemble arrays in other programming
+languages, but there are fundamental differences. In @command{awk}, it
+isn't necessary to specify the size of an array before starting to use it.
+Additionally, any number or string in @command{awk}, not just consecutive integers,
+may be used as an array index.
+
+In most other languages, arrays must be @dfn{declared} before use,
+including a specification of
+how many elements or components they contain. In such languages, the
+declaration causes a contiguous block of memory to be allocated for that
+many elements. Usually, an index in the array must be a positive integer.
+For example, the index zero specifies the first element in the array, which is
+actually stored at the beginning of the block of memory. Index one
+specifies the second element, which is stored in memory right after the
+first element, and so on. It is impossible to add more elements to the
+array, because it has room only for as many elements as given in
+the declaration.
+(Some languages allow arbitrary starting and ending
+indices---e.g., @samp{15 .. 27}---but the size of the array is still fixed when
+the array is declared.)
+
+A contiguous array of four elements might look like the following example,
+conceptually, if the element values are 8, @code{"foo"},
+@code{""}, and 30:
+
+@c NEXT ED: Use real images here
+@iftex
+@c from Karl Berry, much thanks for the help.
+@tex
+\bigskip % space above the table (about 1 linespace)
+\offinterlineskip
+\newdimen\width \width = 1.5cm
+\newdimen\hwidth \hwidth = 4\width \advance\hwidth by 2pt % 5 * 0.4pt
+\centerline{\vbox{
+\halign{\strut\hfil\ignorespaces#&&\vrule#&\hbox to\width{\hfil#\unskip\hfil}\cr
+\noalign{\hrule width\hwidth}
+ &&{\tt 8} &&{\tt "foo"} &&{\tt ""} &&{\tt 30} &&\quad Value\cr
+\noalign{\hrule width\hwidth}
+\noalign{\smallskip}
+ &\omit&0&\omit &1 &\omit&2 &\omit&3 &\omit&\quad Index\cr
+}
+}}
+@end tex
+@end iftex
+@ifinfo
+@example
++---------+---------+--------+---------+
+| 8 | "foo" | "" | 30 | @r{Value}
++---------+---------+--------+---------+
+ 0 1 2 3 @r{Index}
+@end example
+@end ifinfo
+@ifxml
+@example
++---------+---------+--------+---------+
+| 8 | "foo" | "" | 30 | @r{Value}
++---------+---------+--------+---------+
+ 0 1 2 3 @r{Index}
+@end example
+@end ifxml
+
+@noindent
+Only the values are stored; the indices are implicit from the order of
+the values. Here, 8 is the value at index zero, because 8 appears in the
+position with zero elements before it.
+
+@c STARTOFRANGE arrin
+@cindex arrays, indexing
+@c STARTOFRANGE inarr
+@cindex indexing arrays
+@cindex associative arrays
+@cindex arrays, associative
+Arrays in @command{awk} are different---they are @dfn{associative}. This means
+that each array is a collection of pairs: an index and its corresponding
+array element value:
+
+@example
+@r{Element} 3 @r{Value} 30
+@r{Element} 1 @r{Value} "foo"
+@r{Element} 0 @r{Value} 8
+@r{Element} 2 @r{Value} ""
+@end example
+
+@noindent
+The pairs are shown in jumbled order because their order is irrelevant.
+
+One advantage of associative arrays is that new pairs can be added
+at any time. For example, suppose a tenth element is added to the array
+whose value is @w{@code{"number ten"}}. The result is:
+
+@example
+@r{Element} 10 @r{Value} "number ten"
+@r{Element} 3 @r{Value} 30
+@r{Element} 1 @r{Value} "foo"
+@r{Element} 0 @r{Value} 8
+@r{Element} 2 @r{Value} ""
+@end example
+
+@noindent
+@cindex sparse arrays
+@cindex arrays, sparse
+Now the array is @dfn{sparse}, which just means some indices are missing.
+It has elements 0--3 and 10, but doesn't have elements 4, 5, 6, 7, 8, or 9.
+
+Another consequence of associative arrays is that the indices don't
+have to be positive integers. Any number, or even a string, can be
+an index. For example, the following is an array that translates words from
+English to French:
+
+@example
+@r{Element} "dog" @r{Value} "chien"
+@r{Element} "cat" @r{Value} "chat"
+@r{Element} "one" @r{Value} "un"
+@r{Element} 1 @r{Value} "un"
+@end example
+
+@noindent
+Here we decided to translate the number one in both spelled-out and
+numeric form---thus illustrating that a single array can have both
+numbers and strings as indices.
+In fact, array subscripts are always strings; this is discussed
+in more detail in
+@ref{Numeric Array Subscripts}.
+Here, the number @code{1} isn't double-quoted, since @command{awk}
+automatically converts it to a string.
+
+@cindex case sensitivity, array indices and
+@cindex arrays, @code{IGNORECASE} variable and
+@cindex @code{IGNORECASE} variable, array subscripts and
+The value of @code{IGNORECASE} has no effect upon array subscripting.
+The identical string value used to store an array element must be used
+to retrieve it.
+When @command{awk} creates an array (e.g., with the @code{split}
+built-in function),
+that array's indices are consecutive integers starting at one.
+(@xref{String Functions}.)
+
+@command{awk}'s arrays are efficient---the time to access an element
+is independent of the number of elements in the array.
+@c ENDOFRANGE arrin
+@c ENDOFRANGE inarr
+
+@node Reference to Elements
+@section Referring to an Array Element
+@cindex arrays, elements, referencing
+@cindex elements in arrays
+
+The principal way to use an array is to refer to one of its elements.
+An array reference is an expression as follows:
+
+@example
+@var{array}[@var{index}]
+@end example
+
+@noindent
+Here, @var{array} is the name of an array. The expression @var{index} is
+the index of the desired element of the array.
+
+The value of the array reference is the current value of that array
+element. For example, @code{foo[4.3]} is an expression for the element
+of array @code{foo} at index @samp{4.3}.
+
+A reference to an array element that has no recorded value yields a value of
+@code{""}, the null string. This includes elements
+that have not been assigned any value as well as elements that have been
+deleted (@pxref{Delete}). Such a reference
+automatically creates that array element, with the null string as its value.
+(In some cases, this is unfortunate, because it might waste memory inside
+@command{awk}.)
+
+@c @cindex arrays, @code{in} operator and
+@cindex @code{in} operator, arrays and
+To determine whether an element exists in an array at a certain index, use
+the following expression:
+
+@example
+@var{index} in @var{array}
+@end example
+
+@cindex side effects, array indexing
+@noindent
+This expression tests whether the particular index exists,
+without the side effect of creating that element if it is not present.
+The expression has the value one (true) if @code{@var{array}[@var{index}]}
+exists and zero (false) if it does not exist.
+For example, this statement tests whether the array @code{frequencies}
+contains the index @samp{2}:
+
+@example
+if (2 in frequencies)
+ print "Subscript 2 is present."
+@end example
+
+Note that this is @emph{not} a test of whether the array
+@code{frequencies} contains an element whose @emph{value} is two.
+There is no way to do that except to scan all the elements. Also, this
+@emph{does not} create @code{frequencies[2]}, while the following
+(incorrect) alternative does:
+
+@example
+if (frequencies[2] != "")
+ print "Subscript 2 is present."
+@end example
+
+@node Assigning Elements
+@section Assigning Array Elements
+@cindex arrays, elements, assigning
+@cindex elements in arrays, assigning
+
+Array elements can be assigned values just like
+@command{awk} variables:
+
+@example
+@var{array}[@var{subscript}] = @var{value}
+@end example
+
+@noindent
+@var{array} is the name of an array. The expression
+@var{subscript} is the index of the element of the array that is
+assigned a value. The expression @var{value} is the value to
+assign to that element of the array.
+
+@node Array Example
+@section Basic Array Example
+
+The following program takes a list of lines, each beginning with a line
+number, and prints them out in order of line number. The line numbers
+are not in order when they are first read---instead they
+are scrambled. This program sorts the lines by making an array using
+the line numbers as subscripts. The program then prints out the lines
+in sorted order of their numbers. It is a very simple program and gets
+confused upon encountering repeated numbers, gaps, or lines that don't
+begin with a number:
+
+@example
+@c file eg/misc/arraymax.awk
+@{
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
+@}
+
+END @{
+ for (x = 1; x <= max; x++)
+ print arr[x]
+@}
+@c endfile
+@end example
+
+The first rule keeps track of the largest line number seen so far;
+it also stores each line into the array @code{arr}, at an index that
+is the line's number.
+The second rule runs after all the input has been read, to print out
+all the lines.
+When this program is run with the following input:
+
+@example
+@c file eg/misc/arraymax.data
+5 I am the Five man
+2 Who are you? The new number two!
+4 . . . And four on the floor
+1 Who is number one?
+3 I three you.
+@c endfile
+@end example
+
+@noindent
+Its output is:
+
+@example
+1 Who is number one?
+2 Who are you? The new number two!
+3 I three you.
+4 . . . And four on the floor
+5 I am the Five man
+@end example
+
+If a line number is repeated, the last line with a given number overrides
+the others.
+Gaps in the line numbers can be handled with an easy improvement to the
+program's @code{END} rule, as follows:
+
+@example
+END @{
+ for (x = 1; x <= max; x++)
+ if (x in arr)
+ print arr[x]
+@}
+@end example
+
+@node Scanning an Array
+@section Scanning All Elements of an Array
+@cindex elements in arrays, scanning
+@cindex arrays, scanning
+
+In programs that use arrays, it is often necessary to use a loop that
+executes once for each element of an array. In other languages, where
+arrays are contiguous and indices are limited to positive integers,
+this is easy: all the valid indices can be found by counting from
+the lowest index up to the highest. This technique won't do the job
+in @command{awk}, because any number or string can be an array index.
+So @command{awk} has a special kind of @code{for} statement for scanning
+an array:
+
+@example
+for (@var{var} in @var{array})
+ @var{body}
+@end example
+
+@noindent
+@cindex @code{in} operator, arrays and
+This loop executes @var{body} once for each index in @var{array} that the
+program has previously used, with the variable @var{var} set to that index.
+
+@cindex arrays, @code{for} statement and
+@cindex @code{for} statement, in arrays
+The following program uses this form of the @code{for} statement. The
+first rule scans the input records and notes which words appear (at
+least once) in the input, by storing a one into the array @code{used} with
+the word as index. The second rule scans the elements of @code{used} to
+find all the distinct words that appear in the input. It prints each
+word that is more than 10 characters long and also prints the number of
+such words.
+@xref{String Functions},
+for more information on the built-in function @code{length}.
+
+@example
+# Record a 1 for each word that is used at least once
+@{
+ for (i = 1; i <= NF; i++)
+ used[$i] = 1
+@}
+
+# Find number of distinct words more than 10 characters long
+END @{
+ for (x in used)
+ if (length(x) > 10) @{
+ ++num_long_words
+ print x
+ @}
+ print num_long_words, "words longer than 10 characters"
+@}
+@end example
+
+@noindent
+@xref{Word Sorting},
+for a more detailed example of this type.
+
+@cindex arrays, elements, order of
+@cindex elements in arrays, order of
+The order in which elements of the array are accessed by this statement
+is determined by the internal arrangement of the array elements within
+@command{awk} and cannot be controlled or changed. This can lead to
+problems if new elements are added to @var{array} by statements in
+the loop body; it is not predictable whether the @code{for} loop will
+reach them. Similarly, changing @var{var} inside the loop may produce
+strange results. It is best to avoid such things.
+
+@node Delete
+@section The @code{delete} Statement
+@cindex @code{delete} statement
+@cindex deleting elements in arrays
+@cindex arrays, elements, deleting
+@cindex elements in arrays, deleting
+
+To remove an individual element of an array, use the @code{delete}
+statement:
+
+@example
+delete @var{array}[@var{index}]
+@end example
+
+Once an array element has been deleted, any value the element once
+had is no longer available. It is as if the element had never
+been referred to or had been given a value.
+The following is an example of deleting elements in an array:
+
+@example
+for (i in frequencies)
+ delete frequencies[i]
+@end example
+
+@noindent
+This example removes all the elements from the array @code{frequencies}.
+Once an element is deleted, a subsequent @code{for} statement to scan the array
+does not report that element and the @code{in} operator to check for
+the presence of that element returns zero (i.e., false):
+
+@example
+delete foo[4]
+if (4 in foo)
+ print "This will never be printed"
+@end example
+
+@cindex null strings, array elements and
+It is important to note that deleting an element is @emph{not} the
+same as assigning it a null value (the empty string, @code{""}).
+For example:
+
+@example
+foo[4] = ""
+if (4 in foo)
+ print "This is printed, even though foo[4] is empty"
+@end example
+
+@cindex lint checking, array elements
+It is not an error to delete an element that does not exist.
+If @option{--lint} is provided on the command line
+(@pxref{Options}),
+@command{gawk} issues a warning message when an element that
+is not in the array is deleted.
+
+@cindex arrays, deleting entire contents
+@cindex deleting entire arrays
+@cindex differences in @command{awk} and @command{gawk}, array elements, deleting
+All the elements of an array may be deleted with a single statement
+by leaving off the subscript in the @code{delete} statement,
+as follows:
+
+@example
+delete @var{array}
+@end example
+
+This ability is a @command{gawk} extension; it is not available in
+compatibility mode (@pxref{Options}).
+
+Using this version of the @code{delete} statement is about three times
+more efficient than the equivalent loop that deletes each element one
+at a time.
+
+@cindex portability, deleting array elements
+@cindex Brennan, Michael
+The following statement provides a portable but nonobvious way to clear
+out an array:@footnote{Thanks to Michael Brennan for pointing this out.}
+
+@example
+split("", array)
+@end example
+
+@cindex @code{split} function, array elements@comma{} deleting
+The @code{split} function
+(@pxref{String Functions})
+clears out the target array first. This call asks it to split
+apart the null string. Because there is no data to split out, the
+function simply clears the array and then returns.
+
+@strong{Caution:} Deleting an array does not change its type; you cannot
+delete an array and then use the array's name as a scalar
+(i.e., a regular variable). For example, the following does not work:
+
+@example
+a[1] = 3; delete a; a = 3
+@end example
+
+@node Numeric Array Subscripts
+@section Using Numbers to Subscript Arrays
+
+@cindex numbers, as array subscripts
+@cindex arrays, subscripts
+@cindex subscripts in arrays, numbers as
+@cindex @code{CONVFMT} variable, array subscripts and
+An important aspect about arrays to remember is that @emph{array subscripts
+are always strings}. When a numeric value is used as a subscript,
+it is converted to a string value before being used for subscripting
+(@pxref{Conversion}).
+This means that the value of the built-in variable @code{CONVFMT} can
+affect how your program accesses elements of an array. For example:
+
+@example
+xyz = 12.153
+data[xyz] = 1
+CONVFMT = "%2.2f"
+if (xyz in data)
+ printf "%s is in data\n", xyz
+else
+ printf "%s is not in data\n", xyz
+@end example
+
+@noindent
+This prints @samp{12.15 is not in data}. The first statement gives
+@code{xyz} a numeric value. Assigning to
+@code{data[xyz]} subscripts @code{data} with the string value @code{"12.153"}
+(using the default conversion value of @code{CONVFMT}, @code{"%.6g"}).
+Thus, the array element @code{data["12.153"]} is assigned the value one.
+The program then changes
+the value of @code{CONVFMT}. The test @samp{(xyz in data)} generates a new
+string value from @code{xyz}---this time @code{"12.15"}---because the value of
+@code{CONVFMT} only allows two significant digits. This test fails,
+since @code{"12.15"} is a different string from @code{"12.153"}.
+
+@cindex converting, during subscripting
+According to the rules for conversions
+(@pxref{Conversion}), integer
+values are always converted to strings as integers, no matter what the
+value of @code{CONVFMT} may happen to be. So the usual case of
+the following works:
+
+@example
+for (i = 1; i <= maxsub; i++)
+ @i{do something with} array[i]
+@end example
+
+The ``integer values always convert to strings as integers'' rule
+has an additional consequence for array indexing.
+Octal and hexadecimal constants
+(@pxref{Nondecimal-numbers})
+are converted internally into numbers, and their original form
+is forgotten.
+This means, for example, that
+@code{array[17]},
+@code{array[021]},
+and
+@code{array[0x11]}
+all refer to the same element!
+
+As with many things in @command{awk}, the majority of the time
+things work as one would expect them to. But it is useful to have a precise
+knowledge of the actual rules which sometimes can have a subtle
+effect on your programs.
+
+@node Uninitialized Subscripts
+@section Using Uninitialized Variables as Subscripts
+
+@cindex variables, uninitialized@comma{} as array subscripts
+@cindex uninitialized variables, as array subscripts
+@cindex subscripts in arrays, uninitialized variables as
+@cindex arrays, subscripts, uninitialized variables as
+Suppose it's necessary to write a program
+to print the input data in reverse order.
+A reasonable attempt to do so (with some test
+data) might look like this:
+
+@example
+$ echo 'line 1
+> line 2
+> line 3' | awk '@{ l[lines] = $0; ++lines @}
+> END @{
+> for (i = lines-1; i >= 0; --i)
+> print l[i]
+> @}'
+@print{} line 3
+@print{} line 2
+@end example
+
+Unfortunately, the very first line of input data did not come out in the
+output!
+
+At first glance, this program should have worked. The variable @code{lines}
+is uninitialized, and uninitialized variables have the numeric value zero.
+So, @command{awk} should have printed the value of @code{l[0]}.
+
+The issue here is that subscripts for @command{awk} arrays are @emph{always}
+strings. Uninitialized variables, when used as strings, have the
+value @code{""}, not zero. Thus, @samp{line 1} ends up stored in
+@code{l[""]}.
+The following version of the program works correctly:
+
+@example
+@{ l[lines++] = $0 @}
+END @{
+ for (i = lines - 1; i >= 0; --i)
+ print l[i]
+@}
+@end example
+
+Here, the @samp{++} forces @code{lines} to be numeric, thus making
+the ``old value'' numeric zero. This is then converted to @code{"0"}
+as the array subscript.
+
+@cindex null strings, as array subscripts
+@cindex dark corner, array subscripts
+@cindex lint checking, array subscripts
+Even though it is somewhat unusual, the null string
+(@code{""}) is a valid array subscript.
+@value{DARKCORNER}
+@command{gawk} warns about the use of the null string as a subscript
+if @option{--lint} is provided
+on the command line (@pxref{Options}).
+
+@node Multi-dimensional
+@section Multidimensional Arrays
+
+@cindex subscripts in arrays, multidimensional
+@cindex arrays, multidimensional
+A multidimensional array is an array in which an element is identified
+by a sequence of indices instead of a single index. For example, a
+two-dimensional array requires two indices. The usual way (in most
+languages, including @command{awk}) to refer to an element of a
+two-dimensional array named @code{grid} is with
+@code{grid[@var{x},@var{y}]}.
+
+@cindex @code{SUBSEP} variable, multidimensional arrays
+Multidimensional arrays are supported in @command{awk} through
+concatenation of indices into one string.
+@command{awk} converts the indices into strings
+(@pxref{Conversion}) and
+concatenates them together, with a separator between them. This creates
+a single string that describes the values of the separate indices. The
+combined string is used as a single index into an ordinary,
+one-dimensional array. The separator used is the value of the built-in
+variable @code{SUBSEP}.
+
+For example, suppose we evaluate the expression @samp{foo[5,12] = "value"}
+when the value of @code{SUBSEP} is @code{"@@"}. The numbers 5 and 12 are
+converted to strings and
+concatenated with an @samp{@@} between them, yielding @code{"5@@12"}; thus,
+the array element @code{foo["5@@12"]} is set to @code{"value"}.
+
+Once the element's value is stored, @command{awk} has no record of whether
+it was stored with a single index or a sequence of indices. The two
+expressions @samp{foo[5,12]} and @w{@samp{foo[5 SUBSEP 12]}} are always
+equivalent.
+
+The default value of @code{SUBSEP} is the string @code{"\034"},
+which contains a nonprinting character that is unlikely to appear in an
+@command{awk} program or in most input data.
+The usefulness of choosing an unlikely character comes from the fact
+that index values that contain a string matching @code{SUBSEP} can lead to
+combined strings that are ambiguous. Suppose that @code{SUBSEP} is
+@code{"@@"}; then @w{@samp{foo["a@@b", "c"]}} and @w{@samp{foo["a",
+"b@@c"]}} are indistinguishable because both are actually
+stored as @samp{foo["a@@b@@c"]}.
+
+To test whether a particular index sequence exists in a
+multidimensional array, use the same operator (@samp{in}) that is
+used for single dimensional arrays. Write the whole sequence of indices
+in parentheses, separated by commas, as the left operand:
+
+@example
+(@var{subscript1}, @var{subscript2}, @dots{}) in @var{array}
+@end example
+
+The following example treats its input as a two-dimensional array of
+fields; it rotates this array 90 degrees clockwise and prints the
+result. It assumes that all lines have the same number of
+elements:
+
+@example
+@{
+ if (max_nf < NF)
+ max_nf = NF
+ max_nr = NR
+ for (x = 1; x <= NF; x++)
+ vector[x, NR] = $x
+@}
+
+END @{
+ for (x = 1; x <= max_nf; x++) @{
+ for (y = max_nr; y >= 1; --y)
+ printf("%s ", vector[x, y])
+ printf("\n")
+ @}
+@}
+@end example
+
+@noindent
+When given the 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
+the program produces the following 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 Multi-scanning
+@section Scanning Multidimensional Arrays
+
+There is no special @code{for} statement for scanning a
+``multidimensional'' array. There cannot be one, because, in truth, there
+are no multidimensional arrays or elements---there is only a
+multidimensional @emph{way of accessing} an array.
+
+@cindex subscripts in arrays, multidimensional, scanning
+@cindex arrays, multidimensional, scanning
+However, if your program has an array that is always accessed as
+multidimensional, you can get the effect of scanning it by combining
+the scanning @code{for} statement
+(@pxref{Scanning an Array}) with the
+built-in @code{split} function
+(@pxref{String Functions}).
+It works in the following manner:
+
+@example
+for (combined in array) @{
+ split(combined, separate, SUBSEP)
+ @dots{}
+@}
+@end example
+
+@noindent
+This sets the variable @code{combined} to
+each concatenated combined index in the array, and splits it
+into the individual indices by breaking it apart where the value of
+@code{SUBSEP} appears. The individual indices then become the elements of
+the array @code{separate}.
+
+Thus, if a value is previously stored in @code{array[1, "foo"]}; then
+an element with index @code{"1\034foo"} exists in @code{array}. (Recall
+that the default value of @code{SUBSEP} is the character with code 034.)
+Sooner or later, the @code{for} statement finds that index and does an
+iteration with the variable @code{combined} set to @code{"1\034foo"}.
+Then the @code{split} function is called as follows:
+
+@example
+split("1\034foo", separate, "\034")
+@end example
+
+@noindent
+The result is to set @code{separate[1]} to @code{"1"} and
+@code{separate[2]} to @code{"foo"}. Presto! The original sequence of
+separate indices is recovered.
+
+@node Array Sorting
+@section Sorting Array Values and Indices with @command{gawk}
+
+@cindex arrays, sorting
+@cindex @code{asort} function (@command{gawk})
+@cindex @code{asort} function (@command{gawk}), arrays@comma{} sorting
+@cindex sort function, arrays, sorting
+The order in which an array is scanned with a @samp{for (i in array)}
+loop is essentially arbitrary.
+In most @command{awk} implementations, sorting an array requires
+writing a @code{sort} function.
+While this can be educational for exploring different sorting algorithms,
+usually that's not the point of the program.
+@command{gawk} provides the built-in @code{asort}
+and @code{asorti} functions
+(@pxref{String Functions})
+for sorting arrays. For example:
+
+@example
+@var{populate the array} data
+n = asort(data)
+for (i = 1; i <= n; i++)
+ @var{do something with} data[i]
+@end example
+
+After the call to @code{asort}, the array @code{data} is indexed from 1
+to some number @var{n}, the total number of elements in @code{data}.
+(This count is @code{asort}'s return value.)
+@code{data[1]} @value{LEQ} @code{data[2]} @value{LEQ} @code{data[3]}, and so on.
+The comparison of array elements is done
+using @command{gawk}'s usual comparison rules
+(@pxref{Typing and Comparison}).
+
+@cindex side effects, @code{asort} function
+An important side effect of calling @code{asort} is that
+@emph{the array's original indices are irrevocably lost}.
+As this isn't always desirable, @code{asort} accepts a
+second argument:
+
+@example
+@var{populate the array} source
+n = asort(source, dest)
+for (i = 1; i <= n; i++)
+ @var{do something with} dest[i]
+@end example
+
+In this case, @command{gawk} copies the @code{source} array into the
+@code{dest} array and then sorts @code{dest}, destroying its indices.
+However, the @code{source} array is not affected.
+
+Often, what's needed is to sort on the values of the @emph{indices}
+instead of the values of the elements.
+To do that, starting with @command{gawk} 3.1.2, use the
+@code{asorti} function. The interface is identical to that of
+@code{asort}, except that the index values are used for sorting, and
+become the values of the result array:
+
+@example
+@{ source[$0] = some_func($0) @}
+
+END @{
+ n = asorti(source, dest)
+ for (i = 1; i <= n; i++) @{
+ @var{do something with} dest[i] @i{Work with sorted indices directly}
+ @dots{}
+ @var{do something with} source[dest[i]] @i{Access original array via sorted indices}
+ @}
+@}
+@end example
+
+If your version of @command{gawk} is 3.1.0 or 3.1.1, you don't
+have @code{asorti}. Instead, use a helper array
+to hold the sorted index values, and then access the original array's
+elements. It works in the following way:
+
+@example
+@var{populate the array} data
+# copy indices
+j = 1
+for (i in data) @{
+ ind[j] = i # index value becomes element value
+ j++
+@}
+n = asort(ind) # index values are now sorted
+for (i = 1; i <= n; i++) @{
+ @var{do something with} ind[i] @i{Work with sorted indices directly}
+ @dots{}
+ @var{do something with} data[ind[i]] @i{Access original array via sorted indices}
+@}
+@end example
+
+Sorting the array by replacing the indices provides maximal flexibility.
+To traverse the elements in decreasing order, use a loop that goes from
+@var{n} down to 1, either over the elements or over the indices.
+
+@cindex reference counting, sorting arrays
+Copying array indices and elements isn't expensive in terms of memory.
+Internally, @command{gawk} maintains @dfn{reference counts} to data.
+For example, when @code{asort} copies the first array to the second one,
+there is only one copy of the original array elements' data, even though
+both arrays use the values. Similarly, when copying the indices from
+@code{data} to @code{ind}, there is only one copy of the actual index
+strings.
+
+@c Document It And Call It A Feature. Sigh.
+@cindex arrays, sorting, @code{IGNORECASE} variable and
+@cindex @code{IGNORECASE} variable, array sorting and
+We said previously that comparisons are done using @command{gawk}'s
+``usual comparison rules.'' Because @code{IGNORECASE} affects
+string comparisons, the value of @code{IGNORECASE} also
+affects sorting for both @code{asort} and @code{asorti}.
+Caveat Emptor.
+@c ENDOFRANGE arrs
+
+@node Functions
+@chapter Functions
+
+@c STARTOFRANGE funcbi
+@cindex functions, built-in
+@c STARTOFRANGE bifunc
+@cindex built-in functions
+This @value{CHAPTER} describes @command{awk}'s built-in functions,
+which fall into three categories: numeric, string, and I/O.
+@command{gawk} provides additional groups of functions
+to work with values that represent time, do
+bit manipulation, and internationalize and localize programs.
+
+Besides the built-in functions, @command{awk} has provisions for
+writing new functions that the rest of a program can use.
+The second half of this @value{CHAPTER} describes these
+@dfn{user-defined} functions.
+
+@menu
+* Built-in:: Summarizes the built-in functions.
+* User-defined:: Describes User-defined functions in detail.
+@end menu
+
+@node Built-in
+@section Built-in Functions
+
+@c 2e: USE TEXINFO-2 FUNCTION DEFINITION STUFF!!!!!!!!!!!!!
+@dfn{Built-in} functions are always available for
+your @command{awk} program to call. This @value{SECTION} defines all
+the built-in
+functions in @command{awk}; some of these are mentioned in other sections
+but are summarized here for your convenience.
+
+@menu
+* Calling Built-in:: How to call built-in functions.
+* Numeric Functions:: Functions that work with numbers, including
+ @code{int}, @code{sin} and @code{rand}.
+* String Functions:: Functions for string manipulation, such as
+ @code{split}, @code{match} and @code{sprintf}.
+* I/O Functions:: Functions for files and shell commands.
+* Time Functions:: Functions for dealing with timestamps.
+* Bitwise Functions:: Functions for bitwise operations.
+* I18N Functions:: Functions for string translation.
+@end menu
+
+@node Calling Built-in
+@subsection Calling Built-in Functions
+
+To call one of @command{awk}'s built-in functions, write the name of
+the function followed
+by arguments in parentheses. For example, @samp{atan2(y + z, 1)}
+is a call to the function @code{atan2} and has two arguments.
+
+@cindex programming conventions, functions, calling
+@cindex whitespace, functions@comma{} calling
+Whitespace is ignored between the built-in function name and the
+open parenthesis, and it is good practice to avoid using whitespace
+there. User-defined functions do not permit whitespace in this way, and
+it is easier to avoid mistakes by following a simple
+convention that always works---no whitespace after a function name.
+
+@cindex troubleshooting, @command{gawk}, fatal errors@comma{} function arguments
+@cindex @command{gawk}, function arguments and
+@cindex differences in @command{awk} and @command{gawk}, function arguments (@command{gawk})
+Each built-in function accepts a certain number of arguments.
+In some cases, arguments can be omitted. The defaults for omitted
+arguments vary from function to function and are described under the
+individual functions. In some @command{awk} implementations, extra
+arguments given to built-in functions are ignored. However, in @command{gawk},
+it is a fatal error to give extra arguments to a built-in function.
+
+When a function is called, expressions that create the function's actual
+parameters are evaluated completely before the call is performed.
+For example, in the following code fragment:
+
+@example
+i = 4
+j = sqrt(i++)
+@end example
+
+@cindex evaluation order, functions
+@cindex functions, built-in, evaluation order
+@cindex built-in functions, evaluation order
+@noindent
+the variable @code{i} is incremented to the value five before @code{sqrt}
+is called with a value of four for its actual parameter.
+The order of evaluation of the expressions used for the function's
+parameters is undefined. Thus, avoid writing programs that
+assume that parameters are evaluated from left to right or from
+right to left. For example:
+
+@example
+i = 5
+j = atan2(i++, i *= 2)
+@end example
+
+If the order of evaluation is left to right, then @code{i} first becomes
+6, and then 12, and @code{atan2} is called with the two arguments 6
+and 12. But if the order of evaluation is right to left, @code{i}
+first becomes 10, then 11, and @code{atan2} is called with the
+two arguments 11 and 10.
+
+@node Numeric Functions
+@subsection Numeric Functions
+
+The following list describes all of
+the built-in functions that work with numbers.
+Optional parameters are enclosed in square brackets@w{ ([ ]):}
+
+@table @code
+@item int(@var{x})
+@cindex @code{int} function
+This returns the nearest integer to @var{x}, located between @var{x} and zero and
+truncated toward zero.
+
+For example, @code{int(3)} is 3, @code{int(3.9)} is 3, @code{int(-3.9)}
+is @minus{}3, and @code{int(-3)} is @minus{}3 as well.
+
+@item sqrt(@var{x})
+@cindex @code{sqrt} function
+This returns the positive square root of @var{x}.
+@command{gawk} reports an error
+if @var{x} is negative. Thus, @code{sqrt(4)} is 2.
+
+@item exp(@var{x})
+@cindex @code{exp} function
+This returns the exponential of @var{x} (@code{e ^ @var{x}}) or reports
+an error if @var{x} is out of range. The range of values @var{x} can have
+depends on your machine's floating-point representation.
+
+@item log(@var{x})
+@cindex @code{log} function
+This returns the natural logarithm of @var{x}, if @var{x} is positive;
+otherwise, it reports an error.
+
+@item sin(@var{x})
+@cindex @code{sin} function
+This returns the sine of @var{x}, with @var{x} in radians.
+
+@item cos(@var{x})
+@cindex @code{cos} function
+This returns the cosine of @var{x}, with @var{x} in radians.
+
+@item atan2(@var{y}, @var{x})
+@cindex @code{atan2} function
+This returns the arctangent of @code{@var{y} / @var{x}} in radians.
+
+@item rand()
+@cindex @code{rand} function
+@cindex random numbers, @code{rand}/@code{srand} functions
+This returns a random number. The values of @code{rand} are
+uniformly distributed between zero and one.
+The value could be zero but is never one.@footnote{The C version of @code{rand}
+is known to produce fairly poor sequences of random numbers.
+However, nothing requires that an @command{awk} implementation use the C
+@code{rand} to implement the @command{awk} version of @code{rand}.
+In fact, @command{gawk} uses the BSD @code{random} function, which is
+considerably better than @code{rand}, to produce random numbers.}
+
+Often random integers are needed instead. Following is a user-defined function
+that can be used to obtain a random non-negative integer less than @var{n}:
+
+@example
+function randint(n) @{
+ return int(n * rand())
+@}
+@end example
+
+@noindent
+The multiplication produces a random number greater than zero and less
+than @code{n}. Using @code{int}, this result is made into
+an integer between zero and @code{n} @minus{} 1, inclusive.
+
+The following example uses a similar function to produce random integers
+between one and @var{n}. This program prints a new random number for
+each input record:
+
+@example
+# Function to roll a simulated die.
+function roll(n) @{ return 1 + int(rand() * n) @}
+
+# Roll 3 six-sided dice and
+# print total number of points.
+@{
+ printf("%d points\n",
+ roll(6)+roll(6)+roll(6))
+@}
+@end example
+
+@cindex numbers, random
+@cindex random numbers, seed of
+@c MAWK uses a different seed each time.
+@strong{Caution:} In most @command{awk} implementations, including @command{gawk},
+@code{rand} starts generating numbers from the same
+starting number, or @dfn{seed}, each time you run @command{awk}. Thus,
+a program generates the same results each time you run it.
+The numbers are random within one @command{awk} run but predictable
+from run to run. This is convenient for debugging, but if you want
+a program to do different things each time it is used, you must change
+the seed to a value that is different in each run. To do this,
+use @code{srand}.
+
+@item srand(@r{[}@var{x}@r{]})
+@cindex @code{srand} function
+The function @code{srand} sets the starting point, or seed,
+for generating random numbers to the value @var{x}.
+
+Each seed value leads to a particular sequence of random
+numbers.@footnote{Computer-generated random numbers really are not truly
+random. They are technically known as ``pseudorandom.'' This means
+that while the numbers in a sequence appear to be random, you can in
+fact generate the same sequence of random numbers over and over again.}
+Thus, if the seed is set to the same value a second time,
+the same sequence of random numbers is produced again.
+
+Different @command{awk} implementations use different random-number
+generators internally. Don't expect the same @command{awk} program
+to produce the same series of random numbers when executed by
+different versions of @command{awk}.
+
+If the argument @var{x} is omitted, as in @samp{srand()}, then the current
+date and time of day are used for a seed. This is the way to get random
+numbers that are truly unpredictable.
+
+The return value of @code{srand} is the previous seed. This makes it
+easy to keep track of the seeds in case you need to consistently reproduce
+sequences of random numbers.
+@end table
+
+@node String Functions
+@subsection String-Manipulation Functions
+
+The functions in this @value{SECTION} look at or change the text of one or more
+strings.
+Optional parameters are enclosed in square brackets@w{ ([ ]).}
+Those functions that are
+specific to @command{gawk} are marked with a pound sign@w{ (@samp{#}):}
+
+@menu
+* Gory Details:: More than you want to know about @samp{\} and
+ @samp{&} with @code{sub}, @code{gsub}, and
+ @code{gensub}.
+@end menu
+
+@table @code
+@item asort(@var{source} @r{[}, @var{dest}@r{]}) #
+@cindex arrays, elements, retrieving number of
+@cindex @code{asort} function (@command{gawk})
+@code{asort} is a @command{gawk}-specific extension, returning the number of
+elements in the array @var{source}. The contents of @var{source} are
+sorted using @command{gawk}'s normal rules for comparing values
+(in particular, @code{IGNORECASE} affects the sorting)
+and the indices
+of the sorted values of @var{source} are replaced with sequential
+integers starting with one. If the optional array @var{dest} is specified,
+then @var{source} is duplicated into @var{dest}. @var{dest} is then
+sorted, leaving the indices of @var{source} unchanged.
+For example, if the contents of @code{a} are as follows:
+
+@example
+a["last"] = "de"
+a["first"] = "sac"
+a["middle"] = "cul"
+@end example
+
+@noindent
+A call to @code{asort}:
+
+@example
+asort(a)
+@end example
+
+@noindent
+results in the following contents of @code{a}:
+
+@example
+a[1] = "cul"
+a[2] = "de"
+a[3] = "sac"
+@end example
+
+The @code{asort} function is described in more detail in
+@ref{Array Sorting}.
+@code{asort} is a @command{gawk} extension; it is not available
+in compatibility mode (@pxref{Options}).
+
+@item asorti(@var{source} @r{[}, @var{dest}@r{]}) #
+@cindex @code{asorti} function (@command{gawk})
+@code{asorti} is a @command{gawk}-specific extension, returning the number of
+elements in the array @var{source}.
+It works similarly to @code{asort}, however, the @emph{indices}
+are sorted, instead of the values. As array indices are always strings,
+the comparison performed is always a string comparison. (Here too,
+@code{IGNORECASE} affects the sorting.)
+
+The @code{asorti} function is described in more detail in
+@ref{Array Sorting}.
+It was added in @command{gawk} 3.1.2.
+@code{asorti} is a @command{gawk} extension; it is not available
+in compatibility mode (@pxref{Options}).
+
+@item index(@var{in}, @var{find})
+@cindex @code{index} function
+@cindex searching
+This searches the string @var{in} for the first occurrence of the string
+@var{find}, and returns the position in characters where that occurrence
+begins in the string @var{in}. Consider the following example:
+
+@example
+$ awk 'BEGIN @{ print index("peanut", "an") @}'
+@print{} 3
+@end example
+
+@noindent
+If @var{find} is not found, @code{index} returns zero.
+(Remember that string indices in @command{awk} start at one.)
+
+@item length(@r{[}@var{string}@r{]})
+@cindex @code{length} function
+This returns the number of characters in @var{string}. If
+@var{string} is a number, the length of the digit string representing
+that number is returned. For example, @code{length("abcde")} is 5. By
+contrast, @code{length(15 * 35)} works out to 3. In this example, 15 * 35 =
+525, and 525 is then converted to the string @code{"525"}, which has
+three characters.
+
+If no argument is supplied, @code{length} returns the length of @code{$0}.
+
+@c @cindex historical features
+@cindex portability, @code{length} function
+@cindex POSIX @command{awk}, functions and, @code{length}
+@quotation NOTE
+In older versions of @command{awk}, the @code{length} function could
+be called
+without any parentheses. Doing so is marked as ``deprecated'' in the
+POSIX standard. This means that while a program can do this,
+it is a feature that can eventually be removed from a future
+version of the standard. Therefore, for programs to be maximally portable,
+always supply the parentheses.
+@end quotation
+
+@cindex differences between @command{gawk} and @command{awk}
+Beginning with @command{gawk} @value{PVERSION} 3.2, when supplied an
+array argument, the @code{length} function returns the number of elements
+in the array. This is less useful than it might seem at first, as the
+array is not guaranteed to be indexed from one to the number of elements
+in it.
+If @option{--lint} is provided on the command line
+(@pxref{Options}),
+@command{gawk} warns that passing an array argument is not portable.
+If @option{--posix} is supplied, using an array argument is a fatal error
+(@pxref{Arrays}).
+
+@item match(@var{string}, @var{regexp} @r{[}, @var{array}@r{]})
+@cindex @code{match} function
+The @code{match} function searches @var{string} for the
+longest, leftmost substring matched by the regular expression,
+@var{regexp}. It returns the character position, or @dfn{index},
+at which that substring begins (one, if it starts at the beginning of
+@var{string}). If no match is found, it returns zero.
+
+The @var{regexp} argument may be either a regexp constant
+(@samp{/@dots{}/}) or a string constant (@var{"@dots{}"}).
+In the latter case, the string is treated as a regexp to be matched.
+@ref{Computed Regexps}, for a
+discussion of the difference between the two forms, and the
+implications for writing your program correctly.
+
+The order of the first two arguments is backwards from most other string
+functions that work with regular expressions, such as
+@code{sub} and @code{gsub}. It might help to remember that
+for @code{match}, the order is the same as for the @samp{~} operator:
+@samp{@var{string} ~ @var{regexp}}.
+
+@cindex @code{RSTART} variable, @code{match} function and
+@cindex @code{RLENGTH} variable, @code{match} function and
+@cindex @code{match} function, @code{RSTART}/@code{RLENGTH} variables
+The @code{match} function sets the built-in variable @code{RSTART} to
+the index. It also sets the built-in variable @code{RLENGTH} to the
+length in characters of the matched substring. If no match is found,
+@code{RSTART} is set to zero, and @code{RLENGTH} to @minus{}1.
+
+For example:
+
+@example
+@c file eg/misc/findpat.awk
+@{
+ if ($1 == "FIND")
+ regex = $2
+ else @{
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at",
+ where, "in", $0
+ @}
+@}
+@c endfile
+@end example
+
+@noindent
+This program looks for lines that match the regular expression stored in
+the variable @code{regex}. This regular expression can be changed. If the
+first word on a line is @samp{FIND}, @code{regex} is changed to be the
+second word on that line. Therefore, if given:
+
+@example
+@c file eg/misc/findpat.data
+FIND ru+n
+My program runs
+but not very quickly
+FIND Melvin
+JF+KM
+This line is property of Reality Engineering Co.
+Melvin was here.
+@c endfile
+@end example
+
+@noindent
+@command{awk} prints:
+
+@example
+Match of ru+n found at 12 in My program runs
+Match of Melvin found at 1 in Melvin was here.
+@end example
+
+@cindex differences in @command{awk} and @command{gawk}, @code{match} function
+If @var{array} is present, it is cleared, and then the 0th element
+of @var{array} is set to the entire portion of @var{string}
+matched by @var{regexp}. If @var{regexp} contains parentheses,
+the integer-indexed elements of @var{array} are set to contain the
+portion of @var{string} matching the corresponding parenthesized
+subexpression.
+For example:
+
+@example
+$ echo foooobazbarrrrr |
+> gawk '@{ match($0, /(fo+).+(bar*)/, arr)
+> print arr[1], arr[2] @}'
+@print{} foooo barrrrr
+@end example
+
+In addition,
+beginning with @command{gawk} 3.1.2,
+multidimensional subscripts are available providing
+the start index and length of each matched subexpression:
+
+@example
+$ echo foooobazbarrrrr |
+> gawk '@{ match($0, /(fo+).+(bar*)/, arr)
+> print arr[1], arr[2]
+> print arr[1, "start"], arr[1, "length"]
+> print arr[2, "start"], arr[2, "length"]
+> @}'
+@print{} foooo barrrrr
+@print{} 1 5
+@print{} 9 7
+@end example
+
+There may not be subscripts for the start and index for every parenthesized
+subexpressions, since they may not all have matched text; thus they
+should be tested for with the @code{in} operator
+(@pxref{Reference to Elements}).
+
+@cindex troubleshooting, @code{match} function
+The @var{array} argument to @code{match} is a
+@command{gawk} extension. In compatibility mode
+(@pxref{Options}),
+using a third argument is a fatal error.
+
+@item split(@var{string}, @var{array} @r{[}, @var{fieldsep}@r{]})
+@cindex @code{split} function
+This function divides @var{string} into pieces separated by @var{fieldsep}
+and stores the pieces in @var{array}. The first piece is stored in
+@code{@var{array}[1]}, the second piece in @code{@var{array}[2]}, and so
+forth. The string value of the third argument, @var{fieldsep}, is
+a regexp describing where to split @var{string} (much as @code{FS} can
+be a regexp describing where to split input records). If
+@var{fieldsep} is omitted, the value of @code{FS} is used.
+@code{split} returns the number of elements created.
+
+The @code{split} function splits strings into pieces in a
+manner similar to the way input lines are split into fields. For example:
+
+@example
+split("cul-de-sac", a, "-")
+@end example
+
+@noindent
+@cindex strings, splitting
+splits the string @samp{cul-de-sac} into three fields using @samp{-} as the
+separator. It sets the contents of the array @code{a} as follows:
+
+@example
+a[1] = "cul"
+a[2] = "de"
+a[3] = "sac"
+@end example
+
+@noindent
+The value returned by this call to @code{split} is three.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{split} function
+As with input field-splitting, when the value of @var{fieldsep} is
+@w{@code{" "}}, leading and trailing whitespace is ignored, and the elements
+are separated by runs of whitespace.
+Also as with input field-splitting, if @var{fieldsep} is the null string, each
+individual character in the string is split into its own array element.
+(This is a @command{gawk}-specific extension.)
+
+Note, however, that @code{RS} has no effect on the way @code{split}
+works. Even though @samp{RS = ""} causes newline to also be an input
+field separator, this does not affect how @code{split} splits strings.
+
+@cindex dark corner, @code{split} function
+Modern implementations of @command{awk}, including @command{gawk}, allow
+the third argument to be a regexp constant (@code{/abc/}) as well as a
+string.
+@value{DARKCORNER}
+The POSIX standard allows this as well.
+@ref{Computed Regexps}, for a
+discussion of the difference between using a string constant or a regexp constant,
+and the implications for writing your program correctly.
+
+Before splitting the string, @code{split} deletes any previously existing
+elements in the array @var{array}.
+
+If @var{string} is null, the array has no elements. (So this is a portable
+way to delete an entire array with one statement.
+@xref{Delete}.)
+
+If @var{string} does not match @var{fieldsep} at all (but is not null),
+@var{array} has one element only. The value of that element is the original
+@var{string}.
+
+@item sprintf(@var{format}, @var{expression1}, @dots{})
+@cindex @code{sprintf} function
+This returns (without printing) the string that @code{printf} would
+have printed out with the same arguments
+(@pxref{Printf}).
+For example:
+
+@example
+pival = sprintf("pi = %.2f (approx.)", 22/7)
+@end example
+
+@noindent
+assigns the string @w{@code{"pi = 3.14 (approx.)"}} to the variable @code{pival}.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{strtonum} function (@command{gawk})
+@cindex @code{strtonum} function (@command{gawk})
+@item strtonum(@var{str}) #
+Examines @var{str} and returns its numeric value. If @var{str}
+begins with a leading @samp{0}, @code{strtonum} assumes that @var{str}
+is an octal number. If @var{str} begins with a leading @samp{0x} or
+@samp{0X}, @code{strtonum} assumes that @var{str} is a hexadecimal number.
+For example:
+
+@example
+$ echo 0x11 |
+> gawk '@{ printf "%d\n", strtonum($1) @}'
+@print{} 17
+@end example
+
+Using the @code{strtonum} function is @emph{not} the same as adding zero
+to a string value; the automatic coercion of strings to numbers
+works only for decimal data, not for octal or hexadecimal.@footnote{Unless
+you use the @option{--non-decimal-data} option, which isn't recommended.
+@xref{Nondecimal Data}, for more information.}
+
+Note also that @code{strtonum} uses the current locale's decimal point
+for recognizing numbers.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{strtonum} function (@command{gawk})
+@code{strtonum} is a @command{gawk} extension; it is not available
+in compatibility mode (@pxref{Options}).
+
+@item sub(@var{regexp}, @var{replacement} @r{[}, @var{target}@r{]})
+@cindex @code{sub} function
+The @code{sub} function alters the value of @var{target}.
+It searches this value, which is treated as a string, for the
+leftmost, longest substring matched by the regular expression @var{regexp}.
+Then the entire string is
+changed by replacing the matched text with @var{replacement}.
+The modified string becomes the new value of @var{target}.
+
+The @var{regexp} argument may be either a regexp constant
+(@samp{/@dots{}/}) or a string constant (@var{"@dots{}"}).
+In the latter case, the string is treated as a regexp to be matched.
+@ref{Computed Regexps}, for a
+discussion of the difference between the two forms, and the
+implications for writing your program correctly.
+
+This function is peculiar because @var{target} is not simply
+used to compute a value, and not just any expression will do---it
+must be a variable, field, or array element so that @code{sub} can
+store a modified value there. If this argument is omitted, then the
+default is to use and alter @code{$0}.@footnote{Note that this means
+that the record will first be regenerated using the value of @code{OFS} if
+any fields have been changed, and that the fields will be updated
+after the substituion, even if the operation is a ``no-op'' such
+as @samp{sub(/^/, "")}.}
+For example:
+
+@example
+str = "water, water, everywhere"
+sub(/at/, "ith", str)
+@end example
+
+@noindent
+sets @code{str} to @w{@code{"wither, water, everywhere"}}, by replacing the
+leftmost longest occurrence of @samp{at} with @samp{ith}.
+
+The @code{sub} function returns the number of substitutions made (either
+one or zero).
+
+If the special character @samp{&} appears in @var{replacement}, it
+stands for the precise substring that was matched by @var{regexp}. (If
+the regexp can match more than one string, then this precise substring
+may vary.) For example:
+
+@example
+@{ sub(/candidate/, "& and his wife"); print @}
+@end example
+
+@noindent
+changes the first occurrence of @samp{candidate} to @samp{candidate
+and his wife} on each input line.
+Here is another example:
+
+@example
+$ awk 'BEGIN @{
+> str = "daabaaa"
+> sub(/a+/, "C&C", str)
+> print str
+> @}'
+@print{} dCaaCbaaa
+@end example
+
+@noindent
+This shows how @samp{&} can represent a nonconstant string and also
+illustrates the ``leftmost, longest'' rule in regexp matching
+(@pxref{Leftmost Longest}).
+
+The effect of this special character (@samp{&}) can be turned off by putting a
+backslash before it in the string. As usual, to insert one backslash in
+the string, you must write two backslashes. Therefore, write @samp{\\&}
+in a string constant to include a literal @samp{&} in the replacement.
+For example, the following shows how to replace the first @samp{|} on each line with
+an @samp{&}:
+
+@example
+@{ sub(/\|/, "\\&"); print @}
+@end example
+
+@cindex @code{sub} function, arguments of
+@cindex @code{gsub} function, arguments of
+As mentioned, the third argument to @code{sub} must
+be a variable, field or array reference.
+Some versions of @command{awk} allow the third argument to
+be an expression that is not an lvalue. In such a case, @code{sub}
+still searches for the pattern and returns zero or one, but the result of
+the substitution (if any) is thrown away because there is no place
+to put it. Such versions of @command{awk} accept expressions
+such as the following:
+
+@example
+sub(/USA/, "United States", "the USA and Canada")
+@end example
+
+@noindent
+@cindex troubleshooting, @code{gsub}/@code{sub} functions
+For historical compatibility, @command{gawk} accepts erroneous code,
+such as in the previous example. However, using any other nonchangeable
+object as the third parameter causes a fatal error and your program
+will not run.
+
+Finally, if the @var{regexp} is not a regexp constant, it is converted into a
+string, and then the value of that string is treated as the regexp to match.
+
+@item gsub(@var{regexp}, @var{replacement} @r{[}, @var{target}@r{]})
+@cindex @code{gsub} function
+This is similar to the @code{sub} function, except @code{gsub} replaces
+@emph{all} of the longest, leftmost, @emph{nonoverlapping} matching
+substrings it can find. The @samp{g} in @code{gsub} stands for
+``global,'' which means replace everywhere. For example:
+
+@example
+@{ gsub(/Britain/, "United Kingdom"); print @}
+@end example
+
+@noindent
+replaces all occurrences of the string @samp{Britain} with @samp{United
+Kingdom} for all input records.
+
+The @code{gsub} function returns the number of substitutions made. If
+the variable to search and alter (@var{target}) is
+omitted, then the entire input record (@code{$0}) is used.
+As in @code{sub}, the characters @samp{&} and @samp{\} are special,
+and the third argument must be assignable.
+
+@item gensub(@var{regexp}, @var{replacement}, @var{how} @r{[}, @var{target}@r{]}) #
+@cindex @code{gensub} function (@command{gawk})
+@code{gensub} is a general substitution function. Like @code{sub} and
+@code{gsub}, it searches the target string @var{target} for matches of
+the regular expression @var{regexp}. Unlike @code{sub} and @code{gsub},
+the modified string is returned as the result of the function and the
+original target string is @emph{not} changed. If @var{how} is a string
+beginning with @samp{g} or @samp{G}, then it replaces all matches of
+@var{regexp} with @var{replacement}. Otherwise, @var{how} is treated
+as a number that indicates which match of @var{regexp} to replace. If
+no @var{target} is supplied, @code{$0} is used.
+
+@code{gensub} provides an additional feature that is not available
+in @code{sub} or @code{gsub}: the ability to specify components of a
+regexp in the replacement text. This is done by using parentheses in
+the regexp to mark the components and then specifying @samp{\@var{N}}
+in the replacement text, where @var{N} is a digit from 1 to 9.
+For example:
+
+@example
+$ gawk '
+> BEGIN @{
+> a = "abc def"
+> b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)
+> print b
+> @}'
+@print{} def abc
+@end example
+
+@noindent
+As with @code{sub}, you must type two backslashes in order
+to get one into the string.
+In the replacement text, the sequence @samp{\0} represents the entire
+matched text, as does the character @samp{&}.
+
+The following example shows how you can use the third argument to control
+which match of the regexp should be changed:
+
+@example
+$ echo a b c a b c |
+> gawk '@{ print gensub(/a/, "AA", 2) @}'
+@print{} a b c AA b c
+@end example
+
+In this case, @code{$0} is used as the default target string.
+@code{gensub} returns the new string as its result, which is
+passed directly to @code{print} for printing.
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+If the @var{how} argument is a string that does not begin with @samp{g} or
+@samp{G}, or if it is a number that is less than or equal to zero, only one
+substitution is performed. If @var{how} is zero, @command{gawk} issues
+a warning message.
+
+If @var{regexp} does not match @var{target}, @code{gensub}'s return value
+is the original unchanged value of @var{target}.
+
+@code{gensub} is a @command{gawk} extension; it is not available
+in compatibility mode (@pxref{Options}).
+
+@item substr(@var{string}, @var{start} @r{[}, @var{length}@r{]})
+@cindex @code{substr} function
+This returns a @var{length}-character-long substring of @var{string},
+starting at character number @var{start}. The first character of a
+string is character number one.@footnote{This is different from
+C and C++, in which the first character is number zero.}
+For example, @code{substr("washington", 5, 3)} returns @code{"ing"}.
+
+If @var{length} is not present, this function returns the whole suffix of
+@var{string} that begins at character number @var{start}. For example,
+@code{substr("washington", 5)} returns @code{"ington"}. The whole
+suffix is also returned
+if @var{length} is greater than the number of characters remaining
+in the string, counting from character @var{start}.
+
+If @var{start} is less than one, @code{substr} treats it as
+if it was one. (POSIX doesn't specify what to do in this case:
+Unix @command{awk} acts this way, and therefore @command{gawk}
+does too.)
+If @var{start} is greater than the number of characters
+in the string, @code{substr} returns the null string.
+Similarly, if @var{length} is present but less than or equal to zero,
+the null string is returned.
+
+@cindex troubleshooting, @code{substr} function
+The string returned by @code{substr} @emph{cannot} be
+assigned. Thus, it is a mistake to attempt to change a portion of
+a string, as shown in the following example:
+
+@example
+string = "abcdef"
+# try to get "abCDEf", won't work
+substr(string, 3, 3) = "CDE"
+@end example
+
+@noindent
+It is also a mistake to use @code{substr} as the third argument
+of @code{sub} or @code{gsub}:
+
+@example
+gsub(/xyz/, "pdq", substr($0, 5, 20)) # WRONG
+@end example
+
+@cindex portability, @code{substr} function
+(Some commercial versions of @command{awk} do in fact let you use
+@code{substr} this way, but doing so is not portable.)
+
+If you need to replace bits and pieces of a string, combine @code{substr}
+with string concatenation, in the following manner:
+
+@example
+string = "abcdef"
+@dots{}
+string = substr(string, 1, 2) "CDE" substr(string, 6)
+@end example
+
+@cindex case sensitivity, converting case
+@cindex converting, case
+@item tolower(@var{string})
+@cindex @code{tolower} function
+This returns a copy of @var{string}, with each uppercase character
+in the string replaced with its corresponding lowercase character.
+Nonalphabetic characters are left unchanged. For example,
+@code{tolower("MiXeD cAsE 123")} returns @code{"mixed case 123"}.
+
+@item toupper(@var{string})
+@cindex @code{toupper} function
+This returns a copy of @var{string}, with each lowercase character
+in the string replaced with its corresponding uppercase character.
+Nonalphabetic characters are left unchanged. For example,
+@code{toupper("MiXeD cAsE 123")} returns @code{"MIXED CASE 123"}.
+@end table
+
+@node Gory Details
+@subsubsection More About @samp{\} and @samp{&} with @code{sub}, @code{gsub}, and @code{gensub}
+
+@cindex escape processing, @code{gsub}/@code{gensub}/@code{sub} functions
+@cindex @code{sub} function, escape processing
+@cindex @code{gsub} function, escape processing
+@cindex @code{gensub} function (@command{gawk}), escape processing
+@cindex @code{\} (backslash), @code{gsub}/@code{gensub}/@code{sub} functions and
+@cindex backslash (@code{\}), @code{gsub}/@code{gensub}/@code{sub} functions and
+@cindex @code{&} (ampersand), @code{gsub}/@code{gensub}/@code{sub} functions and
+@cindex ampersand (@code{&}), @code{gsub}/@code{gensub}/@code{sub} functions and
+When using @code{sub}, @code{gsub}, or @code{gensub}, and trying to get literal
+backslashes and ampersands into the replacement text, you need to remember
+that there are several levels of @dfn{escape processing} going on.
+
+First, there is the @dfn{lexical} level, which is when @command{awk} reads
+your program
+and builds an internal copy of it that can be executed.
+Then there is the runtime level, which is when @command{awk} actually scans the
+replacement string to determine what to generate.
+
+At both levels, @command{awk} looks for a defined set of characters that
+can come after a backslash. At the lexical level, it looks for the
+escape sequences listed in @ref{Escape Sequences}.
+Thus, for every @samp{\} that @command{awk} processes at the runtime
+level, type two backslashes at the lexical level.
+When a character that is not valid for an escape sequence follows the
+@samp{\}, Unix @command{awk} and @command{gawk} both simply remove the initial
+@samp{\} and put the next character into the string. Thus, for
+example, @code{"a\qb"} is treated as @code{"aqb"}.
+
+At the runtime level, the various functions handle sequences of
+@samp{\} and @samp{&} differently. The situation is (sadly) somewhat complex.
+Historically, the @code{sub} and @code{gsub} functions treated the two
+character sequence @samp{\&} specially; this sequence was replaced in
+the generated text with a single @samp{&}. Any other @samp{\} within
+the @var{replacement} string that did not precede an @samp{&} was passed
+through unchanged. This is illustrated in @ref{table-sub-escapes}.
+
+@c Thank to Karl Berry for help with the TeX stuff.
+@float Table,table-sub-escapes
+@caption{Historical Escape Sequence Processing for sub and gsub}
+@tex
+\vbox{\bigskip
+% This table has lots of &'s and \'s, so unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+% But then we need character for escape and tab.
+@catcode`! = 4
+@halign{@hfil#!@qquad@hfil#!@qquad#@hfil@cr
+ You type!@code{sub} sees!@code{sub} generates@cr
+@hrulefill!@hrulefill!@hrulefill@cr
+ @code{\&}! @code{&}!the matched text@cr
+ @code{\\&}! @code{\&}!a literal @samp{&}@cr
+ @code{\\\&}! @code{\&}!a literal @samp{&}@cr
+@code{\\\\&}! @code{\\&}!a literal @samp{\&}@cr
+@code{\\\\\&}! @code{\\&}!a literal @samp{\&}@cr
+@code{\\\\\\&}! @code{\\\&}!a literal @samp{\\&}@cr
+ @code{\\q}! @code{\q}!a literal @samp{\q}@cr
+}
+@bigskip}
+@end tex
+@ifdocbook
+@multitable @columnfractions .20 .20 .60
+@headitem You type @tab @code{sub} sees @tab @code{sub} generates
+@item @code{\&} @tab @code{&} @tab the matched text
+@item @code{\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\\\&} @tab @code{\\&} @tab a literal @samp{\&}
+@item @code{\\\\\&} @tab @code{\\&} @tab a literal @samp{\&}
+@item @code{\\\\\\&} @tab @code{\\\&} @tab a literal @samp{\\&}
+@item @code{\\q} @tab @code{\q} @tab a literal @samp{\q}
+@end multitable
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@display
+ You type @code{sub} sees @code{sub} generates
+ -------- ---------- ---------------
+ @code{\&} @code{&} the matched text
+ @code{\\&} @code{\&} a literal @samp{&}
+ @code{\\\&} @code{\&} a literal @samp{&}
+ @code{\\\\&} @code{\\&} a literal @samp{\&}
+ @code{\\\\\&} @code{\\&} a literal @samp{\&}
+@code{\\\\\\&} @code{\\\&} a literal @samp{\\&}
+ @code{\\q} @code{\q} a literal @samp{\q}
+@end display
+@end ifnotdocbook
+@end ifnottex
+@end float
+
+@noindent
+This table shows both the lexical-level processing, where
+an odd number of backslashes becomes an even number at the runtime level,
+as well as the runtime processing done by @code{sub}.
+(For the sake of simplicity, the rest of the following tables only show the
+case of even numbers of backslashes entered at the lexical level.)
+
+The problem with the historical approach is that there is no way to get
+a literal @samp{\} followed by the matched text.
+
+@c @cindex @command{awk} language, POSIX version
+@cindex POSIX @command{awk}, functions and, @code{gsub}/@code{sub}
+The 1992 POSIX standard attempted to fix this problem. That standard
+says that @code{sub} and @code{gsub} look for either a @samp{\} or an @samp{&}
+after the @samp{\}. If either one follows a @samp{\}, that character is
+output literally. The interpretation of @samp{\} and @samp{&} then becomes
+as shown in @ref{table-sub-posix-92}.
+
+@float Table,table-sub-posix-92
+@caption{1992 POSIX Rules for sub and gsub Escape Sequence Processing}
+@c thanks to Karl Berry for formatting this table
+@tex
+\vbox{\bigskip
+% This table has lots of &'s and \'s, so unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+% But then we need character for escape and tab.
+@catcode`! = 4
+@halign{@hfil#!@qquad@hfil#!@qquad#@hfil@cr
+ You type!@code{sub} sees!@code{sub} generates@cr
+@hrulefill!@hrulefill!@hrulefill@cr
+ @code{&}! @code{&}!the matched text@cr
+ @code{\\&}! @code{\&}!a literal @samp{&}@cr
+@code{\\\\&}! @code{\\&}!a literal @samp{\}, then the matched text@cr
+@code{\\\\\\&}! @code{\\\&}!a literal @samp{\&}@cr
+}
+@bigskip}
+@end tex
+@ifdocbook
+@multitable @columnfractions .20 .20 .60
+@headitem You type @tab @code{sub} sees @tab @code{sub} generates
+@item @code{&} @tab @code{&} @tab the matched text
+@item @code{\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\\\&} @tab @code{\\&} @tab a literal @samp{\}, then the matched text
+@item @code{\\\\\\&} @tab @code{\\\&} @tab a literal @samp{\&}
+@end multitable
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@display
+ You type @code{sub} sees @code{sub} generates
+ -------- ---------- ---------------
+ @code{&} @code{&} the matched text
+ @code{\\&} @code{\&} a literal @samp{&}
+ @code{\\\\&} @code{\\&} a literal @samp{\}, then the matched text
+@code{\\\\\\&} @code{\\\&} a literal @samp{\&}
+@end display
+@end ifnotdocbook
+@end ifnottex
+@end float
+
+@noindent
+This appears to solve the problem.
+Unfortunately, the phrasing of the standard is unusual. It
+says, in effect, that @samp{\} turns off the special meaning of any
+following character, but for anything other than @samp{\} and @samp{&},
+such special meaning is undefined. This wording leads to two problems:
+
+@itemize @bullet
+@item
+Backslashes must now be doubled in the @var{replacement} string, breaking
+historical @command{awk} programs.
+
+@item
+To make sure that an @command{awk} program is portable, @emph{every} character
+in the @var{replacement} string must be preceded with a
+backslash.@footnote{This consequence was certainly unintended.}
+@c I can say that, 'cause I was involved in making this change
+@end itemize
+
+Because of the problems just listed,
+in 1996, the @command{gawk} maintainer submitted
+proposed text for a revised standard that
+reverts to rules that correspond more closely to the original existing
+practice. The proposed rules have special cases that make it possible
+to produce a @samp{\} preceding the matched text. This is shown in
+@ref{table-sub-proposed}.
+
+@float Table,table-sub-proposed
+@caption{Propsosed rules for sub and backslash}
+@tex
+\vbox{\bigskip
+% This table has lots of &'s and \'s, so unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+% But then we need character for escape and tab.
+@catcode`! = 4
+@halign{@hfil#!@qquad@hfil#!@qquad#@hfil@cr
+ You type!@code{sub} sees!@code{sub} generates@cr
+@hrulefill!@hrulefill!@hrulefill@cr
+@code{\\\\\\&}! @code{\\\&}!a literal @samp{\&}@cr
+@code{\\\\&}! @code{\\&}!a literal @samp{\}, followed by the matched text@cr
+ @code{\\&}! @code{\&}!a literal @samp{&}@cr
+ @code{\\q}! @code{\q}!a literal @samp{\q}@cr
+ @code{\\\\}! @code{\\}!@code{\\}@cr
+}
+@bigskip}
+@end tex
+@ifdocbook
+@multitable @columnfractions .20 .20 .60
+@headitem You type @tab @code{sub} sees @tab @code{sub} generates
+@item @code{\\\\\\&} @tab @code{\\\&} @tab a literal @samp{\&}
+@item @code{\\\\&} @tab @code{\\&} @tab a literal @samp{\}, followed by the matched text
+@item @code{\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\q} @tab @code{\q} @tab a literal @samp{\q}
+@item @code{\\\\} @tab @code{\\} @tab @code{\\}
+@end multitable
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@display
+ You type @code{sub} sees @code{sub} generates
+ -------- ---------- ---------------
+@code{\\\\\\&} @code{\\\&} a literal @samp{\&}
+ @code{\\\\&} @code{\\&} a literal @samp{\}, followed by the matched text
+ @code{\\&} @code{\&} a literal @samp{&}
+ @code{\\q} @code{\q} a literal @samp{\q}
+ @code{\\\\} @code{\\} @code{\\}
+@end display
+@end ifnotdocbook
+@end ifnottex
+@end float
+
+In a nutshell, at the runtime level, there are now three special sequences
+of characters (@samp{\\\&}, @samp{\\&} and @samp{\&}) whereas historically
+there was only one. However, as in the historical case, any @samp{\} that
+is not part of one of these three sequences is not special and appears
+in the output literally.
+
+@command{gawk} 3.0 and 3.1 follow these proposed POSIX rules for @code{sub} and
+@code{gsub}.
+@c As much as we think it's a lousy idea. You win some, you lose some. Sigh.
+The POSIX standard took much longer to be revised than was expected in 1996.
+The 2001 standard does not follow the above rules. Instead, the rules
+there are somewhat simpler. The results are similar except for one case.
+
+The 2001 POSIX rules state that @samp{\&} in the replacement string produces
+a literal @samp{&}, @samp{\\} produces a literal @samp{\}, and @samp{\} followed
+by anything else is not special; the @samp{\} is placed straight into the output.
+These rules are presented in @ref{table-posix-2001-sub}.
+
+@float Table,table-posix-2001-sub
+@caption{POSIX 2001 rules for sub}
+@tex
+\vbox{\bigskip
+% This table has lots of &'s and \'s, so unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+% But then we need character for escape and tab.
+@catcode`! = 4
+@halign{@hfil#!@qquad@hfil#!@qquad#@hfil@cr
+ You type!@code{sub} sees!@code{sub} generates@cr
+@hrulefill!@hrulefill!@hrulefill@cr
+@code{\\\\\\&}! @code{\\\&}!a literal @samp{\&}@cr
+@code{\\\\&}! @code{\\&}!a literal @samp{\}, followed by the matched text@cr
+ @code{\\&}! @code{\&}!a literal @samp{&}@cr
+ @code{\\q}! @code{\q}!a literal @samp{\q}@cr
+ @code{\\\\}! @code{\\}!@code{\}@cr
+}
+@bigskip}
+@end tex
+@ifdocbook
+@multitable @columnfractions .20 .20 .60
+@headitem You type @tab @code{sub} sees @tab @code{sub} generates
+@item @code{\\\\\\&} @tab @code{\\\&} @tab a literal @samp{\&}
+@item @code{\\\\&} @tab @code{\\&} @tab a literal @samp{\}, followed by the matched text
+@item @code{\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\q} @tab @code{\q} @tab a literal @samp{\q}
+@item @code{\\\\} @tab @code{\\} @tab @code{\}
+@end multitable
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@display
+ You type @code{sub} sees @code{sub} generates
+ -------- ---------- ---------------
+@code{\\\\\\&} @code{\\\&} a literal @samp{\&}
+ @code{\\\\&} @code{\\&} a literal @samp{\}, followed by the matched text
+ @code{\\&} @code{\&} a literal @samp{&}
+ @code{\\q} @code{\q} a literal @samp{\q}
+ @code{\\\\} @code{\\} @code{\}
+@end display
+@end ifnotdocbook
+@end ifnottex
+@end float
+
+The only case where the difference is noticeable is the last one: @samp{\\\\}
+is seen as @samp{\\} and produces @samp{\} instead of @samp{\\}.
+
+Starting with version 3.1.4, @command{gawk} follows the POSIX rules
+when @option{--posix} is specified (@pxref{Options}). Otherwise,
+it continues to follow the 1996 proposed rules, since, as of this
+writing, that has been its behavior for over seven years.
+
+@quotation NOTE
+At the next major release, @command{gawk} will switch to using
+the POSIX 2001 rules by default.
+@end quotation
+
+The rules for @code{gensub} are considerably simpler. At the runtime
+level, whenever @command{gawk} sees a @samp{\}, if the following character
+is a digit, then the text that matched the corresponding parenthesized
+subexpression is placed in the generated output. Otherwise,
+no matter what character follows the @samp{\}, it
+appears in the generated text and the @samp{\} does not,
+as shown in @ref{table-gensub-escapes}.
+
+@float Table,table-gensub-escapes
+@caption{Escape Sequence Processing for gensub}
+@tex
+\vbox{\bigskip
+% This table has lots of &'s and \'s, so unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+% But then we need character for escape and tab.
+@catcode`! = 4
+@halign{@hfil#!@qquad@hfil#!@qquad#@hfil@cr
+ You type!@code{gensub} sees!@code{gensub} generates@cr
+@hrulefill!@hrulefill!@hrulefill@cr
+ @code{&}! @code{&}!the matched text@cr
+ @code{\\&}! @code{\&}!a literal @samp{&}@cr
+ @code{\\\\}! @code{\\}!a literal @samp{\}@cr
+ @code{\\\\&}! @code{\\&}!a literal @samp{\}, then the matched text@cr
+@code{\\\\\\&}! @code{\\\&}!a literal @samp{\&}@cr
+ @code{\\q}! @code{\q}!a literal @samp{q}@cr
+}
+@bigskip}
+@end tex
+@ifdocbook
+@multitable @columnfractions .20 .20 .60
+@headitem You type @tab @code{gensub} sees @tab @code{gensub} generates
+@item @code{&} @tab @code{&} @tab the matched text
+@item @code{\\&} @tab @code{\&} @tab a literal @samp{&}
+@item @code{\\\\} @tab @code{\\} @tab a literal @samp{\}
+@item @code{\\\\&} @tab @code{\\&} @tab a literal @samp{\}, then the matched text
+@item @code{\\\\\\&} @tab @code{\\\&} @tab a literal @samp{\&}
+@item @code{\\q} @tab @code{\q} @tab a literal @samp{q}
+@end multitable
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@display
+ You type @code{gensub} sees @code{gensub} generates
+ -------- ------------- ------------------
+ @code{&} @code{&} the matched text
+ @code{\\&} @code{\&} a literal @samp{&}
+ @code{\\\\} @code{\\} a literal @samp{\}
+ @code{\\\\&} @code{\\&} a literal @samp{\}, then the matched text
+@code{\\\\\\&} @code{\\\&} a literal @samp{\&}
+ @code{\\q} @code{\q} a literal @samp{q}
+@end display
+@end ifnotdocbook
+@end ifnottex
+@end float
+
+Because of the complexity of the lexical and runtime level processing
+and the special cases for @code{sub} and @code{gsub},
+we recommend the use of @command{gawk} and @code{gensub} when you have
+to do substitutions.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Matching the Null String
+@cindex advanced features, null strings@comma{} matching
+@cindex matching, null strings
+@cindex null strings, matching
+@cindex @code{*} (asterisk), @code{*} operator, null strings@comma{} matching
+@cindex asterisk (@code{*}), @code{*} operator, null strings@comma{} matching
+
+In @command{awk}, the @samp{*} operator can match the null string.
+This is particularly important for the @code{sub}, @code{gsub},
+and @code{gensub} functions. For example:
+
+@example
+$ echo abc | awk '@{ gsub(/m*/, "X"); print @}'
+@print{} XaXbXcX
+@end example
+
+@noindent
+Although this makes a certain amount of sense, it can be surprising.
+
+@node I/O Functions
+@subsection Input/Output Functions
+
+The following functions relate to input/output (I/O).
+Optional parameters are enclosed in square brackets ([ ]):
+
+@table @code
+@item close(@var{filename} @r{[}, @var{how}@r{]})
+@cindex @code{close} function
+@cindex files, closing
+Close the file @var{filename} for input or output. Alternatively, the
+argument may be a shell command that was used for creating a coprocess, or
+for redirecting to or from a pipe; then the coprocess or pipe is closed.
+@xref{Close Files And Pipes},
+for more information.
+
+When closing a coprocess, it is occasionally useful to first close
+one end of the two-way pipe and then to close the other. This is done
+by providing a second argument to @code{close}. This second argument
+should be one of the two string values @code{"to"} or @code{"from"},
+indicating which end of the pipe to close. Case in the string does
+not matter.
+@xref{Two-way I/O},
+which discusses this feature in more detail and gives an example.
+
+@item fflush(@r{[}@var{filename}@r{]})
+@cindex @code{fflush} function
+Flush any buffered output associated with @var{filename}, which is either a
+file opened for writing or a shell command for redirecting output to
+a pipe or coprocess.
+
+@cindex portability, @code{fflush} function and
+@cindex buffers, flushing
+@cindex output, buffering
+Many utility programs @dfn{buffer} their output; i.e., they save information
+to write to a disk file or terminal in memory until there is enough
+for it to be worthwhile to send the data to the output device.
+This is often more efficient than writing
+every little bit of information as soon as it is ready. However, sometimes
+it is necessary to force a program to @dfn{flush} its buffers; that is,
+write the information to its destination, even if a buffer is not full.
+This is the purpose of the @code{fflush} function---@command{gawk} also
+buffers its output and the @code{fflush} function forces
+@command{gawk} to flush its buffers.
+
+@code{fflush} was added to the Bell Laboratories research
+version of @command{awk} in 1994; it is not part of the POSIX standard and is
+not available if @option{--posix} has been specified on the
+command line (@pxref{Options}).
+
+@cindex @command{gawk}, @code{fflush} function in
+@command{gawk} extends the @code{fflush} function in two ways. The first
+is to allow no argument at all. In this case, the buffer for the
+standard output is flushed. The second is to allow the null string
+(@w{@code{""}}) as the argument. In this case, the buffers for
+@emph{all} open output files and pipes are flushed.
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@cindex troubleshooting, @code{fflush} function
+@code{fflush} returns zero if the buffer is successfully flushed;
+otherwise, it returns @minus{}1.
+In the case where all buffers are flushed, the return value is zero
+only if all buffers were flushed successfully. Otherwise, it is
+@minus{}1, and @command{gawk} warns about the problem @var{filename}.
+
+@command{gawk} also issues a warning message if you attempt to flush
+a file or pipe that was opened for reading (such as with @code{getline}),
+or if @var{filename} is not an open file, pipe, or coprocess.
+In such a case, @code{fflush} returns @minus{}1, as well.
+
+@item system(@var{command})
+@cindex @code{system} function
+@cindex interacting with other programs
+Executes operating-system
+commands and then returns to the @command{awk} program. The @code{system}
+function executes the command given by the string @var{command}.
+It returns the status returned by the command that was executed as
+its value.
+
+For example, if the following fragment of code is put in your @command{awk}
+program:
+
+@example
+END @{
+ system("date | mail -s 'awk run done' root")
+@}
+@end example
+
+@noindent
+the system administrator is sent mail when the @command{awk} program
+finishes processing input and begins its end-of-input processing.
+
+Note that redirecting @code{print} or @code{printf} into a pipe is often
+enough to accomplish your task. If you need to run many commands, it
+is more efficient to simply print them down a pipeline to the shell:
+
+@example
+while (@var{more stuff to do})
+ print @var{command} | "/bin/sh"
+close("/bin/sh")
+@end example
+
+@noindent
+@cindex troubleshooting, @code{system} function
+However, if your @command{awk}
+program is interactive, @code{system} is useful for cranking up large
+self-contained programs, such as a shell or an editor.
+Some operating systems cannot implement the @code{system} function.
+@code{system} causes a fatal error if it is not supported.
+@end table
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Interactive Versus Noninteractive Buffering
+@cindex advanced features, buffering
+@cindex buffering, interactive vs. noninteractive
+
+As a side point, buffering issues can be even more confusing, depending
+upon whether your program is @dfn{interactive}, i.e., communicating
+with a user sitting at a keyboard.@footnote{A program is interactive
+if the standard output is connected
+to a terminal device.}
+
+@c Thanks to Walter.Mecky@dresdnerbank.de for this example, and for
+@c motivating me to write this section.
+Interactive programs generally @dfn{line buffer} their output; i.e., they
+write out every line. Noninteractive programs wait until they have
+a full buffer, which may be many lines of output.
+Here is an example of the difference:
+
+@example
+$ awk '@{ print $1 + $2 @}'
+1 1
+@print{} 2
+2 3
+@print{} 5
+@kbd{@value{CTL}-d}
+@end example
+
+@noindent
+Each line of output is printed immediately. Compare that behavior
+with this example:
+
+@example
+$ awk '@{ print $1 + $2 @}' | cat
+1 1
+2 3
+@kbd{@value{CTL}-d}
+@print{} 2
+@print{} 5
+@end example
+
+@noindent
+Here, no output is printed until after the @kbd{@value{CTL}-d} is typed, because
+it is all buffered and sent down the pipe to @command{cat} in one shot.
+
+@c fakenode --- for prepinfo
+@subheading Advanced Notes: Controlling Output Buffering with @code{system}
+@cindex advanced features, buffering
+@cindex buffers, flushing
+@cindex buffering, input/output
+@cindex output, buffering
+
+The @code{fflush} function provides explicit control over output buffering for
+individual files and pipes. However, its use is not portable to many other
+@command{awk} implementations. An alternative method to flush output
+buffers is to call @code{system} with a null string as its argument:
+
+@example
+system("") # flush output
+@end example
+
+@noindent
+@command{gawk} treats this use of the @code{system} function as a special
+case and is smart enough not to run a shell (or other command
+interpreter) with the empty command. Therefore, with @command{gawk}, this
+idiom is not only useful, it is also efficient. While this method should work
+with other @command{awk} implementations, it does not necessarily avoid
+starting an unnecessary shell. (Other implementations may only
+flush the buffer associated with the standard output and not necessarily
+all buffered output.)
+
+If you think about what a programmer expects, it makes sense that
+@code{system} should flush any pending output. The following program:
+
+@example
+BEGIN @{
+ print "first print"
+ system("echo system echo")
+ print "second print"
+@}
+@end example
+
+@noindent
+must print:
+
+@example
+first print
+system echo
+second print
+@end example
+
+@noindent
+and not:
+
+@example
+system echo
+first print
+second print
+@end example
+
+If @command{awk} did not flush its buffers before calling @code{system},
+you would see the latter (undesirable) output.
+
+@node Time Functions
+@subsection Using @command{gawk}'s Timestamp Functions
+
+@c STARTOFRANGE tst
+@cindex timestamps
+@c STARTOFRANGE logftst
+@cindex log files, timestamps in
+@c STARTOFRANGE filogtst
+@cindex files, log@comma{} timestamps in
+@c STARTOFRANGE gawtst
+@cindex @command{gawk}, timestamps
+@cindex POSIX @command{awk}, timestamps and
+@code{awk} programs are commonly used to process log files
+containing timestamp information, indicating when a
+particular log record was written. Many programs log their timestamp
+in the form returned by the @code{time} system call, which is the
+number of seconds since a particular epoch. On POSIX-compliant systems,
+it is the number of seconds since
+1970-01-01 00:00:00 UTC, not counting leap seconds.@footnote{@xref{Glossary},
+especially the entries ``Epoch'' and ``UTC.''}
+All known POSIX-compliant systems support timestamps from 0 through
+@math{2^31 - 1}, which is sufficient to represent times through
+2038-01-19 03:14:07 UTC. Many systems support a wider range of timestamps,
+including negative timestamps that represent times before the
+epoch.
+
+@cindex @command{date} utility, GNU
+@cindex time, retrieving
+In order to make it easier to process such log files and to produce
+useful reports, @command{gawk} provides the following functions for
+working with timestamps. They are @command{gawk} extensions; they are
+not specified in the POSIX standard, nor are they in any other known
+version of @command{awk}.@footnote{The GNU @command{date} utility can
+also do many of the things described here. Its use may be preferable
+for simple time-related operations in shell scripts.}
+Optional parameters are enclosed in square brackets ([ ]):
+
+@table @code
+@item systime()
+@cindex @code{systime} function (@command{gawk})
+@cindex timestamps
+This function returns the current time as the number of seconds since
+the system epoch. On POSIX systems, this is the number of seconds
+since 1970-01-01 00:00:00 UTC, not counting leap seconds.
+It may be a different number on
+other systems.
+
+@item mktime(@var{datespec})
+@cindex @code{mktime} function (@command{gawk})
+This function turns @var{datespec} into a timestamp in the same form
+as is returned by @code{systime}. It is similar to the function of the
+same name in ISO C. The argument, @var{datespec}, is a string of the form
+@w{@code{"@var{YYYY} @var{MM} @var{DD} @var{HH} @var{MM} @var{SS} [@var{DST}]"}}.
+The string consists of six or seven numbers representing, respectively,
+the full year including century, the month from 1 to 12, the day of the month
+from 1 to 31, the hour of the day from 0 to 23, the minute from 0 to
+59, the second from 0 to 60,@footnote{Occasionally there are
+minutes in a year with a leap second, which is why the
+seconds can go up to 60.}
+and an optional daylight-savings flag.
+
+The values of these numbers need not be within the ranges specified;
+for example, an hour of @minus{}1 means 1 hour before midnight.
+The origin-zero Gregorian calendar is assumed, with year 0 preceding
+year 1 and year @minus{}1 preceding year 0.
+The time is assumed to be in the local timezone.
+If the daylight-savings flag is positive, the time is assumed to be
+daylight savings time; if zero, the time is assumed to be standard
+time; and if negative (the default), @code{mktime} attempts to determine
+whether daylight savings time is in effect for the specified time.
+
+If @var{datespec} does not contain enough elements or if the resulting time
+is out of range, @code{mktime} returns @minus{}1.
+
+@item strftime(@r{[}@var{format} @r{[}, @var{timestamp}@r{]]})
+@c STARTOFRANGE strf
+@cindex @code{strftime} function (@command{gawk})
+This function returns a string. It is similar to the function of the
+same name in ISO C. The time specified by @var{timestamp} is used to
+produce a string, based on the contents of the @var{format} string.
+The @var{timestamp} is in the same format as the value returned by the
+@code{systime} function. If no @var{timestamp} argument is supplied,
+@command{gawk} uses the current time of day as the timestamp.
+If no @var{format} argument is supplied, @code{strftime} uses
+@code{@w{"%a %b %d %H:%M:%S %Z %Y"}}. This format string produces
+output that is (almost) equivalent to that of the @command{date} utility.
+(Versions of @command{gawk} prior to 3.0 require the @var{format} argument.)
+@end table
+
+The @code{systime} function allows you to compare a timestamp from a
+log file with the current time of day. In particular, it is easy to
+determine how long ago a particular record was logged. It also allows
+you to produce log records using the ``seconds since the epoch'' format.
+
+@cindex converting, dates to timestamps
+@cindex dates, converting to timestamps
+@cindex timestamps, converting dates to
+The @code{mktime} function allows you to convert a textual representation
+of a date and time into a timestamp. This makes it easy to do before/after
+comparisons of dates and times, particularly when dealing with date and
+time data coming from an external source, such as a log file.
+
+The @code{strftime} function allows you to easily turn a timestamp
+into human-readable information. It is similar in nature to the @code{sprintf}
+function
+(@pxref{String Functions}),
+in that it copies nonformat specification characters verbatim to the
+returned string, while substituting date and time values for format
+specifications in the @var{format} string.
+
+@cindex format specifiers, @code{strftime} function (@command{gawk})
+@code{strftime} is guaranteed by the 1999 ISO C standard@footnote{As this
+is a recent standard, not every system's @code{strftime} necessarily
+supports all of the conversions listed here.}
+to support the following date format specifications:
+
+@table @code
+@item %a
+The locale's abbreviated weekday name.
+
+@item %A
+The locale's full weekday name.
+
+@item %b
+The locale's abbreviated month name.
+
+@item %B
+The locale's full month name.
+
+@item %c
+The locale's ``appropriate'' date and time representation.
+(This is @samp{%A %B %d %T %Y} in the @code{"C"} locale.)
+
+@item %C
+The century. This is the year divided by 100 and truncated to the next
+lower integer.
+
+@item %d
+The day of the month as a decimal number (01--31).
+
+@item %D
+Equivalent to specifying @samp{%m/%d/%y}.
+
+@item %e
+The day of the month, padded with a space if it is only one digit.
+
+@item %F
+Equivalent to specifying @samp{%Y-%m-%d}.
+This is the ISO 8601 date format.
+
+@item %g
+The year modulo 100 of the ISO week number, as a decimal number (00--99).
+For example, January 1, 1993 is in week 53 of 1992. Thus, the year
+of its ISO week number is 1992, even though its year is 1993.
+Similarly, December 31, 1973 is in week 1 of 1974. Thus, the year
+of its ISO week number is 1974, even though its year is 1973.
+
+@item %G
+The full year of the ISO week number, as a decimal number.
+
+@item %h
+Equivalent to @samp{%b}.
+
+@item %H
+The hour (24-hour clock) as a decimal number (00--23).
+
+@item %I
+The hour (12-hour clock) as a decimal number (01--12).
+
+@item %j
+The day of the year as a decimal number (001--366).
+
+@item %m
+The month as a decimal number (01--12).
+
+@item %M
+The minute as a decimal number (00--59).
+
+@item %n
+A newline character (ASCII LF).
+
+@item %p
+The locale's equivalent of the AM/PM designations associated
+with a 12-hour clock.
+
+@item %r
+The locale's 12-hour clock time.
+(This is @samp{%I:%M:%S %p} in the @code{"C"} locale.)
+
+@item %R
+Equivalent to specifying @samp{%H:%M}.
+
+@item %S
+The second as a decimal number (00--60).
+
+@item %t
+A TAB character.
+
+@item %T
+Equivalent to specifying @samp{%H:%M:%S}.
+
+@item %u
+The weekday as a decimal number (1--7). Monday is day one.
+
+@item %U
+The week number of the year (the first Sunday as the first day of week one)
+as a decimal number (00--53).
+
+@c @cindex ISO 8601
+@item %V
+The week number of the year (the first Monday as the first
+day of week one) as a decimal number (01--53).
+The method for determining the week number is as specified by ISO 8601.
+(To wit: if the week containing January 1 has four or more days in the
+new year, then it is week one; otherwise it is week 53 of the previous year
+and the next week is week one.)
+
+@item %w
+The weekday as a decimal number (0--6). Sunday is day zero.
+
+@item %W
+The week number of the year (the first Monday as the first day of week one)
+as a decimal number (00--53).
+
+@item %x
+The locale's ``appropriate'' date representation.
+(This is @samp{%A %B %d %Y} in the @code{"C"} locale.)
+
+@item %X
+The locale's ``appropriate'' time representation.
+(This is @samp{%T} in the @code{"C"} locale.)
+
+@item %y
+The year modulo 100 as a decimal number (00--99).
+
+@item %Y
+The full year as a decimal number (e.g., 1995).
+
+@c @cindex RFC 822
+@c @cindex RFC 1036
+@item %z
+The timezone offset in a +HHMM format (e.g., the format necessary to
+produce RFC 822/RFC 1036 date headers).
+
+@item %Z
+The time zone name or abbreviation; no characters if
+no time zone is determinable.
+
+@item %Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH
+@itemx %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
+``Alternate representations'' for the specifications
+that use only the second letter (@samp{%c}, @samp{%C},
+and so on).@footnote{If you don't understand any of this, don't worry about
+it; these facilities are meant to make it easier to ``internationalize''
+programs.
+Other internationalization features are described in
+@ref{Internationalization}.}
+(These facilitate compliance with the POSIX @command{date} utility.)
+
+@item %%
+A literal @samp{%}.
+@end table
+
+If a conversion specifier is not one of the above, the behavior is
+undefined.@footnote{This is because ISO C leaves the
+behavior of the C version of @code{strftime} undefined and @command{gawk}
+uses the system's version of @code{strftime} if it's there.
+Typically, the conversion specifier either does not appear in the
+returned string or appears literally.}
+
+@c @cindex locale, definition of
+Informally, a @dfn{locale} is the geographic place in which a program
+is meant to run. For example, a common way to abbreviate the date
+September 4, 1991 in the United States is ``9/4/91.''
+In many countries in Europe, however, it is abbreviated ``4.9.91.''
+Thus, the @samp{%x} specification in a @code{"US"} locale might produce
+@samp{9/4/91}, while in a @code{"EUROPE"} locale, it might produce
+@samp{4.9.91}. The ISO C standard defines a default @code{"C"}
+locale, which is an environment that is typical of what most C programmers
+are used to.
+
+A public-domain C version of @code{strftime} is supplied with @command{gawk}
+for systems that are not yet fully standards-compliant.
+It supports all of the just listed format specifications.
+If that version is
+used to compile @command{gawk} (@pxref{Installation}),
+then the following additional format specifications are available:
+
+@table @code
+@item %k
+The hour (24-hour clock) as a decimal number (0--23).
+Single-digit numbers are padded with a space.
+
+@item %l
+The hour (12-hour clock) as a decimal number (1--12).
+Single-digit numbers are padded with a space.
+
+@item %N
+The ``Emperor/Era'' name.
+Equivalent to @code{%C}.
+
+@item %o
+The ``Emperor/Era'' year.
+Equivalent to @code{%y}.
+
+@item %s
+The time as a decimal timestamp in seconds since the epoch.
+
+@item %v
+The date in VMS format (e.g., @samp{20-JUN-1991}).
+@end table
+@c ENDOFRANGE strf
+
+Additionally, the alternate representations are recognized but their
+normal representations are used.
+
+@cindex @code{date} utility, POSIX
+@cindex POSIX @command{awk}, @code{date} utility and
+This example is an @command{awk} implementation of the POSIX
+@command{date} utility. Normally, the @command{date} utility prints the
+current date and time of day in a well-known format. However, if you
+provide an argument to it that begins with a @samp{+}, @command{date}
+copies nonformat specifier characters to the standard output and
+interprets the current time according to the format specifiers in
+the string. For example:
+
+@example
+$ date '+Today is %A, %B %d, %Y.'
+@print{} Today is Thursday, September 14, 2000.
+@end example
+
+Here is the @command{gawk} version of the @command{date} utility.
+It has a shell ``wrapper'' to handle the @option{-u} option,
+which requires that @command{date} run as if the time zone
+is set to UTC:
+
+@example
+#! /bin/sh
+#
+# date --- approximate the P1003.2 'date' command
+
+case $1 in
+-u) TZ=UTC0 # use UTC
+ export TZ
+ shift ;;
+esac
+
+@c FIXME: One day, change %d to %e, when C 99 is common.
+gawk 'BEGIN @{
+ format = "%a %b %d %H:%M:%S %Z %Y"
+ exitval = 0
+
+ if (ARGC > 2)
+ exitval = 1
+ else if (ARGC == 2) @{
+ format = ARGV[1]
+ if (format ~ /^\+/)
+ format = substr(format, 2) # remove leading +
+ @}
+ print strftime(format)
+ exit exitval
+@}' "$@@"
+@end example
+@c ENDOFRANGE tst
+@c ENDOFRANGE logftst
+@c ENDOFRANGE filogtst
+@c ENDOFRANGE gawtst
+
+@node Bitwise Functions
+@subsection Bit-Manipulation Functions of @command{gawk}
+@c STARTOFRANGE bit
+@cindex bitwise, operations
+@c STARTOFRANGE and
+@cindex AND bitwise operation
+@c STARTOFRANGE oro
+@cindex OR bitwise operation
+@c STARTOFRANGE xor
+@cindex XOR bitwise operation
+@c STARTOFRANGE opbit
+@cindex operations, bitwise
+@quotation
+@i{I can explain it for you, but I can't understand it for you.}@*
+Anonymous
+@end quotation
+
+Many languages provide the ability to perform @dfn{bitwise} operations
+on two integer numbers. In other words, the operation is performed on
+each successive pair of bits in the operands.
+Three common operations are bitwise AND, OR, and XOR.
+The operations are described in @ref{table-bitwise-ops}.
+
+@float Table,table-bitwise-ops
+@caption{Bitwise Operations}
+@ifnottex
+@ifnotdocbook
+@display
+ Bit Operator
+ | AND | OR | XOR
+ |---+---+---+---+---+---
+Operands | 0 | 1 | 0 | 1 | 0 | 1
+----------+---+---+---+---+---+---
+ 0 | 0 0 | 0 1 | 0 1
+ 1 | 0 1 | 1 1 | 1 0
+@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 Bit operator\hfil\cr
+\noalign{\smallskip}
+& &\multispan3\hfil AND\hfil&&\multispan3\hfil OR\hfil
+ &&\multispan3\hfil XOR\hfil\cr
+\bf Operands&&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
+<!-- FIXME: Fix ID and add xref in text. -->
+<table id="table-bitwise-ops">
+<title>Bitwise Operations</title>
+
+<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">Bit Operator</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">Operands</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>
+</table>
+@end docbook
+@end float
+
+@cindex bitwise, complement
+@cindex complement, bitwise
+As you can see, the result of an AND operation is 1 only when @emph{both}
+bits are 1.
+The result of an OR operation is 1 if @emph{either} bit is 1.
+The result of an XOR operation is 1 if either bit is 1,
+but not both.
+The next operation is the @dfn{complement}; the complement of 1 is 0 and
+the complement of 0 is 1. Thus, this operation ``flips'' all the bits
+of a given value.
+
+@cindex bitwise, shift
+@cindex left shift, bitwise
+@cindex right shift, bitwise
+@cindex shift, bitwise
+Finally, two other common operations are to shift the bits left or right.
+For example, if you have a bit string @samp{10111001} and you shift it
+right by three bits, you end up with @samp{00010111}.@footnote{This example
+shows that 0's come in on the left side. For @command{gawk}, this is
+always true, but in some languages, it's possible to have the left side
+fill with 1's. Caveat emptor.}
+@c Purposely decided to use 0's and 1's here. 2/2001.
+If you start over
+again with @samp{10111001} and shift it left by three bits, you end up
+with @samp{11001000}.
+@command{gawk} provides built-in functions that implement the
+bitwise operations just described. They are:
+
+@ignore
+@table @code
+@cindex @code{and} function (@command{gawk})
+@item and(@var{v1}, @var{v2})
+Return the bitwise AND of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{or} function (@command{gawk})
+@item or(@var{v1}, @var{v2})
+Return the bitwise OR of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{xor} function (@command{gawk})
+@item xor(@var{v1}, @var{v2})
+Return the bitwise XOR of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{compl} function (@command{gawk})
+@item compl(@var{val})
+Return the bitwise complement of @var{val}.
+
+@cindex @code{lshift} function (@command{gawk})
+@item lshift(@var{val}, @var{count})
+Return the value of @var{val}, shifted left by @var{count} bits.
+
+@cindex @code{rshift} function (@command{gawk})
+@item rshift(@var{val}, @var{count})
+Return the value of @var{val}, shifted right by @var{count} bits.
+@end table
+@end ignore
+
+@cindex @command{gawk}, bitwise operations in
+@multitable {@code{rshift(@var{val}, @var{count})}} {Return the value of @var{val}, shifted right by @var{count} bits.}
+@cindex @code{and} function (@command{gawk})
+@item @code{and(@var{v1}, @var{v2})}
+@tab Returns the bitwise AND of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{or} function (@command{gawk})
+@item @code{or(@var{v1}, @var{v2})}
+@tab Returns the bitwise OR of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{xor} function (@command{gawk})
+@item @code{xor(@var{v1}, @var{v2})}
+@tab Returns the bitwise XOR of the values provided by @var{v1} and @var{v2}.
+
+@cindex @code{compl} function (@command{gawk})
+@item @code{compl(@var{val})}
+@tab Returns the bitwise complement of @var{val}.
+
+@cindex @code{lshift} function (@command{gawk})
+@item @code{lshift(@var{val}, @var{count})}
+@tab Returns the value of @var{val}, shifted left by @var{count} bits.
+
+@cindex @code{rshift} function (@command{gawk})
+@item @code{rshift(@var{val}, @var{count})}
+@tab Returns the value of @var{val}, shifted right by @var{count} bits.
+@end multitable
+
+For all of these functions, first the double-precision floating-point value is
+converted to the widest C unsigned integer type, then the bitwise operation is
+performed. If the result cannot be represented exactly as a C @code{double},
+leading nonzero bits are removed one by one until it can be represented
+exactly. The result is then converted back into a C @code{double}. (If
+you don't understand this paragraph, don't worry about it.)
+
+Here is a user-defined function
+(@pxref{User-defined})
+that illustrates the use of these functions:
+
+@cindex @code{bits2str} user-defined function
+@cindex @code{testbits.awk} program
+@smallexample
+@group
+@c file eg/lib/bits2str.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 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 smallexample
+
+@noindent
+This program produces the following output when run:
+
+@smallexample
+$ gawk -f testbits.awk
+@print{} 123 = 01111011
+@print{} 0123 = 01010011
+@print{} 0x99 = 10011001
+@print{} compl(0x99) = 0xffffff66 = 11111111111111111111111101100110
+@print{} lshift(0x99, 2) = 0x264 = 0000001001100100
+@print{} rshift(0x99, 2) = 0x26 = 00100110
+@end smallexample
+
+@cindex numbers, converting, to strings
+@cindex strings, converting, numbers to
+@cindex converting, numbers, to strings
+The @code{bits2str} function turns a binary number into a string.
+The number @code{1} represents a binary value where the rightmost bit
+is set to 1. Using this mask,
+the function repeatedly checks the rightmost bit.
+ANDing the mask with the value indicates whether the
+rightmost bit is 1 or not. If so, a @code{"1"} is concatenated onto the front
+of the string.
+Otherwise, a @code{"0"} is added.
+The value is then shifted right by one bit and the loop continues
+until there are no more 1 bits.
+
+If the initial value is zero it returns a simple @code{"0"}.
+Otherwise, at the end, it pads the value with zeros to represent multiples
+of 8-bit quantities. This is typical in modern computers.
+
+The main code in the @code{BEGIN} rule shows the difference between the
+decimal and octal values for the same numbers
+(@pxref{Nondecimal-numbers}),
+and then demonstrates the
+results of the @code{compl}, @code{lshift}, and @code{rshift} functions.
+@c ENDOFRANGE bit
+@c ENDOFRANGE and
+@c ENDOFRANGE oro
+@c ENDOFRANGE xor
+@c ENDOFRANGE opbit
+
+@node I18N Functions
+@subsection Using @command{gawk}'s String-Translation Functions
+@cindex @command{gawk}, string-translation functions
+@cindex functions, string-translation
+@cindex internationalization
+@cindex @command{awk} programs, internationalizing
+
+@command{gawk} provides facilities for internationalizing @command{awk} programs.
+These include the functions described in the following list.
+The descriptions here are purposely brief.
+@xref{Internationalization},
+for the full story.
+Optional parameters are enclosed in square brackets ([ ]):
+
+@table @code
+@cindex @code{dcgettext} function (@command{gawk})
+@item dcgettext(@var{string} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
+This function returns the translation of @var{string} in
+text domain @var{domain} for locale category @var{category}.
+The default value for @var{domain} is the current value of @code{TEXTDOMAIN}.
+The default value for @var{category} is @code{"LC_MESSAGES"}.
+
+@cindex @code{dcngettext} function (@command{gawk})
+@item dcngettext(@var{string1}, @var{string2}, @var{number} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
+This function returns the plural form used for @var{number} of the
+translation of @var{string1} and @var{string2} in text domain
+@var{domain} for locale category @var{category}. @var{string1} is the
+English singular variant of a message, and @var{string2} the English plural
+variant of the same message.
+The default value for @var{domain} is the current value of @code{TEXTDOMAIN}.
+The default value for @var{category} is @code{"LC_MESSAGES"}.
+
+@cindex @code{bindtextdomain} function (@command{gawk})
+@item bindtextdomain(@var{directory} @r{[}, @var{domain}@r{]})
+This function allows you to specify the directory in which
+@command{gawk} will look for message translation files, in case they
+will not or cannot be placed in the ``standard'' locations
+(e.g., during testing).
+It returns the directory in which @var{domain} is ``bound.''
+
+The default @var{domain} is the value of @code{TEXTDOMAIN}.
+If @var{directory} is the null string (@code{""}), then
+@code{bindtextdomain} returns the current binding for the
+given @var{domain}.
+@end table
+@c ENDOFRANGE funcbi
+@c ENDOFRANGE bifunc
+
+@node User-defined
+@section User-Defined Functions
+
+@c STARTOFRANGE udfunc
+@cindex user-defined, functions
+@c STARTOFRANGE funcud
+@cindex functions, user-defined
+Complicated @command{awk} programs can often be simplified by defining
+your own functions. User-defined functions can be called just like
+built-in ones (@pxref{Function Calls}), but it is up to you to define
+them, i.e., to tell @command{awk} what they should do.
+
+@menu
+* Definition Syntax:: How to write definitions and what they mean.
+* Function Example:: An example function definition and what it
+ does.
+* Function Caveats:: Things to watch out for.
+* Return Statement:: Specifying the value a function returns.
+* Dynamic Typing:: How variable types can change at runtime.
+@end menu
+
+@node Definition Syntax
+@subsection Function Definition Syntax
+
+@c STARTOFRANGE fdef
+@cindex functions, defining
+Definitions of functions can appear anywhere between the rules of an
+@command{awk} program. Thus, the general form of an @command{awk} program is
+extended to include sequences of rules @emph{and} user-defined function
+definitions.
+There is no need to put the definition of a function
+before all uses of the function. This is because @command{awk} reads the
+entire program before starting to execute any of it.
+
+The definition of a function named @var{name} looks like this:
+@c NEXT ED: put [ ] around parameter list
+
+@example
+function @var{name}(@var{parameter-list})
+@{
+ @var{body-of-function}
+@}
+@end example
+
+@cindex names, functions
+@cindex functions, names of
+@cindex namespace issues, functions
+@noindent
+@var{name} is the name of the function to define. A valid function
+name is like a valid variable name: a sequence of letters, digits, and
+underscores that doesn't start with a digit.
+Within a single @command{awk} program, any particular name can only be
+used as a variable, array, or function.
+
+@c NEXT ED: parameter-list is an OPTIONAL list of ...
+@var{parameter-list} is a list of the function's arguments and local
+variable names, separated by commas. When the function is called,
+the argument names are used to hold the argument values given in
+the call. The local variables are initialized to the empty string.
+A function cannot have two parameters with the same name, nor may it
+have a parameter with the same name as the function itself.
+
+The @var{body-of-function} consists of @command{awk} statements. It is the
+most important part of the definition, because it says what the function
+should actually @emph{do}. The argument names exist to give the body a
+way to talk about the arguments; local variables exist to give the body
+places to keep temporary values.
+
+Argument names are not distinguished syntactically from local variable
+names. Instead, the number of arguments supplied when the function is
+called determines how many argument variables there are. Thus, if three
+argument values are given, the first three names in @var{parameter-list}
+are arguments and the rest are local variables.
+
+It follows that if the number of arguments is not the same in all calls
+to the function, some of the names in @var{parameter-list} may be
+arguments on some occasions and local variables on others. Another
+way to think of this is that omitted arguments default to the
+null string.
+
+@cindex programming conventions, functions, writing
+Usually when you write a function, you know how many names you intend to
+use for arguments and how many you intend to use as local variables. It is
+conventional to place some extra space between the arguments and
+the local variables, in order to document how your function is supposed to be used.
+
+@cindex variables, shadowing
+During execution of the function body, the arguments and local variable
+values hide, or @dfn{shadow}, any variables of the same names used in the
+rest of the program. The shadowed variables are not accessible in the
+function definition, because there is no way to name them while their
+names have been taken away for the local variables. All other variables
+used in the @command{awk} program can be referenced or set normally in the
+function's body.
+
+The arguments and local variables last only as long as the function body
+is executing. Once the body finishes, you can once again access the
+variables that were shadowed while the function was running.
+
+@cindex recursive functions
+@cindex functions, recursive
+The function body can contain expressions that call functions. They
+can even call this function, either directly or by way of another
+function. When this happens, we say the function is @dfn{recursive}.
+The act of a function calling itself is called @dfn{recursion}.
+
+@c @cindex @command{awk} language, POSIX version
+@c @cindex POSIX @command{awk}
+@cindex POSIX @command{awk}, @code{function} keyword in
+In many @command{awk} implementations, including @command{gawk},
+the keyword @code{function} may be
+abbreviated @code{func}. However, POSIX only specifies the use of
+the keyword @code{function}. This actually has some practical implications.
+If @command{gawk} is in POSIX-compatibility mode
+(@pxref{Options}), then the following
+statement does @emph{not} define a function:
+
+@example
+func foo() @{ a = sqrt($1) ; print a @}
+@end example
+
+@noindent
+Instead it defines a rule that, for each record, concatenates the value
+of the variable @samp{func} with the return value of the function @samp{foo}.
+If the resulting string is non-null, the action is executed.
+This is probably not what is desired. (@command{awk} accepts this input as
+syntactically valid, because functions may be used before they are defined
+in @command{awk} programs.)
+@c NEXT ED: This won't actually run, since foo() is undefined ...
+
+@cindex portability, functions@comma{} defining
+To ensure that your @command{awk} programs are portable, always use the
+keyword @code{function} when defining a function.
+
+@node Function Example
+@subsection Function Definition Examples
+
+Here is an example of a user-defined function, called @code{myprint}, that
+takes a number and prints it in a specific format:
+
+@example
+function myprint(num)
+@{
+ printf "%6.3g\n", num
+@}
+@end example
+
+@noindent
+To illustrate, here is an @command{awk} rule that uses our @code{myprint}
+function:
+
+@example
+$3 > 0 @{ myprint($3) @}
+@end example
+
+@noindent
+This program prints, in our special format, all the third fields that
+contain a positive number in our input. Therefore, when given the following:
+
+@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
+this program, using our function to format the results, prints:
+
+@example
+ 5.6
+ 21.2
+@end example
+
+This function deletes all the elements in an array:
+
+@example
+function delarray(a, i)
+@{
+ for (i in a)
+ delete a[i]
+@}
+@end example
+
+When working with arrays, it is often necessary to delete all the elements
+in an array and start over with a new list of elements
+(@pxref{Delete}).
+Instead of having
+to repeat this loop everywhere that you need to clear out
+an array, your program can just call @code{delarray}.
+(This guarantees portability. The use of @samp{delete @var{array}} to delete
+the contents of an entire array is a nonstandard extension.)
+
+The following is an example of a recursive function. It takes a string
+as an input parameter and returns the string in backwards order.
+Recursive functions must always have a test that stops the recursion.
+In this case, the recursion terminates when the starting position
+is zero, i.e., when there are no more characters left in the string.
+
+@cindex @code{rev} user-defined function
+@example
+function rev(str, start)
+@{
+ if (start == 0)
+ return ""
+
+ return (substr(str, start, 1) rev(str, start - 1))
+@}
+@end example
+
+If this function is in a file named @file{rev.awk}, it can be tested
+this way:
+
+@example
+$ echo "Don't Panic!" |
+> gawk --source '@{ print rev($0, length($0)) @}' -f rev.awk
+@print{} !cinaP t'noD
+@end example
+
+The C @code{ctime} function takes a timestamp and returns it in a string,
+formatted in a well-known fashion.
+The following example uses the built-in @code{strftime} function
+(@pxref{Time Functions})
+to create an @command{awk} version of @code{ctime}:
+
+@cindex @code{ctime} user-defined function
+@c FIXME: One day, change %d to %e, when C 99 is common.
+@example
+@c file eg/lib/ctime.awk
+# ctime.awk
+#
+# awk version of C ctime(3) function
+
+function ctime(ts, format)
+@{
+ format = "%a %b %d %H:%M:%S %Z %Y"
+ if (ts == 0)
+ ts = systime() # use current time as default
+ return strftime(format, ts)
+@}
+@c endfile
+@end example
+@c ENDOFRANGE fdef
+
+@node Function Caveats
+@subsection Calling User-Defined Functions
+
+@c STARTOFRANGE fudc
+@cindex functions, user-defined, calling
+@dfn{Calling a function} means causing the function to run and do its job.
+A function call is an expression and its value is the value returned by
+the function.
+
+A function call consists of the function name followed by the arguments
+in parentheses. @command{awk} expressions are what you write in the
+call for the arguments. Each time the call is executed, these
+expressions are evaluated, and the values are the actual arguments. For
+example, here is a call to @code{foo} with three arguments (the first
+being a string concatenation):
+
+@example
+foo(x y, "lose", 4 * z)
+@end example
+
+@strong{Caution:} Whitespace characters (spaces and tabs) are not allowed
+between the function name and the open-parenthesis of the argument list.
+If you write whitespace by mistake, @command{awk} might think that you mean
+to concatenate a variable with an expression in parentheses. However, it
+notices that you used a function name and not a variable name, and reports
+an error.
+
+@cindex call by value
+When a function is called, it is given a @emph{copy} of the values of
+its arguments. This is known as @dfn{call by value}. The caller may use
+a variable as the expression for the argument, but the called function
+does not know this---it only knows what value the argument had. For
+example, if you write the following code:
+
+@example
+foo = "bar"
+z = myfunc(foo)
+@end example
+
+@noindent
+then you should not think of the argument to @code{myfunc} as being
+``the variable @code{foo}.'' Instead, think of the argument as the
+string value @code{"bar"}.
+If the function @code{myfunc} alters the values of its local variables,
+this has no effect on any other variables. Thus, if @code{myfunc}
+does this:
+
+@example
+function myfunc(str)
+@{
+ print str
+ str = "zzz"
+ print str
+@}
+@end example
+
+@noindent
+to change its first argument variable @code{str}, it does @emph{not}
+change the value of @code{foo} in the caller. The role of @code{foo} in
+calling @code{myfunc} ended when its value (@code{"bar"}) was computed.
+If @code{str} also exists outside of @code{myfunc}, the function body
+cannot alter this outer value, because it is shadowed during the
+execution of @code{myfunc} and cannot be seen or changed from there.
+
+@cindex call by reference
+@cindex arrays, as parameters to functions
+@cindex functions, arrays as parameters to
+However, when arrays are the parameters to functions, they are @emph{not}
+copied. Instead, the array itself is made available for direct manipulation
+by the function. This is usually called @dfn{call by reference}.
+Changes made to an array parameter inside the body of a function @emph{are}
+visible outside that function.
+
+@quotation NOTE
+Changing an array parameter inside a function
+can be very dangerous if you do not watch what you are doing.
+For example:
+
+@example
+function changeit(array, ind, nvalue)
+@{
+ array[ind] = nvalue
+@}
+
+BEGIN @{
+ a[1] = 1; a[2] = 2; a[3] = 3
+ changeit(a, 2, "two")
+ printf "a[1] = %s, a[2] = %s, a[3] = %s\n",
+ a[1], a[2], a[3]
+@}
+@end example
+
+@noindent
+prints @samp{a[1] = 1, a[2] = two, a[3] = 3}, because
+@code{changeit} stores @code{"two"} in the second element of @code{a}.
+@end quotation
+
+@cindex undefined functions
+@cindex functions, undefined
+Some @command{awk} implementations allow you to call a function that
+has not been defined. They only report a problem at runtime when the
+program actually tries to call the function. For example:
+
+@example
+BEGIN @{
+ if (0)
+ foo()
+ else
+ bar()
+@}
+function bar() @{ @dots{} @}
+# note that `foo' is not defined
+@end example
+
+@noindent
+Because the @samp{if} statement will never be true, it is not really a
+problem that @code{foo} has not been defined. Usually, though, it is a
+problem if a program calls an undefined function.
+
+@cindex lint checking, undefined functions
+If @option{--lint} is specified
+(@pxref{Options}),
+@command{gawk} reports calls to undefined functions.
+
+@cindex portability, @code{next} statement in user-defined functions
+Some @command{awk} implementations generate a runtime
+error if you use the @code{next} statement
+(@pxref{Next Statement})
+inside a user-defined function.
+@command{gawk} does not have this limitation.
+@c ENDOFRANGE fudc
+
+@node Return Statement
+@subsection The @code{return} Statement
+@cindex @code{return} statement@comma{} user-defined functions
+
+The body of a user-defined function can contain a @code{return} statement.
+This statement returns control to the calling part of the @command{awk} program. It
+can also be used to return a value for use in the rest of the @command{awk}
+program. It looks like this:
+
+@example
+return @r{[}@var{expression}@r{]}
+@end example
+
+The @var{expression} part is optional. If it is omitted, then the returned
+value is undefined, and therefore, unpredictable.
+
+A @code{return} statement with no value expression is assumed at the end of
+every function definition. So if control reaches the end of the function
+body, then the function returns an unpredictable value. @command{awk}
+does @emph{not} warn you if you use the return value of such a function.
+
+Sometimes, you want to write a function for what it does, not for
+what it returns. Such a function corresponds to a @code{void} function
+in C or to a @code{procedure} in Pascal. Thus, it may be appropriate to not
+return any value; simply bear in mind that if you use the return
+value of such a function, you do so at your own risk.
+
+The following is an example of a user-defined function that returns a value
+for the largest number among the elements of an array:
+
+@example
+function maxelt(vec, i, ret)
+@{
+ for (i in vec) @{
+ if (ret == "" || vec[i] > ret)
+ ret = vec[i]
+ @}
+ return ret
+@}
+@end example
+
+@cindex programming conventions, function parameters
+@noindent
+You call @code{maxelt} with one argument, which is an array name. The local
+variables @code{i} and @code{ret} are not intended to be arguments;
+while there is nothing to stop you from passing more than one argument
+to @code{maxelt}, the results would be strange. The extra space before
+@code{i} in the function parameter list indicates that @code{i} and
+@code{ret} are not supposed to be arguments.
+You should follow this convention when defining functions.
+
+The following program uses the @code{maxelt} function. It loads an
+array, calls @code{maxelt}, and then reports the maximum number in that
+array:
+
+@example
+function maxelt(vec, i, ret)
+@{
+ for (i in vec) @{
+ if (ret == "" || vec[i] > ret)
+ ret = vec[i]
+ @}
+ return ret
+@}
+
+# Load all fields of each record into nums.
+@{
+ for(i = 1; i <= NF; i++)
+ nums[NR, i] = $i
+@}
+
+END @{
+ print maxelt(nums)
+@}
+@end example
+
+Given the following 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
+the program reports (predictably) that @code{99385} is the largest number
+in the array.
+
+@node Dynamic Typing
+@subsection Functions and Their Effects on Variable Typing
+
+@command{awk} is a very fluid language.
+It is possible that @command{awk} can't tell if an identifier
+represents a regular variable or an array until runtime.
+Here is an annotated sample program:
+
+@example
+function foo(a)
+@{
+ a[1] = 1 # parameter is an array
+@}
+
+BEGIN @{
+ b = 1
+ foo(b) # invalid: fatal type mismatch
+
+ foo(x) # x uninitialized, becomes an array dynamically
+ x = 1 # now not allowed, runtime error
+@}
+@end example
+
+Usually, such things aren't a big issue, but it's worth
+being aware of them.
+@c ENDOFRANGE udfunc
+@c ENDOFRANGE funcud
+
+@node Internationalization
+@chapter Internationalization with @command{gawk}
+
+Once upon a time, computer makers
+wrote software that worked only in English.
+Eventually, hardware and software vendors noticed that if their
+systems worked in the native languages of non-English-speaking
+countries, they were able to sell more systems.
+As a result, internationalization and localization
+of programs and software systems became a common practice.
+
+@c STARTOFRANGE inloc
+@cindex internationalization, localization
+@cindex @command{gawk}, internationalization and, See internationalization
+@cindex internationalization, localization, @command{gawk} and
+Until recently, the ability to provide internationalization
+was largely restricted to programs written in C and C++.
+This @value{CHAPTER} describes the underlying library @command{gawk}
+uses for internationalization, as well as how
+@command{gawk} makes internationalization
+features available at the @command{awk} program level.
+Having internationalization available at the @command{awk} level
+gives software developers additional flexibility---they are no
+longer required to write in C when internationalization is
+a requirement.
+
+@menu
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @code{gettext} works.
+* Programmer i18n:: Features for the programmer.
+* Translator i18n:: Features for the translator.
+* I18N Example:: A simple i18n example.
+* Gawk I18N:: @command{gawk} is also internationalized.
+@end menu
+
+@node I18N and L10N
+@section Internationalization and Localization
+
+@cindex internationalization
+@cindex localization, See internationalization@comma{} localization
+@cindex localization
+@dfn{Internationalization} means writing (or modifying) a program once,
+in such a way that it can use multiple languages without requiring
+further source-code changes.
+@dfn{Localization} means providing the data necessary for an
+internationalized program to work in a particular language.
+Most typically, these terms refer to features such as the language
+used for printing error messages, the language used to read
+responses, and information related to how numerical and
+monetary values are printed and read.
+
+@node Explaining gettext
+@section GNU @code{gettext}
+
+@cindex internationalizing a program
+@c STARTOFRANGE gettex
+@cindex @code{gettext} library
+The facilities in GNU @code{gettext} focus on messages; strings printed
+by a program, either directly or via formatting with @code{printf} or
+@code{sprintf}.@footnote{For some operating systems, the @command{gawk}
+port doesn't support GNU @code{gettext}. This applies most notably to
+the PC operating systems. As such, these features are not available
+if you are using one of those operating systems. Sorry.}
+
+@cindex portability, @code{gettext} library and
+When using GNU @code{gettext}, each application has its own
+@dfn{text domain}. This is a unique name, such as @samp{kpilot} or @samp{gawk},
+that identifies the application.
+A complete application may have multiple components---programs written
+in C or C++, as well as scripts written in @command{sh} or @command{awk}.
+All of the components use the same text domain.
+
+To make the discussion concrete, assume we're writing an application
+named @command{guide}. Internationalization consists of the
+following steps, in this order:
+
+@enumerate
+@item
+The programmer goes
+through the source for all of @command{guide}'s components
+and marks each string that is a candidate for translation.
+For example, @code{"`-F': option required"} is a good candidate for translation.
+A table with strings of option names is not (e.g., @command{gawk}'s
+@option{--profile} option should remain the same, no matter what the local
+language).
+
+@cindex @code{textdomain} function (C library)
+@item
+The programmer indicates the application's text domain
+(@code{"guide"}) to the @code{gettext} library,
+by calling the @code{textdomain} function.
+
+@item
+Messages from the application are extracted from the source code and
+collected into a portable object file (@file{guide.po}),
+which lists the strings and their translations.
+The translations are initially empty.
+The original (usually English) messages serve as the key for
+lookup of the translations.
+
+@cindex @code{.po} files
+@cindex files, @code{.po}
+@cindex portable object files
+@cindex files, portable object
+@item
+For each language with a translator, @file{guide.po}
+is copied and translations are created and shipped with the application.
+
+@cindex @code{.mo} files
+@cindex files, @code{.mo}
+@cindex message object files
+@cindex files, message object
+@item
+Each language's @file{.po} file is converted into a binary
+message object (@file{.mo}) file.
+A message object file contains the original messages and their
+translations in a binary format that allows fast lookup of translations
+at runtime.
+
+@item
+When @command{guide} is built and installed, the binary translation files
+are installed in a standard place.
+
+@cindex @code{bindtextdomain} function (C library)
+@item
+For testing and development, it is possible to tell @code{gettext}
+to use @file{.mo} files in a different directory than the standard
+one by using the @code{bindtextdomain} function.
+
+@cindex @code{.mo} files, specifying directory of
+@cindex files, @code{.mo}, specifying directory of
+@cindex message object files, specifying directory of
+@cindex files, message object, specifying directory of
+@item
+At runtime, @command{guide} looks up each string via a call
+to @code{gettext}. The returned string is the translated string
+if available, or the original string if not.
+
+@item
+If necessary, it is possible to access messages from a different
+text domain than the one belonging to the application, without
+having to switch the application's default text domain back
+and forth.
+@end enumerate
+
+@cindex @code{gettext} function (C library)
+In C (or C++), the string marking and dynamic translation lookup
+are accomplished by wrapping each string in a call to @code{gettext}:
+
+@example
+printf(gettext("Don't Panic!\n"));
+@end example
+
+The tools that extract messages from source code pull out all
+strings enclosed in calls to @code{gettext}.
+
+@cindex @code{_} (underscore), @code{_} C macro
+@cindex underscore (@code{_}), @code{_} C macro
+The GNU @code{gettext} developers, recognizing that typing
+@samp{gettext} over and over again is both painful and ugly to look
+at, use the macro @samp{_} (an underscore) to make things easier:
+
+@example
+/* In the standard header file: */
+#define _(str) gettext(str)
+
+/* In the program text: */
+printf(_("Don't Panic!\n"));
+@end example
+
+@cindex internationalization, localization, locale categories
+@cindex @code{gettext} library, locale categories
+@cindex locale categories
+@noindent
+This reduces the typing overhead to just three extra characters per string
+and is considerably easier to read as well.
+There are locale @dfn{categories}
+for different types of locale-related information.
+The defined locale categories that @code{gettext} knows about are:
+
+@table @code
+@cindex @code{LC_MESSAGES} locale category
+@item LC_MESSAGES
+Text messages. This is the default category for @code{gettext}
+operations, but it is possible to supply a different one explicitly,
+if necessary. (It is almost never necessary to supply a different category.)
+
+@cindex sorting characters in different languages
+@cindex @code{LC_COLLATE} locale category
+@item LC_COLLATE
+Text-collation information; i.e., how different characters
+and/or groups of characters sort in a given language.
+
+@cindex @code{LC_CTYPE} locale category
+@item LC_CTYPE
+Character-type information (alphabetic, digit, upper- or lowercase, and
+so on).
+This information is accessed via the
+POSIX character classes in regular expressions,
+such as @code{/[[:alnum:]]/}
+(@pxref{Regexp Operators}).
+
+@cindex monetary information, localization
+@cindex currency symbols, localization
+@cindex @code{LC_MONETARY} locale category
+@item LC_MONETARY
+Monetary information, such as the currency symbol, and whether the
+symbol goes before or after a number.
+
+@cindex @code{LC_NUMERIC} locale category
+@item LC_NUMERIC
+Numeric information, such as which characters to use for the decimal
+point and the thousands separator.@footnote{Americans
+use a comma every three decimal places and a period for the decimal
+point, while many Europeans do exactly the opposite:
+@code{1,234.56} versus @code{1.234,56}.}
+
+@cindex @code{LC_RESPONSE} locale category
+@item LC_RESPONSE
+Response information, such as how ``yes'' and ``no'' appear in the
+local language, and possibly other information as well.
+
+@cindex time, localization and
+@cindex dates, information related to@comma{} localization
+@cindex @code{LC_TIME} locale category
+@item LC_TIME
+Time- and date-related information, such as 12- or 24-hour clock, month printed
+before or after day in a date, local month abbreviations, and so on.
+
+@cindex @code{LC_ALL} locale category
+@item LC_ALL
+All of the above. (Not too useful in the context of @code{gettext}.)
+@end table
+@c ENDOFRANGE gettex
+
+@node Programmer i18n
+@section Internationalizing @command{awk} Programs
+@c STARTOFRANGE inap
+@cindex @command{awk} programs, internationalizing
+
+@command{gawk} provides the following variables and functions for
+internationalization:
+
+@table @code
+@cindex @code{TEXTDOMAIN} variable
+@item TEXTDOMAIN
+This variable indicates the application's text domain.
+For compatibility with GNU @code{gettext}, the default
+value is @code{"messages"}.
+
+@cindex internationalization, localization, marked strings
+@cindex strings, for localization
+@item _"your message here"
+String constants marked with a leading underscore
+are candidates for translation at runtime.
+String constants without a leading underscore are not translated.
+
+@cindex @code{dcgettext} function (@command{gawk})
+@item dcgettext(@var{string} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
+This built-in function returns the translation of @var{string} in
+text domain @var{domain} for locale category @var{category}.
+The default value for @var{domain} is the current value of @code{TEXTDOMAIN}.
+The default value for @var{category} is @code{"LC_MESSAGES"}.
+
+If you supply a value for @var{category}, it must be a string equal to
+one of the known locale categories described in
+@ifnotinfo
+the previous @value{SECTION}.
+@end ifnotinfo
+@ifinfo
+@ref{Explaining gettext}.
+@end ifinfo
+You must also supply a text domain. Use @code{TEXTDOMAIN} if
+you want to use the current domain.
+
+@strong{Caution:} The order of arguments to the @command{awk} version
+of the @code{dcgettext} function is purposely different from the order for
+the C version. The @command{awk} version's order was
+chosen to be simple and to allow for reasonable @command{awk}-style
+default arguments.
+
+@cindex @code{dcngettext} function (@command{gawk})
+@item dcngettext(@var{string1}, @var{string2}, @var{number} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
+This built-in function returns the plural form used for @var{number} of the
+translation of @var{string1} and @var{string2} in text domain
+@var{domain} for locale category @var{category}. @var{string1} is the
+English singular variant of a message, and @var{string2} the English plural
+variant of the same message.
+The default value for @var{domain} is the current value of @code{TEXTDOMAIN}.
+The default value for @var{category} is @code{"LC_MESSAGES"}.
+
+The same remarks as for the @code{dcgettext} function apply.
+
+@cindex @code{.mo} files, specifying directory of
+@cindex files, @code{.mo}, specifying directory of
+@cindex message object files, specifying directory of
+@cindex files, message object, specifying directory of
+@cindex @code{bindtextdomain} function (@command{gawk})
+@item bindtextdomain(@var{directory} @r{[}, @var{domain}@r{]})
+This built-in function allows you to specify the directory in which
+@code{gettext} looks for @file{.mo} files, in case they
+will not or cannot be placed in the standard locations
+(e.g., during testing).
+It returns the directory in which @var{domain} is ``bound.''
+
+The default @var{domain} is the value of @code{TEXTDOMAIN}.
+If @var{directory} is the null string (@code{""}), then
+@code{bindtextdomain} returns the current binding for the
+given @var{domain}.
+@end table
+
+To use these facilities in your @command{awk} program, follow the steps
+outlined in
+@ifnotinfo
+the previous @value{SECTION},
+@end ifnotinfo
+@ifinfo
+@ref{Explaining gettext},
+@end ifinfo
+like so:
+
+@enumerate
+@cindex @code{BEGIN} pattern, @code{TEXTDOMAIN} variable and
+@cindex @code{TEXTDOMAIN} variable, @code{BEGIN} pattern and
+@item
+Set the variable @code{TEXTDOMAIN} to the text domain of
+your program. This is best done in a @code{BEGIN} rule
+(@pxref{BEGIN/END}),
+or it can also be done via the @option{-v} command-line
+option (@pxref{Options}):
+
+@example
+BEGIN @{
+ TEXTDOMAIN = "guide"
+ @dots{}
+@}
+@end example
+
+@cindex @code{_} (underscore), translatable string
+@cindex underscore (@code{_}), translatable string
+@item
+Mark all translatable strings with a leading underscore (@samp{_})
+character. It @emph{must} be adjacent to the opening
+quote of the string. For example:
+
+@example
+print _"hello, world"
+x = _"you goofed"
+printf(_"Number of users is %d\n", nusers)
+@end example
+
+@item
+If you are creating strings dynamically, you can
+still translate them, using the @code{dcgettext}
+built-in function:
+
+@example
+message = nusers " users logged in"
+message = dcgettext(message, "adminprog")
+print message
+@end example
+
+Here, the call to @code{dcgettext} supplies a different
+text domain (@code{"adminprog"}) in which to find the
+message, but it uses the default @code{"LC_MESSAGES"} category.
+
+@cindex @code{LC_MESSAGES} locale category, @code{bindtextdomain} function (@command{gawk})
+@item
+During development, you might want to put the @file{.mo}
+file in a private directory for testing. This is done
+with the @code{bindtextdomain} built-in function:
+
+@example
+BEGIN @{
+ TEXTDOMAIN = "guide" # our text domain
+ if (Testing) @{
+ # where to find our files
+ bindtextdomain("testdir")
+ # joe is in charge of adminprog
+ bindtextdomain("../joe/testdir", "adminprog")
+ @}
+ @dots{}
+@}
+@end example
+
+@end enumerate
+
+@xref{I18N Example},
+for an example program showing the steps to create
+and use translations from @command{awk}.
+
+@node Translator i18n
+@section Translating @command{awk} Programs
+
+@cindex @code{.po} files
+@cindex files, @code{.po}
+@cindex portable object files
+@cindex files, portable object
+Once a program's translatable strings have been marked, they must
+be extracted to create the initial @file{.po} file.
+As part of translation, it is often helpful to rearrange the order
+in which arguments to @code{printf} are output.
+
+@command{gawk}'s @option{--gen-po} command-line option extracts
+the messages and is discussed next.
+After that, @code{printf}'s ability to
+rearrange the order for @code{printf} arguments at runtime
+is covered.
+
+@menu
+* String Extraction:: Extracting marked strings.
+* Printf Ordering:: Rearranging @code{printf} arguments.
+* I18N Portability:: @command{awk}-level portability issues.
+@end menu
+
+@node String Extraction
+@subsection Extracting Marked Strings
+@cindex strings, extracting
+@cindex marked strings@comma{} extracting
+@cindex @code{--gen-po} option
+@cindex command-line options, string extraction
+@cindex string extraction (internationalization)
+@cindex marked string extraction (internationalization)
+@cindex extraction, of marked strings (internationalization)
+
+@cindex @code{--gen-po} option
+Once your @command{awk} program is working, and all the strings have
+been marked and you've set (and perhaps bound) the text domain,
+it is time to produce translations.
+First, use the @option{--gen-po} command-line option to create
+the initial @file{.po} file:
+
+@example
+$ gawk --gen-po -f guide.awk > guide.po
+@end example
+
+@cindex @code{xgettext} utility
+When run with @option{--gen-po}, @command{gawk} does not execute your
+program. Instead, it parses it as usual and prints all marked strings
+to standard output in the format of a GNU @code{gettext} Portable Object
+file. Also included in the output are any constant strings that
+appear as the first argument to @code{dcgettext} or as the first and
+second argument to @code{dcngettext}.@footnote{Starting with @code{gettext}
+version 0.11.5, the @command{xgettext} utility that comes with GNU
+@code{gettext} can handle @file{.awk} files.}
+@xref{I18N Example},
+for the full list of steps to go through to create and test
+translations for @command{guide}.
+
+@node Printf Ordering
+@subsection Rearranging @code{printf} Arguments
+
+@cindex @code{printf} statement, positional specifiers
+@cindex positional specifiers@comma{} @code{printf} statement
+Format strings for @code{printf} and @code{sprintf}
+(@pxref{Printf})
+present a special problem for translation.
+Consider the following:@footnote{This example is borrowed
+from the GNU @code{gettext} manual.}
+
+@c line broken here only for smallbook format
+@example
+printf(_"String `%s' has %d characters\n",
+ string, length(string)))
+@end example
+
+A possible German translation for this might be:
+
+@example
+"%d Zeichen lang ist die Zeichenkette `%s'\n"
+@end example
+
+The problem should be obvious: the order of the format
+specifications is different from the original!
+Even though @code{gettext} can return the translated string
+at runtime,
+it cannot change the argument order in the call to @code{printf}.
+
+To solve this problem, @code{printf} format specificiers may have
+an additional optional element, which we call a @dfn{positional specifier}.
+For example:
+
+@example
+"%2$d Zeichen lang ist die Zeichenkette `%1$s'\n"
+@end example
+
+Here, the positional specifier consists of an integer count, which indicates which
+argument to use, and a @samp{$}. Counts are one-based, and the
+format string itself is @emph{not} included. Thus, in the following
+example, @samp{string} is the first argument and @samp{length(string)} is the second:
+
+@example
+$ gawk 'BEGIN @{
+> string = "Dont Panic"
+> printf _"%2$d characters live in \"%1$s\"\n",
+> string, length(string)
+> @}'
+@print{} 10 characters live in "Dont Panic"
+@end example
+
+If present, positional specifiers come first in the format specification,
+before the flags, the field width, and/or the precision.
+
+Positional specifiers can be used with the dynamic field width and
+precision capability:
+
+@example
+$ gawk 'BEGIN @{
+> printf("%*.*s\n", 10, 20, "hello")
+> printf("%3$*2$.*1$s\n", 20, 10, "hello")
+> @}'
+@print{} hello
+@print{} hello
+@end example
+
+@quotation NOTE
+When using @samp{*} with a positional specifier, the @samp{*}
+comes first, then the integer position, and then the @samp{$}.
+This is somewhat counterintutive.
+@end quotation
+
+@cindex @code{printf} statement, positional specifiers, mixing with regular formats
+@cindex positional specifiers@comma{} @code{printf} statement, mixing with regular formats
+@cindex format specifiers, mixing regular with positional specifiers
+@command{gawk} does not allow you to mix regular format specifiers
+and those with positional specifiers in the same string:
+
+@smallexample
+$ gawk 'BEGIN @{ printf _"%d %3$s\n", 1, 2, "hi" @}'
+@error{} gawk: cmd. line:1: fatal: must use `count$' on all formats or none
+@end smallexample
+
+@quotation NOTE
+There are some pathological cases that @command{gawk} may fail to
+diagnose. In such cases, the output may not be what you expect.
+It's still a bad idea to try mixing them, even if @command{gawk}
+doesn't detect it.
+@end quotation
+
+Although positional specifiers can be used directly in @command{awk} programs,
+their primary purpose is to help in producing correct translations of
+format strings into languages different from the one in which the program
+is first written.
+
+@node I18N Portability
+@subsection @command{awk} Portability Issues
+
+@cindex portability, internationalization and
+@cindex internationalization, localization, portability and
+@command{gawk}'s internationalization features were purposely chosen to
+have as little impact as possible on the portability of @command{awk}
+programs that use them to other versions of @command{awk}.
+Consider this program:
+
+@example
+BEGIN @{
+ TEXTDOMAIN = "guide"
+ if (Test_Guide) # set with -v
+ bindtextdomain("/test/guide/messages")
+ print _"don't panic!"
+@}
+@end example
+
+@noindent
+As written, it won't work on other versions of @command{awk}.
+However, it is actually almost portable, requiring very little
+change:
+
+@itemize @bullet
+@cindex @code{TEXTDOMAIN} variable, portability and
+@item
+Assignments to @code{TEXTDOMAIN} won't have any effect,
+since @code{TEXTDOMAIN} is not special in other @command{awk} implementations.
+
+@item
+Non-GNU versions of @command{awk} treat marked strings
+as the concatenation of a variable named @code{_} with the string
+following it.@footnote{This is good fodder for an ``Obfuscated
+@command{awk}'' contest.} Typically, the variable @code{_} has
+the null string (@code{""}) as its value, leaving the original string constant as
+the result.
+
+@item
+By defining ``dummy'' functions to replace @code{dcgettext}, @code{dcngettext}
+and @code{bindtextdomain}, the @command{awk} program can be made to run, but
+all the messages are output in the original language.
+For example:
+
+@cindex @code{bindtextdomain} function (@command{gawk}), portability and
+@cindex @code{dcgettext} function (@command{gawk}), portability and
+@cindex @code{dcngettext} function (@command{gawk}), portability and
+@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
+The use of positional specifications in @code{printf} or
+@code{sprintf} is @emph{not} portable.
+To support @code{gettext} at the C level, many systems' C versions of
+@code{sprintf} do support positional specifiers. But it works only if
+enough arguments are supplied in the function call. Many versions of
+@command{awk} pass @code{printf} formats and arguments unchanged to the
+underlying C library version of @code{sprintf}, but only one format and
+argument at a time. What happens if a positional specification is
+used is anybody's guess.
+However, since the positional specifications are primarily for use in
+@emph{translated} format strings, and since non-GNU @command{awk}s never
+retrieve the translated string, this should not be a problem in practice.
+@end itemize
+@c ENDOFRANGE inap
+
+@node I18N Example
+@section A Simple Internationalization Example
+
+Now let's look at a step-by-step example of how to internationalize and
+localize a simple @command{awk} program, using @file{guide.awk} as our
+original source:
+
+@example
+@c file eg/prog/guide.awk
+BEGIN @{
+ TEXTDOMAIN = "guide"
+ bindtextdomain(".") # for testing
+ print _"Don't Panic"
+ print _"The Answer Is", 42
+ print "Pardon me, Zaphod who?"
+@}
+@c endfile
+@end example
+
+@noindent
+Run @samp{gawk --gen-po} to create the @file{.po} file:
+
+@example
+$ gawk --gen-po -f guide.awk > guide.po
+@end example
+
+@noindent
+This produces:
+
+@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
+
+This original portable object file is saved and reused for each language
+into which the application is translated. The @code{msgid}
+is the original string and the @code{msgstr} is the translation.
+
+@quotation NOTE
+Strings not marked with a leading underscore do not
+appear in the @file{guide.po} file.
+@end quotation
+
+Next, the messages must be translated.
+Here is a translation to a hypothetical dialect of English,
+called ``Mellow'':@footnote{Perhaps it would be better if it were
+called ``Hippy.'' Ah, well.}
+
+@example
+@group
+$ cp guide.po guide-mellow.po
+@var{Add translations to} guide-mellow.po @dots{}
+@end group
+@end example
+
+@noindent
+Following are the translations:
+
+@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
+The next step is to make the directory to hold the binary message object
+file and then to create the @file{guide.mo} file.
+The directory layout shown here is standard for GNU @code{gettext} on
+GNU/Linux systems. Other versions of @code{gettext} may use a different
+layout:
+
+@example
+$ mkdir en_US en_US/LC_MESSAGES
+@end example
+
+@cindex @code{.po} files, converting to @code{.mo}
+@cindex files, @code{.po}, converting to @code{.mo}
+@cindex @code{.mo} files, converting from @code{.po}
+@cindex files, @code{.mo}, converting from @code{.po}
+@cindex portable object files, converting to message object files
+@cindex files, portable object, converting to message object files
+@cindex message object files, converting from portable object files
+@cindex files, message object, converting from portable object files
+@cindex @command{msgfmt} utility
+The @command{msgfmt} utility does the conversion from human-readable
+@file{.po} file to machine-readable @file{.mo} file.
+By default, @command{msgfmt} creates a file named @file{messages}.
+This file must be renamed and placed in the proper directory so that
+@command{gawk} can find it:
+
+@example
+$ msgfmt guide-mellow.po
+$ mv messages en_US/LC_MESSAGES/guide.mo
+@end example
+
+Finally, we run the program to test it:
+
+@example
+$ gawk -f guide.awk
+@print{} Hey man, relax!
+@print{} Like, the scoop is 42
+@print{} Pardon me, Zaphod who?
+@end example
+
+If the three replacement functions for @code{dcgettext}, @code{dcngettext}
+and @code{bindtextdomain}
+(@pxref{I18N Portability})
+are in a file named @file{libintl.awk},
+then we can run @file{guide.awk} unchanged as follows:
+
+@example
+$ 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 I18N
+@section @command{gawk} Can Speak Your Language
+
+As of @value{PVERSION} 3.1, @command{gawk} itself has been internationalized
+using the GNU @code{gettext} package.
+@ifinfo
+(GNU @code{gettext} is described in
+complete detail in
+@ref{Top}.)
+@end ifinfo
+@ifnotinfo
+(GNU @code{gettext} is described in
+complete detail in
+@cite{GNU gettext tools}.)
+@end ifnotinfo
+As of this writing, the latest version of GNU @code{gettext} is
+@uref{ftp://ftp.gnu.org/gnu/gettext/gettext-0.11.5.tar.gz, @value{PVERSION} 0.11.5}.
+
+If a translation of @command{gawk}'s messages exists,
+then @command{gawk} produces usage messages, warnings,
+and fatal errors in the local language.
+@c ENDOFRANGE inloc
+
+@node Advanced Features
+@chapter Advanced Features of @command{gawk}
+@cindex advanced features, network connections, See Also networks, connections
+@c STARTOFRANGE gawadv
+@cindex @command{gawk}, features, advanced
+@c STARTOFRANGE advgaw
+@cindex advanced features, @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
+@quotation
+@i{Write documentation as if whoever reads it is
+a violent psychopath who knows where you live.}@*
+Steve English, as quoted by Peter Langston
+@end quotation
+
+This @value{CHAPTER} discusses advanced features in @command{gawk}.
+It's a bit of a ``grab bag'' of items that are otherwise unrelated
+to each other.
+First, a command-line option allows @command{gawk} to recognize
+nondecimal numbers in input data, not just in @command{awk}
+programs. Next, two-way I/O, discussed briefly in earlier parts of this
+@value{DOCUMENT}, is described in full detail, along with the basics
+of TCP/IP networking and BSD portal files. Finally, @command{gawk}
+can @dfn{profile} an @command{awk} program, making it possible to tune
+it for performance.
+
+@ref{Dynamic Extensions},
+discusses the ability to dynamically add new built-in functions to
+@command{gawk}. As this feature is still immature and likely to change,
+its description is relegated to an appendix.
+
+@menu
+* Nondecimal Data:: Allowing nondecimal input data.
+* Two-way I/O:: Two-way communications with another process.
+* TCP/IP Networking:: Using @command{gawk} for network programming.
+* Portal Files:: Using @command{gawk} with BSD portals.
+* Profiling:: Profiling your @command{awk} programs.
+@end menu
+
+@node Nondecimal Data
+@section Allowing Nondecimal Input Data
+@cindex @code{--non-decimal-data} option
+@cindex advanced features, @command{gawk}, nondecimal input data
+@cindex input, data@comma{} nondecimal
+@cindex constants, nondecimal
+
+If you run @command{gawk} with the @option{--non-decimal-data} option,
+you can have nondecimal constants in your input data:
+
+@c line break here for small book format
+@example
+$ echo 0123 123 0x123 |
+> gawk --non-decimal-data '@{ printf "%d, %d, %d\n",
+> $1, $2, $3 @}'
+@print{} 83, 123, 291
+@end example
+
+For this feature to work, write your program so that
+@command{gawk} treats your data as numeric:
+
+@example
+$ echo 0123 123 0x123 | gawk '@{ print $1, $2, $3 @}'
+@print{} 0123 123 0x123
+@end example
+
+@noindent
+The @code{print} statement treats its expressions as strings.
+Although the fields can act as numbers when necessary,
+they are still strings, so @code{print} does not try to treat them
+numerically. You may need to add zero to a field to force it to
+be treated as a number. For example:
+
+@example
+$ echo 0123 123 0x123 | gawk --non-decimal-data '
+> @{ print $1, $2, $3
+> print $1 + 0, $2 + 0, $3 + 0 @}'
+@print{} 0123 123 0x123
+@print{} 83 123 291
+@end example
+
+Because it is common to have decimal data with leading zeros, and because
+using it could lead to surprising results, the default is to leave this
+facility disabled. If you want it, you must explicitly request it.
+
+@cindex programming conventions, @code{--non-decimal-data} option
+@cindex @code{--non-decimal-data} option, @code{strtonum} function and
+@cindex @code{strtonum} function (@command{gawk}), @code{--non-decimal-data} option and
+@strong{Caution:}
+@emph{Use of this option is not recommended.}
+It can break old programs very badly.
+Instead, use the @code{strtonum} function to convert your data
+(@pxref{Nondecimal-numbers}).
+This makes your programs easier to write and easier to read, and
+leads to less surprising results.
+
+@node Two-way I/O
+@section Two-Way Communications with Another Process
+@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
+
+@cindex advanced features, @command{gawk}, processes@comma{} communicating with
+@cindex processes, two-way communications with
+It is often useful to be able to
+send data to a separate program for
+processing and then read the result. This can always be
+done with temporary files:
+
+@example
+# write the data for processing
+tempfile = ("mydata." PROCINFO["pid"])
+while (@var{not done with data})
+ print @var{data} | ("subprogram > " tempfile)
+close("subprogram > " tempfile)
+
+# read the results, remove tempfile when done
+while ((getline newdata < tempfile) > 0)
+ @var{process} newdata @var{appropriately}
+close(tempfile)
+system("rm " tempfile)
+@end example
+
+@noindent
+This works, but not elegantly. Among other things, it requires that
+the program be run in a directory that cannot be shared among users;
+for example, @file{/tmp} will not do, as another user might happen
+to be using a temporary file with the same name.
+
+@cindex coprocesses
+@cindex input/output, two-way
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} I/O operator (I/O)
+@cindex @command{csh} utility, @code{|&} operator, comparison with
+Starting with @value{PVERSION} 3.1 of @command{gawk}, it is possible to
+open a @emph{two-way} pipe to another process. The second process is
+termed a @dfn{coprocess}, since it runs in parallel with @command{gawk}.
+The two-way connection is created using the new @samp{|&} operator
+(borrowed from the Korn shell, @command{ksh}):@footnote{This is very
+different from the same operator in the C shell, @command{csh}.}
+
+@example
+do @{
+ print @var{data} |& "subprogram"
+ "subprogram" |& getline results
+@} while (@var{data left to process})
+close("subprogram")
+@end example
+
+The first time an I/O operation is executed using the @samp{|&}
+operator, @command{gawk} creates a two-way pipeline to a child process
+that runs the other program. Output created with @code{print}
+or @code{printf} is written to the program's standard input, and
+output from the program's standard output can be read by the @command{gawk}
+program using @code{getline}.
+As is the case with processes started by @samp{|}, the subprogram
+can be any program, or pipeline of programs, that can be started by
+the shell.
+
+There are some cautionary items to be aware of:
+
+@itemize @bullet
+@item
+As the code inside @command{gawk} currently stands, the coprocess's
+standard error goes to the same place that the parent @command{gawk}'s
+standard error goes. It is not possible to read the child's
+standard error separately.
+
+@cindex deadlocks
+@cindex buffering, input/output
+@cindex @code{getline} command, deadlock and
+@item
+I/O buffering may be a problem. @command{gawk} automatically
+flushes all output down the pipe to the child process.
+However, if the coprocess does not flush its output,
+@command{gawk} may hang when doing a @code{getline} in order to read
+the coprocess's results. This could lead to a situation
+known as @dfn{deadlock}, where each process is waiting for the
+other one to do something.
+@end itemize
+
+@cindex @code{close} function, two-way pipes and
+It is possible to close just one end of the two-way pipe to
+a coprocess, by supplying a second argument to the @code{close}
+function of either @code{"to"} or @code{"from"}
+(@pxref{Close Files And Pipes}).
+These strings tell @command{gawk} to close the end of the pipe
+that sends data to the process or the end that reads from it,
+respectively.
+
+@cindex @command{sort} utility, coprocesses and
+This is particularly necessary in order to use
+the system @command{sort} utility as part of a coprocess;
+@command{sort} must read @emph{all} of its input
+data before it can produce any output.
+The @command{sort} program does not receive an end-of-file indication
+until @command{gawk} closes the write end of the pipe.
+
+When you have finished writing data to the @command{sort}
+utility, you can close the @code{"to"} end of the pipe, and
+then start reading sorted data via @code{getline}.
+For example:
+
+@example
+BEGIN @{
+ command = "LC_ALL=C sort"
+ n = split("abcdefghijklmnopqrstuvwxyz", a, "")
+
+ for (i = n; i > 0; i--)
+ print a[i] |& command
+ close(command, "to")
+
+ while ((command |& getline line) > 0)
+ print "got", line
+ close(command)
+@}
+@end example
+
+This program writes the letters of the alphabet in reverse order, one
+per line, down the two-way pipe to @command{sort}. It then closes the
+write end of the pipe, so that @command{sort} receives an end-of-file
+indication. This causes @command{sort} to sort the data and write the
+sorted data back to the @command{gawk} program. Once all of the data
+has been read, @command{gawk} terminates the coprocess and exits.
+
+As a side note, the assignment @samp{LC_ALL=C} in the @command{sort}
+command ensures traditional Unix (ASCII) sorting from @command{sort}.
+
+Beginning with @command{gawk} 3.1.2, you may use Pseudo-ttys (ptys) for
+two-way communication instead of pipes, if your system supports them.
+This is done on a per-command basis, by setting a special element
+in the @code{PROCINFO} array
+(@pxref{Auto-set}),
+like so:
+
+@example
+command = "sort -nr" # command, saved in variable for convenience
+PROCINFO[command, "pty"] = 1 # update PROCINFO
+print @dots{} |& command # start two-way pipe
+@dots{}
+@end example
+
+@noindent
+Using ptys avoids the buffer deadlock issues described earlier, at some
+loss in performance. If your system does not have ptys, or if all the
+system's ptys are in use, @command{gawk} automatically falls back to
+using regular pipes.
+
+@node TCP/IP Networking
+@section Using @command{gawk} for Network Programming
+@cindex advanced features, @command{gawk}, network programming
+@cindex networks, programming
+@c STARTOFRANGE tcpip
+@cindex TCP/IP
+@cindex @code{/inet/} files (@command{gawk})
+@cindex files, @code{/inet/} (@command{gawk})
+@cindex @code{EMISTERED}
+@quotation
+@code{EMISTERED}: @i{A host is a host from coast to coast,@*
+and no-one can talk to host that's close,@*
+unless the host that isn't close@*
+is busy hung or dead.}
+@end quotation
+
+In addition to being able to open a two-way pipeline to a coprocess
+on the same system
+(@pxref{Two-way I/O}),
+it is possible to make a two-way connection to
+another process on another system across an IP networking connection.
+
+You can think of this as just a @emph{very long} two-way pipeline to
+a coprocess.
+The way @command{gawk} decides that you want to use TCP/IP networking is
+by recognizing special @value{FN}s that begin with @samp{/inet/}.
+
+The full syntax of the special @value{FN} is
+@file{/inet/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}.
+The components are:
+
+@table @var
+@item protocol
+The protocol to use over IP. This must be either @samp{tcp},
+@samp{udp}, or @samp{raw}, for a TCP, UDP, or raw IP connection,
+respectively. The use of TCP is recommended for most applications.
+
+@cindex raw sockets
+@cindex sockets
+@strong{Caution:} The use of raw sockets is not currently supported
+in @value{PVERSION} 3.1 of @command{gawk}.
+
+@item local-port
+@cindex @code{getservbyname} function (C library)
+The local TCP or UDP port number to use. Use a port number of @samp{0}
+when you want the system to pick a port. This is what you should do
+when writing a TCP or UDP client.
+You may also use a well-known service name, such as @samp{smtp}
+or @samp{http}, in which case @command{gawk} attempts to determine
+the predefined port number using the C @code{getservbyname} function.
+
+@item remote-host
+The IP address or fully-qualified domain name of the Internet
+host to which you want to connect.
+
+@item remote-port
+The TCP or UDP port number to use on the given @var{remote-host}.
+Again, use @samp{0} if you don't care, or else a well-known
+service name.
+@end table
+
+Consider the following very simple example:
+
+@example
+BEGIN @{
+ Service = "/inet/tcp/0/localhost/daytime"
+ Service |& getline
+ print $0
+ close(Service)
+@}
+@end example
+
+This program reads the current date and time from the local system's
+TCP @samp{daytime} server.
+It then prints the results and closes the connection.
+
+Because this topic is extensive, the use of @command{gawk} for
+TCP/IP programming is documented separately.
+@ifinfo
+@xref{Top},
+@end ifinfo
+@ifnotinfo
+See @cite{TCP/IP Internetworking with @command{gawk}},
+which comes as part of the @command{gawk} distribution,
+@end ifnotinfo
+for a much more complete introduction and discussion, as well as
+extensive examples.
+
+@node Portal Files
+@section Using @command{gawk} with BSD Portals
+@cindex advanced features, @command{gawk}, BSD portals
+@cindex portal files
+@cindex files, portal
+@cindex BSD portals
+@cindex @code{/p} files (@command{gawk})
+@cindex files, @code{/p} (@command{gawk})
+@cindex @code{--enable-portals} configuration option
+@cindex operating systems, BSD-based
+
+Similar to the @file{/inet} special files, if @command{gawk}
+is configured with the @option{--enable-portals} option
+(@pxref{Quick Installation}),
+then @command{gawk} treats
+files whose pathnames begin with @code{/p} as 4.4 BSD-style portals.
+
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O), two-way communications
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O), two-way communications
+When used with the @samp{|&} operator, @command{gawk} opens the file
+for two-way communications. The operating system's portal mechanism
+then manages creating the process associated with the portal and
+the corresponding communications with the portal's process.
+@c ENDOFRANGE tcpip
+
+@node Profiling
+@section Profiling Your @command{awk} Programs
+@c STARTOFRANGE awkp
+@cindex @command{awk} programs, profiling
+@c STARTOFRANGE proawk
+@cindex profiling @command{awk} programs
+@c STARTOFRANGE pgawk
+@cindex @command{pgawk} program
+@cindex profiling @command{gawk}, See @command{pgawk} program
+
+Beginning with @value{PVERSION} 3.1 of @command{gawk}, you may produce execution
+traces of your @command{awk} programs.
+This is done with a specially compiled version of @command{gawk},
+called @command{pgawk} (``profiling @command{gawk}'').
+
+@cindex @code{awkprof.out} file
+@cindex files, @code{awkprof.out}
+@cindex @command{pgawk} program, @code{awkprof.out} file
+@command{pgawk} is identical in every way to @command{gawk}, except that when
+it has finished running, it creates a profile of your program in a file
+named @file{awkprof.out}.
+Because it is profiling, it also executes up to 45% slower than
+@command{gawk} normally does.
+
+@cindex @code{--profile} option
+As shown in the following example,
+the @option{--profile} option can be used to change the name of the file
+where @command{pgawk} will write the profile:
+
+@example
+$ pgawk --profile=myprog.prof -f myprog.awk data1 data2
+@end example
+
+@noindent
+In the above example, @command{pgawk} places the profile in
+@file{myprog.prof} instead of in @file{awkprof.out}.
+
+Regular @command{gawk} also accepts this option. When called with just
+@option{--profile}, @command{gawk} ``pretty prints'' the program into
+@file{awkprof.out}, without any execution counts. You may supply an
+option to @option{--profile} to change the @value{FN}. Here is a sample
+session showing a simple @command{awk} program, its input data, and the
+results from running @command{pgawk}. First, the @command{awk} program:
+
+@example
+BEGIN @{ print "First BEGIN rule" @}
+
+END @{ print "First END rule" @}
+
+/foo/ @{
+ print "matched /foo/, gosh"
+ for (i = 1; i <= 3; i++)
+ sing()
+@}
+
+@{
+ if (/foo/)
+ print "if is true"
+ else
+ print "else is true"
+@}
+
+BEGIN @{ print "Second BEGIN rule" @}
+
+END @{ print "Second END rule" @}
+
+function sing( dummy)
+@{
+ print "I gotta be me!"
+@}
+@end example
+
+Following is the input data:
+
+@example
+foo
+bar
+baz
+foo
+junk
+@end example
+
+Here is the @file{awkprof.out} that results from running @command{pgawk}
+on this program and data (this example also illustrates that @command{awk}
+programmers sometimes have to work late):
+
+@cindex @code{BEGIN} pattern, @command{pgawk} program
+@cindex @code{END} pattern, @command{pgawk} program
+@example
+ # gawk profile, created Sun Aug 13 00:00:15 2000
+
+ # BEGIN block(s)
+
+ BEGIN @{
+ 1 print "First BEGIN rule"
+ 1 print "Second BEGIN rule"
+ @}
+
+ # Rule(s)
+
+ 5 /foo/ @{ # 2
+ 2 print "matched /foo/, gosh"
+ 6 for (i = 1; i <= 3; i++) @{
+ 6 sing()
+ @}
+ @}
+
+ 5 @{
+ 5 if (/foo/) @{ # 2
+ 2 print "if is true"
+ 3 @} else @{
+ 3 print "else is true"
+ @}
+ @}
+
+ # END block(s)
+
+ END @{
+ 1 print "First END rule"
+ 1 print "Second END rule"
+ @}
+
+ # Functions, listed alphabetically
+
+ 6 function sing(dummy)
+ @{
+ 6 print "I gotta be me!"
+ @}
+@end example
+
+This example illustrates many of the basic rules for profiling output.
+The rules are as follows:
+
+@itemize @bullet
+@item
+The program is printed in the order @code{BEGIN} rule,
+pattern/action rules, @code{END} rule and functions, listed
+alphabetically.
+Multiple @code{BEGIN} and @code{END} rules are merged together.
+
+@cindex patterns, counts
+@item
+Pattern-action rules have two counts.
+The first count, to the left of the rule, shows how many times
+the rule's pattern was @emph{tested}.
+The second count, to the right of the rule's opening left brace
+in a comment,
+shows how many times the rule's action was @emph{executed}.
+The difference between the two indicates how many times the rule's
+pattern evaluated to false.
+
+@item
+Similarly,
+the count for an @code{if}-@code{else} statement shows how many times
+the condition was tested.
+To the right of the opening left brace for the @code{if}'s body
+is a count showing how many times the condition was true.
+The count for the @code{else}
+indicates how many times the test failed.
+
+@cindex loops, count for header
+@item
+The count for a loop header (such as @code{for}
+or @code{while}) shows how many times the loop test was executed.
+(Because of this, you can't just look at the count on the first
+statement in a rule to determine how many times the rule was executed.
+If the first statement is a loop, the count is misleading.)
+
+@cindex functions, user-defined, counts
+@cindex user-defined, functions, counts
+@item
+For user-defined functions, the count next to the @code{function}
+keyword indicates how many times the function was called.
+The counts next to the statements in the body show how many times
+those statements were executed.
+
+@cindex @code{@{@}} (braces), @command{pgawk} program
+@cindex braces (@code{@{@}}), @command{pgawk} program
+@item
+The layout uses ``K&R'' style with tabs.
+Braces are used everywhere, even when
+the body of an @code{if}, @code{else}, or loop is only a single statement.
+
+@cindex @code{()} (parentheses), @command{pgawk} program
+@cindex parentheses @code{()}, @command{pgawk} program
+@item
+Parentheses are used only where needed, as indicated by the structure
+of the program and the precedence rules.
+@c extra verbiage here satisfies the copyeditor. ugh.
+For example, @samp{(3 + 5) * 4} means add three plus five, then multiply
+the total by four. However, @samp{3 + 5 * 4} has no parentheses, and
+means @samp{3 + (5 * 4)}.
+
+@item
+All string concatenations are parenthesized too.
+(This could be made a bit smarter.)
+
+@item
+Parentheses are used around the arguments to @code{print}
+and @code{printf} only when
+the @code{print} or @code{printf} statement is followed by a redirection.
+Similarly, if
+the target of a redirection isn't a scalar, it gets parenthesized.
+
+@item
+@command{pgawk} supplies leading comments in
+front of the @code{BEGIN} and @code{END} rules,
+the pattern/action rules, and the functions.
+
+@end itemize
+
+The profiled version of your program may not look exactly like what you
+typed when you wrote it. This is because @command{pgawk} creates the
+profiled version by ``pretty printing'' its internal representation of
+the program. The advantage to this is that @command{pgawk} can produce
+a standard representation. The disadvantage is that all source-code
+comments are lost, as are the distinctions among multiple @code{BEGIN}
+and @code{END} rules. Also, things such as:
+
+@example
+/foo/
+@end example
+
+@noindent
+come out as:
+
+@example
+/foo/ @{
+ print $0
+@}
+@end example
+
+@noindent
+which is correct, but possibly surprising.
+
+@cindex profiling @command{awk} programs, dynamically
+@cindex @command{pgawk} program, dynamic profiling
+Besides creating profiles when a program has completed,
+@command{pgawk} can produce a profile while it is running.
+This is useful if your @command{awk} program goes into an
+infinite loop and you want to see what has been executed.
+To use this feature, run @command{pgawk} in the background:
+
+@example
+$ pgawk -f myprog &
+[1] 13992
+@end example
+
+@cindex @command{kill} command@comma{} dynamic profiling
+@cindex @code{USR1} signal
+@cindex signals, @code{USR1}/@code{SIGUSR1}
+@noindent
+The shell prints a job number and process ID number; in this case, 13992.
+Use the @command{kill} command to send the @code{USR1} signal
+to @command{pgawk}:
+
+@example
+$ kill -USR1 13992
+@end example
+
+@noindent
+As usual, the profiled version of the program is written to
+@file{awkprof.out}, or to a different file if you use the @option{--profile}
+option.
+
+Along with the regular profile, as shown earlier, the profile
+includes a trace of any active functions:
+
+@example
+# Function Call Stack:
+
+# 3. baz
+# 2. bar
+# 1. foo
+# -- main --
+@end example
+
+You may send @command{pgawk} the @code{USR1} signal as many times as you like.
+Each time, the profile and function call trace are appended to the output
+profile file.
+
+@cindex @code{HUP} signal
+@cindex signals, @code{HUP}/@code{SIGHUP}
+If you use the @code{HUP} signal instead of the @code{USR1} signal,
+@command{pgawk} produces the profile and the function call trace and then exits.
+
+@cindex @code{INT} signal (MS-DOS)
+@cindex signals, @code{INT}/@code{SIGINT} (MS-DOS)
+@cindex @code{QUIT} signal (MS-DOS)
+@cindex signals, @code{QUIT}/@code{SIGQUIT} (MS-DOS)
+When @command{pgawk} runs on MS-DOS or MS-Windows, it uses the
+@code{INT} and @code{QUIT} signals for producing the profile and, in
+the case of the @code{INT} signal, @command{pgawk} exits. This is
+because these systems don't support the @command{kill} command, so the
+only signals you can deliver to a program are those generated by the
+keyboard. The @code{INT} signal is generated by the
+@kbd{@value{CTL}-@key{C}} or @kbd{@value{CTL}-@key{BREAK}} key, while the
+@code{QUIT} signal is generated by the @kbd{@value{CTL}-@key{\}} key.
+@c ENDOFRANGE advgaw
+@c ENDOFRANGE gawadv
+@c ENDOFRANGE pgawk
+@c ENDOFRANGE awkp
+@c ENDOFRANGE proawk
+
+@node Invoking Gawk
+@chapter Running @command{awk} and @command{gawk}
+
+This @value{CHAPTER} covers how to run awk, both POSIX-standard
+and @command{gawk}-specific command-line options, and what
+@command{awk} and
+@command{gawk} do with non-option arguments.
+It then proceeds to cover how @command{gawk} searches for source files,
+obsolete options and/or features, and known bugs in @command{gawk}.
+This @value{CHAPTER} rounds out the discussion of @command{awk}
+as a program and as a language.
+
+While a number of the options and features described here were
+discussed in passing earlier in the book, this @value{CHAPTER} provides the
+full details.
+
+@menu
+* Command Line:: How to run @command{awk}.
+* Options:: Command-line options and their meanings.
+* Other Arguments:: Input file names and variable assignments.
+* AWKPATH Variable:: Searching directories for @command{awk}
+ programs.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Known Bugs:: Known Bugs in @command{gawk}.
+@end menu
+
+@node Command Line
+@section Invoking @command{awk}
+@cindex command line, invoking @command{awk} from
+@cindex @command{awk}, invoking
+@cindex arguments, command-line, invoking @command{awk}
+@cindex options, command-line, invoking @command{awk}
+
+There are two ways to run @command{awk}---with an explicit program or with
+one or more program files. Here are templates for both of them; items
+enclosed in [@dots{}] in these templates are optional:
+
+@example
+awk @r{[@var{options}]} -f progfile @r{[@code{--}]} @var{file} @dots{}
+awk @r{[@var{options}]} @r{[@code{--}]} '@var{program}' @var{file} @dots{}
+@end example
+
+@cindex GNU long options
+@cindex long options
+@cindex options, long
+Besides traditional one-letter POSIX-style options, @command{gawk} also
+supports GNU long options.
+
+@cindex dark corner, invoking @command{awk}
+@cindex lint checking, empty programs
+It is possible to invoke @command{awk} with an empty program:
+
+@example
+awk '' datafile1 datafile2
+@end example
+
+@cindex @code{--lint} option
+@noindent
+Doing so makes little sense, though; @command{awk} exits
+silently when given an empty program.
+@value{DARKCORNER}
+If @option{--lint} has
+been specified on the command line, @command{gawk} issues a
+warning that the program is empty.
+
+@node Options
+@section Command-Line Options
+@c STARTOFRANGE ocl
+@cindex options, command-line
+@c STARTOFRANGE clo
+@cindex command line, options
+@c STARTOFRANGE gnulo
+@cindex GNU long options
+@c STARTOFRANGE longo
+@cindex options, long
+
+Options begin with a dash and consist of a single character.
+GNU-style long options consist of two dashes and a keyword.
+The keyword can be abbreviated, as long as the abbreviation allows the option
+to be uniquely identified. If the option takes an argument, then the
+keyword is either immediately followed by an equals sign (@samp{=}) and the
+argument's value, or the keyword and the argument's value are separated
+by whitespace.
+If a particular option with a value is given more than once, it is the
+last value that counts.
+
+@cindex POSIX @command{awk}, GNU long options and
+Each long option for @command{gawk} has a corresponding
+POSIX-style option.
+The long and short options are
+interchangeable in all contexts.
+The options and their meanings are as follows:
+
+@table @code
+@item -F @var{fs}
+@itemx --field-separator @var{fs}
+@cindex @code{-F} option
+@cindex @code{--field-separator} option
+@cindex @code{FS} variable, @code{--field-separator} option and
+Sets the @code{FS} variable to @var{fs}
+(@pxref{Field Separators}).
+
+@item -f @var{source-file}
+@itemx --file @var{source-file}
+@cindex @code{-f} option
+@cindex @code{--file} option
+@cindex @command{awk} programs, location of
+Indicates that the @command{awk} program is to be found in @var{source-file}
+instead of in the first non-option argument.
+
+@item -v @var{var}=@var{val}
+@itemx --assign @var{var}=@var{val}
+@cindex @code{-v} option
+@cindex @code{--assign} option
+@cindex variables, setting
+Sets the variable @var{var} to the value @var{val} @emph{before}
+execution of the program begins. Such variable values are available
+inside the @code{BEGIN} rule
+(@pxref{Other Arguments}).
+
+The @option{-v} option can only set one variable, but it can be used
+more than once, setting another variable each time, like this:
+@samp{awk @w{-v foo=1} @w{-v bar=2} @dots{}}.
+
+@cindex built-in variables, @code{-v} option@comma{} setting with
+@cindex variables, built-in, @code{-v} option@comma{} setting with
+@strong{Caution:} Using @option{-v} to set the values of the built-in
+variables may lead to surprising results. @command{awk} will reset the
+values of those variables as it needs to, possibly ignoring any
+predefined value you may have given.
+
+@item -mf @var{N}
+@itemx -mr @var{N}
+@cindex @code{-mf}/@code{-mr} options
+@cindex memory, setting limits
+Sets various memory limits to the value @var{N}. The @samp{f} flag sets
+the maximum number of fields and the @samp{r} flag sets the maximum
+record size. These two flags and the @option{-m} option are from the
+Bell Laboratories research version of Unix @command{awk}. They are provided
+for compatibility but otherwise ignored by
+@command{gawk}, since @command{gawk} has no predefined limits.
+(The Bell Laboratories @command{awk} no longer needs these options;
+it continues to accept them to avoid breaking old programs.)
+
+@item -W @var{gawk-opt}
+@cindex @code{-W} option
+Following the POSIX standard, implementation-specific
+options are supplied as arguments to the @option{-W} option. These options
+also have corresponding GNU-style long options.
+Note that the long options may be abbreviated, as long as
+the abbreviations remain unique.
+The full list of @command{gawk}-specific options is provided next.
+
+@item --
+@cindex command line, options, end of
+@cindex options, command-line, end of
+Signals the end of the command-line options. The following arguments
+are not treated as options even if they begin with @samp{-}. This
+interpretation of @option{--} follows the POSIX argument parsing
+conventions.
+
+@cindex @code{-} (hyphen), filenames beginning with
+@cindex hyphen (@code{-}), filenames beginning with
+This is useful if you have @value{FN}s that start with @samp{-},
+or in shell scripts, if you have @value{FN}s that will be specified
+by the user that could start with @samp{-}.
+@end table
+@c ENDOFRANGE gnulo
+@c ENDOFRANGE longo
+
+The previous list described options mandated by the POSIX standard,
+as well as options available in the Bell Laboratories version of @command{awk}.
+The following list describes @command{gawk}-specific options:
+
+@table @code
+@item -W compat
+@itemx -W traditional
+@itemx --compat
+@itemx --traditional
+@cindex @code{--compat} option
+@cindex @code{--traditional} option
+@cindex compatibility mode (@command{gawk}), specifying
+Specifies @dfn{compatibility mode}, in which the GNU extensions to
+the @command{awk} language are disabled, so that @command{gawk} behaves just
+like the Bell Laboratories research version of Unix @command{awk}.
+@option{--traditional} is the preferred form of this option.
+@xref{POSIX/GNU},
+which summarizes the extensions. Also see
+@ref{Compatibility Mode}.
+
+@item -W copyright
+@itemx --copyright
+@cindex @code{--copyright} option
+@cindex GPL (General Public License), printing
+Print the short version of the General Public License and then exit.
+
+@item -W copyleft
+@itemx --copyleft
+@cindex @code{--copyleft} option
+Just like @option{--copyright}.
+This option may disappear in a future version of @command{gawk}.
+
+@cindex @code{--dump-variables} option
+@cindex @code{awkvars.out} file
+@cindex files, @code{awkvars.out}
+@cindex variables, global, printing list of
+@item -W dump-variables@r{[}=@var{file}@r{]}
+@itemx --dump-variables@r{[}=@var{file}@r{]}
+Prints a sorted list of global variables, their types, and final values
+to @var{file}. If no @var{file} is provided, @command{gawk} prints this
+list to the file named @file{awkvars.out} in the current directory.
+
+@cindex troubleshooting, typographical errors@comma{} global variables
+Having a list of all global variables is a good way to look for
+typographical errors in your programs.
+You would also use this option if you have a large program with a lot of
+functions, and you want to be sure that your functions don't
+inadvertently use global variables that you meant to be local.
+(This is a particularly easy mistake to make with simple variable
+names like @code{i}, @code{j}, etc.)
+
+@item -W exec @var{file}
+@itemx --exec @var{file}
+@cindex @code{--exec} option
+@cindex @command{awk} programs, location of
+@cindex CGI, @command{awk} scripts for
+Similar to @option{-f}, reads @command{awk} program text from @var{file}.
+There are two differences. The fist is that this option also terminates option processing; anything
+else on the command line is passed on directly to the @command{awk} program.
+The second is that command line variable assignments of the form
+@samp{@var{var}=@var{value}} are disallowed.
+
+This option is particularly necessary for World Wide Web CGI applications
+that pass arguments through the URL; using this option prevents a malicious
+(or other) user from passing in options, assignments, or @command{awk} source code (via
+@option{--source}) to the CGI application. This option should be used
+with @samp{#!} scripts (@pxref{Executable Scripts}), like so:
+
+@example
+#! /usr/local/bin/gawk --exec
+
+@var{awk program here @dots{}}
+@end example
+
+@item -W gen-po
+@itemx --gen-po
+@cindex @code{--gen-po} option
+@cindex portable object files, generating
+@cindex files, portable object, generating
+Analyzes the source program and
+generates a GNU @code{gettext} Portable Object file on standard
+output for all string constants that have been marked for translation.
+@xref{Internationalization},
+for information about this option.
+
+@item -W help
+@itemx -W usage
+@itemx --help
+@itemx --usage
+@cindex @code{--help} option
+@cindex @code{--usage} option
+@cindex GNU long options, printing list of
+@cindex options, printing list of
+@cindex printing, list of options
+Prints a ``usage'' message summarizing the short and long style options
+that @command{gawk} accepts and then exit.
+
+@item -W lint@r{[}=fatal@r{]}
+@itemx --lint@r{[}=fatal@r{]}
+@cindex @code{--lint} option
+@cindex lint checking, issuing warnings
+@cindex warnings, issuing
+Warns about constructs that are dubious or nonportable to
+other @command{awk} implementations.
+Some warnings are issued when @command{gawk} first reads your program. Others
+are issued at runtime, as your program executes.
+With an optional argument of @samp{fatal},
+lint warnings become fatal errors.
+This may be drastic, but its use will certainly encourage the
+development of cleaner @command{awk} programs.
+With an optional argument of @samp{invalid}, only warnings about things that are
+actually invalid are issued. (This is not fully implemented yet.)
+
+@item -W lint-old
+@itemx --lint-old
+@cindex @code{--lint-old} option
+Warns about constructs that are not available in the original version of
+@command{awk} from Version 7 Unix
+(@pxref{V7/SVR3.1}).
+
+@item -W non-decimal-data
+@itemx --non-decimal-data
+@cindex @code{--non-decimal-data} option
+@cindex hexadecimal values@comma{} enabling interpretation of
+@cindex octal values@comma{} enabling interpretation of
+Enable automatic interpretation of octal and hexadecimal
+values in input data
+(@pxref{Nondecimal Data}).
+
+@cindex troubleshooting, @code{--non-decimal-data} option
+@strong{Caution:} This option can severely break old programs.
+Use with care.
+
+@item -W posix
+@itemx --posix
+@cindex @code{--posix} option
+@cindex POSIX mode
+@cindex @command{gawk}, extensions@comma{} disabling
+Operates in strict POSIX mode. This disables all @command{gawk}
+extensions (just like @option{--traditional}) and adds the following additional
+restrictions:
+
+@c IMPORTANT! Keep this list in sync with the one in node POSIX
+
+@itemize @bullet
+@cindex escape sequences, unrecognized
+@item
+@code{\x} escape sequences are not recognized
+(@pxref{Escape Sequences}).
+
+@cindex newlines
+@cindex whitespace, newlines as
+@item
+Newlines do not act as whitespace to separate fields when @code{FS} is
+equal to a single space
+(@pxref{Fields}).
+
+@item
+Newlines are not allowed after @samp{?} or @samp{:}
+(@pxref{Conditional Exp}).
+
+@item
+The synonym @code{func} for the keyword @code{function} is not
+recognized (@pxref{Definition Syntax}).
+
+@cindex @code{*} (asterisk), @code{**} operator
+@cindex asterisk (@code{*}), @code{**} operator
+@cindex @code{*} (asterisk), @code{**=} operator
+@cindex asterisk (@code{*}), @code{**=} operator
+@cindex @code{^} (caret), @code{^} operator
+@cindex caret (@code{^}), @code{^} operator
+@cindex @code{^} (caret), @code{^=} operator
+@cindex caret (@code{^}), @code{^=} operator
+@item
+The @samp{**} and @samp{**=} operators cannot be used in
+place of @samp{^} and @samp{^=} (@pxref{Arithmetic Ops},
+and also @pxref{Assignment Ops}).
+
+@cindex @code{FS} variable, as TAB character
+@item
+Specifying @samp{-Ft} on the command-line does not set the value
+of @code{FS} to be a single TAB character
+(@pxref{Field Separators}).
+
+@cindex @code{fflush} function@comma{} unsupported
+@item
+The @code{fflush} built-in function is not supported
+(@pxref{I/O Functions}).
+@end itemize
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@cindex @code{--traditional} option, @code{--posix} option and
+@cindex @code{--posix} option, @code{--traditional} option and
+If you supply both @option{--traditional} and @option{--posix} on the
+command line, @option{--posix} takes precedence. @command{gawk}
+also issues a warning if both options are supplied.
+
+@item -W profile@r{[}=@var{file}@r{]}
+@itemx --profile@r{[}=@var{file}@r{]}
+@cindex @code{--profile} option
+@cindex @command{awk} programs, profiling, enabling
+Enable profiling of @command{awk} programs
+(@pxref{Profiling}).
+By default, profiles are created in a file named @file{awkprof.out}.
+The optional @var{file} argument allows you to specify a different
+@value{FN} for the profile file.
+
+When run with @command{gawk}, the profile is just a ``pretty printed'' version
+of the program. When run with @command{pgawk}, the profile contains execution
+counts for each statement in the program in the left margin, and function
+call counts for each function.
+
+@item -W re-interval
+@itemx --re-interval
+@cindex @code{--re-interval} option
+@cindex regular expressions, interval expressions and
+Allows interval expressions
+(@pxref{Regexp Operators})
+in regexps.
+Because interval expressions were traditionally not available in @command{awk},
+@command{gawk} does not provide them by default. This prevents old @command{awk}
+programs from breaking.
+
+@item -W source @var{program-text}
+@itemx --source @var{program-text}
+@cindex @code{--source} option
+@cindex source code, mixing
+Allows you to mix source code in files with source
+code that you enter on the command line.
+Program source code is taken from the @var{program-text}.
+This is particularly useful
+when you have library functions that you want to use from your command-line
+programs (@pxref{AWKPATH Variable}).
+
+@item -W version
+@itemx --version
+@cindex @code{--version} option
+@cindex @command{gawk}, versions of, information about@comma{} printing
+Prints version information for this particular copy of @command{gawk}.
+This allows you to determine if your copy of @command{gawk} is up to date
+with respect to whatever the Free Software Foundation is currently
+distributing.
+It is also useful for bug reports
+(@pxref{Bugs}).
+@end table
+
+As long as program text has been supplied,
+any other options are flagged as invalid with a warning message but
+are otherwise ignored.
+
+@cindex @code{-F} option, @code{-Ft} sets @code{FS} to TAB
+In compatibility mode, as a special case, if the value of @var{fs} supplied
+to the @option{-F} option is @samp{t}, then @code{FS} is set to the TAB
+character (@code{"\t"}). This is true only for @option{--traditional} and not
+for @option{--posix}
+(@pxref{Field Separators}).
+
+@cindex @code{-f} option, on command line
+The @option{-f} option may be used more than once on the command line.
+If it is, @command{awk} reads its program source from all of the named files, as
+if they had been concatenated together into one big file. This is
+useful for creating libraries of @command{awk} functions. These functions
+can be written once and then retrieved from a standard place, instead
+of having to be included into each individual program.
+(As mentioned in
+@ref{Definition Syntax},
+function names must be unique.)
+
+Library functions can still be used, even if the program is entered at the terminal,
+by specifying @samp{-f /dev/tty}. After typing your program,
+type @kbd{@value{CTL}-d} (the end-of-file character) to terminate it.
+(You may also use @samp{-f -} to read program source from the standard
+input but then you will not be able to also use the standard input as a
+source of data.)
+
+Because it is clumsy using the standard @command{awk} mechanisms to mix source
+file and command-line @command{awk} programs, @command{gawk} provides the
+@option{--source} option. This does not require you to pre-empt the standard
+input for your source code; it allows you to easily mix command-line
+and library source code
+(@pxref{AWKPATH Variable}).
+
+@cindex @code{--source} option
+If no @option{-f} or @option{--source} option is specified, then @command{gawk}
+uses the first non-option command-line argument as the text of the
+program source code.
+
+@cindex @code{POSIXLY_CORRECT} environment variable
+@cindex lint checking, @code{POSIXLY_CORRECT} environment variable
+@cindex POSIX mode
+If the environment variable @env{POSIXLY_CORRECT} exists,
+then @command{gawk} behaves in strict POSIX mode, exactly as if
+you had supplied the @option{--posix} command-line option.
+Many GNU programs look for this environment variable to turn on
+strict POSIX mode. If @option{--lint} is supplied on the command line
+and @command{gawk} turns on POSIX mode because of @env{POSIXLY_CORRECT},
+then it issues a warning message indicating that POSIX
+mode is in effect.
+You would typically set this variable in your shell's startup file.
+For a Bourne-compatible shell (such as @command{bash}), you would add these
+lines to the @file{.profile} file in your home directory:
+
+@example
+POSIXLY_CORRECT=true
+export POSIXLY_CORRECT
+@end example
+
+@cindex @command{csh} utility, @code{POSIXLY_CORRECT} environment variable
+For a @command{csh}-compatible
+shell,@footnote{Not recommended.}
+you would add this line to the @file{.login} file in your home directory:
+
+@example
+setenv POSIXLY_CORRECT true
+@end example
+
+@cindex portability, @code{POSIXLY_CORRECT} environment variable
+Having @env{POSIXLY_CORRECT} set is not recommended for daily use,
+but it is good for testing the portability of your programs to other
+environments.
+@c ENDOFRANGE ocl
+@c ENDOFRANGE clo
+
+@node Other Arguments
+@section Other Command-Line Arguments
+@cindex command line, arguments
+@cindex arguments, command-line
+
+Any additional arguments on the command line are normally treated as
+input files to be processed in the order specified. However, an
+argument that has the form @code{@var{var}=@var{value}}, assigns
+the value @var{value} to the variable @var{var}---it does not specify a
+file at all.
+(This was discussed earlier in
+@ref{Assignment Options}.)
+
+@cindex @code{ARGIND} variable, command-line arguments
+@cindex @code{ARGC}/@code{ARGV} variables, command-line arguments
+All these arguments are made available to your @command{awk} program in the
+@code{ARGV} array (@pxref{Built-in Variables}). Command-line options
+and the program text (if present) are omitted from @code{ARGV}.
+All other arguments, including variable assignments, are
+included. As each element of @code{ARGV} is processed, @command{gawk}
+sets the variable @code{ARGIND} to the index in @code{ARGV} of the
+current element.
+
+@cindex input files, variable assignments and
+The distinction between @value{FN} arguments and variable-assignment
+arguments is made when @command{awk} is about to open the next input file.
+At that point in execution, it checks the @value{FN} to see whether
+it is really a variable assignment; if so, @command{awk} sets the variable
+instead of reading a file.
+
+Therefore, the variables actually receive the given values after all
+previously specified files have been read. In particular, the values of
+variables assigned in this fashion are @emph{not} available inside a
+@code{BEGIN} rule
+(@pxref{BEGIN/END}),
+because such rules are run before @command{awk} begins scanning the argument list.
+
+@cindex dark corner, escape sequences
+The variable values given on the command line are processed for escape
+sequences (@pxref{Escape Sequences}).
+@value{DARKCORNER}
+
+In some earlier implementations of @command{awk}, when a variable assignment
+occurred before any @value{FN}s, the assignment would happen @emph{before}
+the @code{BEGIN} rule was executed. @command{awk}'s behavior was thus
+inconsistent; some command-line assignments were available inside the
+@code{BEGIN} rule, while others were not. Unfortunately,
+some applications came to depend
+upon this ``feature.'' When @command{awk} was changed to be more consistent,
+the @option{-v} option was added to accommodate applications that depended
+upon the old behavior.
+
+The variable assignment feature is most useful for assigning to variables
+such as @code{RS}, @code{OFS}, and @code{ORS}, which control input and
+output formats before scanning the @value{DF}s. It is also useful for
+controlling state if multiple passes are needed over a @value{DF}. For
+example:
+
+@cindex files, multiple passes over
+@example
+awk 'pass == 1 @{ @var{pass 1 stuff} @}
+ pass == 2 @{ @var{pass 2 stuff} @}' pass=1 mydata pass=2 mydata
+@end example
+
+Given the variable assignment feature, the @option{-F} option for setting
+the value of @code{FS} is not
+strictly necessary. It remains for historical compatibility.
+
+@node AWKPATH Variable
+@section The @env{AWKPATH} Environment Variable
+@cindex @env{AWKPATH} environment variable
+@cindex directories, searching
+@cindex search paths, for source files
+@cindex differences in @command{awk} and @command{gawk}, @code{AWKPATH} environment variable
+@ifinfo
+The previous @value{SECTION} described how @command{awk} program files can be named
+on the command-line with the @option{-f} option.
+@end ifinfo
+In most @command{awk}
+implementations, you must supply a precise path name for each program
+file, unless the file is in the current directory.
+But in @command{gawk}, if the @value{FN} supplied to the @option{-f} option
+does not contain a @samp{/}, then @command{gawk} searches a list of
+directories (called the @dfn{search path}), one by one, looking for a
+file with the specified name.
+
+The search path is a string consisting of directory names
+separated by colons. @command{gawk} gets its search path from the
+@env{AWKPATH} environment variable. If that variable does not exist,
+@command{gawk} uses a default path,
+@samp{.:/usr/local/share/awk}.@footnote{Your version of @command{gawk}
+may use a different directory; it
+will depend upon how @command{gawk} was built and installed. The actual
+directory is the value of @samp{$(datadir)} generated when
+@command{gawk} was configured. You probably don't need to worry about this,
+though.} (Programs written for use by
+system administrators should use an @env{AWKPATH} variable that
+does not include the current directory, @file{.}.)
+
+The search path feature is particularly useful for building libraries
+of useful @command{awk} functions. The library files can be placed in a
+standard directory in the default path and then specified on
+the command line with a short @value{FN}. Otherwise, the full @value{FN}
+would have to be typed for each file.
+
+By using both the @option{--source} and @option{-f} options, your command-line
+@command{awk} programs can use facilities in @command{awk} library files
+(@pxref{Library Functions}).
+Path searching is not done if @command{gawk} is in compatibility mode.
+This is true for both @option{--traditional} and @option{--posix}.
+@xref{Options}.
+
+@quotation NOTE
+If you want files in the current directory to be found,
+you must include the current directory in the path, either by including
+@file{.} explicitly in the path or by writing a null entry in the
+path. (A null entry is indicated by starting or ending the path with a
+colon or by placing two colons next to each other (@samp{::}).) If the
+current directory is not included in the path, then files cannot be
+found in the current directory. This path search mechanism is identical
+to the shell's.
+@c someday, @cite{The Bourne Again Shell}....
+@end quotation
+
+Starting with @value{PVERSION} 3.0, if @env{AWKPATH} is not defined in the
+environment, @command{gawk} places its default search path into
+@code{ENVIRON["AWKPATH"]}. This makes it easy to determine
+the actual search path that @command{gawk} will use
+from within an @command{awk} program.
+
+While you can change @code{ENVIRON["AWKPATH"]} within your @command{awk}
+program, this has no effect on the running program's behavior. This makes
+sense: the @env{AWKPATH} environment variable is used to find the program
+source files. Once your program is running, all the files have been
+found, and @command{gawk} no longer needs to use @env{AWKPATH}.
+
+@node Obsolete
+@section Obsolete Options and/or Features
+
+@cindex features, advanced, See advanced features
+@cindex options, deprecated
+@cindex features, deprecated
+@cindex obsolete features
+This @value{SECTION} describes features and/or command-line options from
+previous releases of @command{gawk} that are either not available in the
+current version or that are still supported but deprecated (meaning that
+they will @emph{not} be in the next release).
+
+@c update this section for each release!
+
+@cindex @code{next file} statement, deprecated
+@cindex @code{nextfile} statement, @code{next file} statement and
+For @value{PVERSION} @value{VERSION} of @command{gawk}, there are no
+deprecated command-line options
+@c or other deprecated features
+from the previous version of @command{gawk}.
+The use of @samp{next file} (two words) for @code{nextfile} was deprecated
+in @command{gawk} 3.0 but still worked. Starting with @value{PVERSION} 3.1, the
+two-word usage is no longer accepted.
+
+The process-related special files described in
+@ref{Special Process},
+work as described, but
+are now considered deprecated.
+@command{gawk} prints a warning message every time they are used.
+(Use @code{PROCINFO} instead; see
+@ref{Auto-set}.)
+They will be removed from the next release of @command{gawk}.
+
+@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 Undocumented
+@section Undocumented Options and Features
+@cindex undocumented features
+@cindex features, undocumented
+@cindex Skywalker, Luke
+@cindex Kenobi, Obi-Wan
+@cindex Jedi knights
+@cindex Knights, jedi
+@quotation
+@i{Use the Source, Luke!}@*
+Obi-Wan
+@end quotation
+
+This @value{SECTION} intentionally left
+blank.
+
+@ignore
+@c If these came out in the Info file or TeX document, then they wouldn't
+@c be undocumented, would they?
+
+@command{gawk} has one undocumented option:
+
+@table @code
+@item -W nostalgia
+@itemx --nostalgia
+Print the message @code{"awk: bailing out near line 1"} and dump core.
+This option was inspired by the common behavior of very early versions of
+Unix @command{awk} and by a t--shirt.
+The message is @emph{not} subject to translation in non-English locales.
+@c so there! nyah, nyah.
+@end table
+
+Early versions of @command{awk} used to not require any separator (either
+a newline or @samp{;}) between the rules in @command{awk} programs. Thus,
+it was common to see one-line programs like:
+
+@example
+awk '@{ sum += $1 @} END @{ print sum @}'
+@end example
+
+@command{gawk} actually supports this but it is purposely undocumented
+because it is considered bad style. The correct way to write such a program
+is either
+
+@example
+awk '@{ sum += $1 @} ; END @{ print sum @}'
+@end example
+
+@noindent
+or
+
+@example
+awk '@{ sum += $1 @}
+ END @{ print sum @}' data
+@end example
+
+@noindent
+@xref{Statements/Lines}, for a fuller
+explanation.
+
+You can insert newlines after the @samp{;} in @code{for} loops.
+This seems to have been a long-undocumented feature in Unix @command{awk}.
+
+Similarly, you may use @code{print} or @code{printf} statements in the
+@var{init} and @var{increment} parts of a @code{for} loop. This is another
+long-undocumented ``feature'' of Unix @code{awk}.
+
+If the environment variable @env{WHINY_USERS} exists
+when @command{gawk} is run,
+then the associative @code{for} loop will go through the array
+indices in sorted order.
+The comparison used for sorting is simple string comparison;
+any non-English or non-ASCII locales are not taken into account.
+@code{IGNORECASE} does not affect the comparison either.
+
+In addition, if @env{WHINY_USERS} is set, the profiled version of a
+program generated by @option{--profile} will print all 8-bit characters
+verbatim, instead of using the octal equivalent.
+
+@end ignore
+
+@node Known Bugs
+@section Known Bugs in @command{gawk}
+@cindex @command{gawk}, debugging
+@cindex debugging @command{gawk}
+@cindex troubleshooting, @command{gawk}
+
+@itemize @bullet
+@cindex troubleshooting, @code{-F} option
+@cindex @code{-F} option, troubleshooting
+@cindex @code{FS} variable, changing value of
+@item
+The @option{-F} option for changing the value of @code{FS}
+(@pxref{Options})
+is not necessary given the command-line variable
+assignment feature; it remains only for backward compatibility.
+
+@item
+Syntactically invalid single-character programs tend to overflow
+the parse stack, generating a rather unhelpful message. Such programs
+are surprisingly difficult to diagnose in the completely general case,
+and the effort to do so really is not worth it.
+@end itemize
+
+@ignore
+@c Try this
+@iftex
+@page
+@headings off
+@majorheading II@ @ @ Using @command{awk} and @command{gawk}
+Part II shows how to use @command{awk} and @command{gawk} for problem solving.
+There is lots of code here for you to read and learn from.
+It contains the following chapters:
+
+@itemize @bullet
+@item
+@ref{Library Functions}.
+
+@item
+@ref{Sample Programs}.
+
+@end itemize
+
+@page
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+@end ignore
+
+@node Library Functions
+@chapter A Library of @command{awk} Functions
+@c STARTOFRANGE libf
+@cindex libraries of @command{awk} functions
+@c STARTOFRANGE flib
+@cindex functions, library
+@c STARTOFRANGE fudlib
+@cindex functions, user-defined, library of
+
+@ref{User-defined}, describes how to write
+your own @command{awk} functions. Writing functions is important, because
+it allows you to encapsulate algorithms and program tasks in a single
+place. It simplifies programming, making program development more
+manageable, and making programs more readable.
+
+One valuable way to learn a new programming language is to @emph{read}
+programs in that language. To that end, this @value{CHAPTER}
+and @ref{Sample Programs},
+provide a good-sized body of code for you to read,
+and hopefully, to learn from.
+
+@c 2e: USE TEXINFO-2 FUNCTION DEFINITION STUFF!!!!!!!!!!!!!
+This @value{CHAPTER} presents a library of useful @command{awk} functions.
+Many of the sample programs presented later in this @value{DOCUMENT}
+use these functions.
+The functions are presented here in a progression from simple to complex.
+
+@cindex Texinfo
+@ref{Extract Program},
+presents a program that you can use to extract the source code for
+these example library functions and programs from the Texinfo source
+for this @value{DOCUMENT}.
+(This has already been done as part of the @command{gawk} distribution.)
+
+If you have written one or more useful, general-purpose @command{awk} functions
+and would like to contribute them to the author's collection of @command{awk}
+programs, see
+@ref{How To Contribute}, for more information.
+
+@cindex portability, example programs
+The programs in this @value{CHAPTER} and in
+@ref{Sample Programs},
+freely use features that are @command{gawk}-specific.
+Rewriting these programs for different implementations of awk is pretty straightforward.
+
+Diagnostic error messages are sent to @file{/dev/stderr}.
+Use @samp{| "cat 1>&2"} instead of @samp{> "/dev/stderr"} if your system
+does not have a @file{/dev/stderr}, or if you cannot use @command{gawk}.
+
+A number of programs use @code{nextfile}
+(@pxref{Nextfile Statement})
+to skip any remaining input in the input file.
+@ref{Nextfile Function},
+shows you how to write a function that does the same thing.
+
+@c 12/2000: Thanks to Nelson Beebe for pointing out the output issue.
+@cindex case sensitivity, example programs
+@cindex @code{IGNORECASE} variable, in example programs
+Finally, some of the programs choose to ignore upper- and lowercase
+distinctions in their input. They do so by assigning one to @code{IGNORECASE}.
+You can achieve almost the same effect@footnote{The effects are
+not identical. Output of the transformed
+record will be in all lowercase, while @code{IGNORECASE} preserves the original
+contents of the input record.} by adding the following rule to the
+beginning of the program:
+
+@example
+# ignore case
+@{ $0 = tolower($0) @}
+@end example
+
+@noindent
+Also, verify that all regexp and string constants used in
+comparisons use only lowercase letters.
+
+@menu
+* Library Names:: How to best name private global variables in
+ library functions.
+* General Functions:: Functions that are of general use.
+* Data File Management:: Functions for managing command-line data
+ files.
+* Getopt Function:: A function for processing command-line
+ arguments.
+* Passwd Functions:: Functions for getting user information.
+* Group Functions:: Functions for getting group information.
+@end menu
+
+@node Library Names
+@section Naming Library Function Global Variables
+
+@cindex names, arrays/variables
+@cindex names, functions
+@cindex namespace issues
+@cindex @command{awk} programs, documenting
+@cindex documentation, of @command{awk} programs
+Due to the way the @command{awk} language evolved, variables are either
+@dfn{global} (usable by the entire program) or @dfn{local} (usable just by
+a specific function). There is no intermediate state analogous to
+@code{static} variables in C.
+
+@cindex variables, global, for library functions
+@cindex private variables
+@cindex variables, private
+Library functions often need to have global variables that they can use to
+preserve state information between calls to the function---for example,
+@code{getopt}'s variable @code{_opti}
+(@pxref{Getopt Function}).
+Such variables are called @dfn{private}, since the only functions that need to
+use them are the ones in the library.
+
+When writing a library function, you should try to choose names for your
+private variables that will not conflict with any variables used by
+either another library function or a user's main program. For example, a
+name like @samp{i} or @samp{j} is not a good choice, because user programs
+often use variable names like these for their own purposes.
+
+@cindex programming conventions, private variable names
+The example programs shown in this @value{CHAPTER} all start the names of their
+private variables with an underscore (@samp{_}). Users generally don't use
+leading underscores in their variable names, so this convention immediately
+decreases the chances that the variable name will be accidentally shared
+with the user's program.
+
+@cindex @code{_} (underscore), in names of private variables
+@cindex underscore (@code{_}), in names of private variables
+In addition, several of the library functions use a prefix that helps
+indicate what function or set of functions use the variables---for example,
+@code{_pw_byname} in the user database routines
+(@pxref{Passwd Functions}).
+This convention is recommended, since it even further decreases the
+chance of inadvertent conflict among variable names. Note that this
+convention is used equally well for variable names and for private
+function names as well.@footnote{While all the library routines could have
+been rewritten to use this convention, this was not done, in order to
+show how my own @command{awk} programming style has evolved and to
+provide some basis for this discussion.}
+
+As a final note on variable naming, if a function makes global variables
+available for use by a main program, it is a good convention to start that
+variable's name with a capital letter---for
+example, @code{getopt}'s @code{Opterr} and @code{Optind} variables
+(@pxref{Getopt Function}).
+The leading capital letter indicates that it is global, while the fact that
+the variable name is not all capital letters indicates that the variable is
+not one of @command{awk}'s built-in variables, such as @code{FS}.
+
+@cindex @code{--dump-variables} option
+It is also important that @emph{all} variables in library
+functions that do not need to save state are, in fact, declared
+local.@footnote{@command{gawk}'s @option{--dump-variables} command-line
+option is useful for verifying this.} If this is not done, the variable
+could accidentally be used in the user's program, leading to bugs that
+are very difficult to track down:
+
+@example
+function lib_func(x, y, l1, l2)
+@{
+ @dots{}
+ @var{use variable} some_var # some_var should be local
+ @dots{} # but is not by oversight
+@}
+@end example
+
+@cindex arrays, associative, library functions and
+@cindex libraries of @command{awk} functions, associative arrays and
+@cindex functions, library, associative arrays and
+@cindex Tcl
+A different convention, common in the Tcl community, is to use a single
+associative array to hold the values needed by the library function(s), or
+``package.'' This significantly decreases the number of actual global names
+in use. For example, the functions described in
+@ref{Passwd Functions},
+might have used array elements @code{@w{PW_data["inited"]}}, @code{@w{PW_data["total"]}},
+@code{@w{PW_data["count"]}}, and @code{@w{PW_data["awklib"]}}, instead of
+@code{@w{_pw_inited}}, @code{@w{_pw_awklib}}, @code{@w{_pw_total}},
+and @code{@w{_pw_count}}.
+
+The conventions presented in this @value{SECTION} are exactly
+that: conventions. You are not required to write your programs this
+way---we merely recommend that you do so.
+
+@node General Functions
+@section General Programming
+
+This @value{SECTION} presents a number of functions that are of general
+programming use.
+
+@menu
+* Nextfile Function:: Two implementations of a @code{nextfile}
+ function.
+* Strtonum Function:: A replacement for the built-in @code{strtonum}
+ function.
+* Assert Function:: A function for assertions in @command{awk}
+ programs.
+* Round Function:: A function for rounding if @code{sprintf} does
+ not do it correctly.
+* Cliff Random Function:: The Cliff Random Number Generator.
+* Ordinal Functions:: Functions for using characters as numbers and
+ vice versa.
+* Join Function:: A function to join an array into a string.
+* Gettimeofday Function:: A function to get formatted times.
+@end menu
+
+@node Nextfile Function
+@subsection Implementing @code{nextfile} as a Function
+
+@cindex input files, skipping
+@c STARTOFRANGE libfnex
+@cindex libraries of @command{awk} functions, @code{nextfile} statement
+@c STARTOFRANGE flibnex
+@cindex functions, library, @code{nextfile} statement
+@c STARTOFRANGE nexim
+@cindex @code{nextfile} statement, implementing
+@cindex @command{gawk}, @code{nextfile} statement in
+The @code{nextfile} statement, presented in
+@ref{Nextfile Statement},
+is a @command{gawk}-specific extension---it is not available in most other
+implementations of @command{awk}. This @value{SECTION} shows two versions of a
+@code{nextfile} function that you can use to simulate @command{gawk}'s
+@code{nextfile} statement if you cannot use @command{gawk}.
+
+A first attempt at writing a @code{nextfile} function is as follows:
+
+@example
+# nextfile --- skip remaining records in current file
+# this should be read in before the "main" awk program
+
+function nextfile() @{ _abandon_ = FILENAME; next @}
+_abandon_ == FILENAME @{ next @}
+@end example
+
+@cindex programming conventions, @code{nextfile} statement
+Because it supplies a rule that must be executed first, this file should
+be included before the main program. This rule compares the current
+@value{DF}'s name (which is always in the @code{FILENAME} variable) to
+a private variable named @code{_abandon_}. If the @value{FN} matches,
+then the action part of the rule executes a @code{next} statement to
+go on to the next record. (The use of @samp{_} in the variable name is
+a convention. It is discussed more fully in
+@ref{Library Names}.)
+
+The use of the @code{next} statement effectively creates a loop that reads
+all the records from the current @value{DF}.
+The end of the file is eventually reached and
+a new @value{DF} is opened, changing the value of @code{FILENAME}.
+Once this happens, the comparison of @code{_abandon_} to @code{FILENAME}
+fails, and execution continues with the first rule of the ``real'' program.
+
+The @code{nextfile} function itself simply sets the value of @code{_abandon_}
+and then executes a @code{next} statement to start the
+loop.
+@ignore
+@c If the function can't be used on other versions of awk, this whole
+@c section is pointless, no? Sigh.
+@footnote{@command{gawk} is the only known @command{awk} implementation
+that allows you to
+execute @code{next} from within a function body. Some other workaround
+is necessary if you are not using @command{gawk}.}
+@end ignore
+
+@cindex @code{nextfile} user-defined function
+This initial version has a subtle problem.
+If the same @value{DF} is listed @emph{twice} on the commandline,
+one right after the other
+or even with just a variable assignment between them,
+this code skips right through the file a second time, even though
+it should stop when it gets to the end of the first occurrence.
+A second version of @code{nextfile} that remedies this problem
+is shown here:
+
+@example
+@c file eg/lib/nextfile.awk
+# nextfile --- skip remaining records in current file
+# correctly handle successive occurrences of the same file
+@c endfile
+@ignore
+@c file eg/lib/nextfile.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May, 1993
+
+@c endfile
+@end ignore
+@c file eg/lib/nextfile.awk
+# this should be read in before the "main" awk program
+
+function nextfile() @{ _abandon_ = FILENAME; next @}
+
+_abandon_ == FILENAME @{
+ if (FNR == 1)
+ _abandon_ = ""
+ else
+ next
+@}
+@c endfile
+@end example
+
+The @code{nextfile} function has not changed. It makes @code{_abandon_}
+equal to the current @value{FN} and then executes a @code{next} statement.
+The @code{next} statement reads the next record and increments @code{FNR}
+so that @code{FNR} is guaranteed to have a value of at least two.
+However, if @code{nextfile} is called for the last record in the file,
+then @command{awk} closes the current @value{DF} and moves on to the next
+one. Upon doing so, @code{FILENAME} is set to the name of the new file
+and @code{FNR} is reset to one. If this next file is the same as
+the previous one, @code{_abandon_} is still equal to @code{FILENAME}.
+However, @code{FNR} is equal to one, telling us that this is a new
+occurrence of the file and not the one we were reading when the
+@code{nextfile} function was executed. In that case, @code{_abandon_}
+is reset to the empty string, so that further executions of this rule
+fail (until the next time that @code{nextfile} is called).
+
+If @code{FNR} is not one, then we are still in the original @value{DF}
+and the program executes a @code{next} statement to skip through it.
+
+An important question to ask at this point is: given that the
+functionality of @code{nextfile} can be provided with a library file,
+why is it built into @command{gawk}? Adding
+features for little reason leads to larger, slower programs that are
+harder to maintain.
+The answer is that building @code{nextfile} into @command{gawk} provides
+significant gains in efficiency. If the @code{nextfile} function is executed
+at the beginning of a large @value{DF}, @command{awk} still has to scan the entire
+file, splitting it up into records,
+@c at least conceptually
+just to skip over it. The built-in
+@code{nextfile} can simply close the file immediately and proceed to the
+next one, which saves a lot of time. This is particularly important in
+@command{awk}, because @command{awk} programs are generally I/O-bound (i.e.,
+they spend most of their time doing input and output, instead of performing
+computations).
+@c ENDOFRANGE libfnex
+@c ENDOFRANGE flibnex
+@c ENDOFRANGE nexim
+
+@node Strtonum Function
+@subsection Converting Strings To Numbers
+
+The @code{strtonum} function (@pxref{String Functions})
+is a @command{gawk} extension. The following function
+provides an implementation for other versions of @command{awk}:
+
+@example
+@c file eg/lib/strtonum.awk
+# strtonum --- convert string to number
+@c endfile
+@ignore
+@c file eg/lib/strtonum.awk
+
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# February, 2004
+
+@c endfile
+@end ignore
+@c file eg/lib/strtonum.awk
+function mystrtonum(str, ret, chars, n, i, k, c)
+@{
+ if (str ~ /^0[0-7]*$/) @{
+ # octal
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) @{
+ c = substr(str, i, 1)
+ if ((k = index("01234567", c)) > 0)
+ k-- # adjust for 1-basing in awk
+
+ ret = ret * 8 + k
+ @}
+ @} else if (str ~ /^0[xX][0-9a-fA-f]+/) @{
+ # hexadecimal
+ str = substr(str, 3) # lop off leading 0x
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) @{
+ c = substr(str, i, 1)
+ c = tolower(c)
+ if ((k = index("0123456789", c)) > 0)
+ k-- # adjust for 1-basing in awk
+ else if ((k = index("abcdef", c)) > 0)
+ k += 9
+
+ ret = ret * 16 + k
+ @}
+ @} else if (str ~ /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) @{
+ # decimal number, possibly floating point
+ ret = str + 0
+ @} else
+ ret = "NOT-A-NUMBER"
+
+ return ret
+@}
+
+# BEGIN @{ # gawk test harness
+# 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[7] = "1.32E2"
+#
+# for (i = 1; i in a; i++)
+# print a[i], strtonum(a[i]), mystrtonum(a[i])
+# @}
+@c endfile
+@end example
+
+The function first looks for C-style octal numbers (base 8).
+If the input string matches a regular expression describing octal
+numbers, then @code{mystrtonum} loops through each character in the
+string. It sets @code{k} to the index in @code{"01234567"} of the current
+octal digit. Since the return value is one-based, the @samp{k--}
+adjusts @code{k} so it can be used in computing the return value.
+
+Similar logic applies to the code that checks for and converts a
+hexadecimal value, which starts with @samp{0x} or @samp{0X}.
+The use of @code{tolower} simplifies the computation for finding
+the correct numeric value for each hexadecimal digit.
+
+Finally, if the string matches the (rather complicated) regex for a
+regular decimal integer or floating-point numer, the computation
+@samp{ret = str + 0} lets @command{awk} convert the value to a
+number.
+
+A commented-out test program is included, so that the function can
+be tested with @command{gawk} and the results compared to the built-in
+@code{strtonum} function.
+
+@node Assert Function
+@subsection Assertions
+
+@c STARTOFRANGE asse
+@cindex assertions
+@c STARTOFRANGE assef
+@cindex @code{assert} function (C library)
+@c STARTOFRANGE libfass
+@cindex libraries of @command{awk} functions, assertions
+@c STARTOFRANGE flibass
+@cindex functions, library, assertions
+@cindex @command{awk} programs, lengthy, assertions
+When writing large programs, it is often useful to know
+that a condition or set of conditions is true. Before proceeding with a
+particular computation, you make a statement about what you believe to be
+the case. Such a statement is known as an
+@dfn{assertion}. The C language provides an @code{<assert.h>} header file
+and corresponding @code{assert} macro that the programmer can use to make
+assertions. If an assertion fails, the @code{assert} macro arranges to
+print a diagnostic message describing the condition that should have
+been true but was not, and then it kills the program. In C, using
+@code{assert} looks this:
+
+@example
+#include <assert.h>
+
+int myfunc(int a, double b)
+@{
+ assert(a <= 5 && b >= 17.1);
+ @dots{}
+@}
+@end example
+
+If the assertion fails, the program prints a message similar to this:
+
+@example
+prog.c:5: assertion failed: a <= 5 && b >= 17.1
+@end example
+
+@cindex @code{assert} user-defined function
+The C language makes it possible to turn the condition into a string for use
+in printing the diagnostic message. This is not possible in @command{awk}, so
+this @code{assert} function also requires a string version of the condition
+that is being tested.
+Following is the function:
+
+@example
+@c file eg/lib/assert.awk
+# assert --- assert that a condition is true. Otherwise exit.
+@c endfile
+@ignore
+@c file eg/lib/assert.awk
+
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May, 1993
+
+@c endfile
+@end ignore
+@c file eg/lib/assert.awk
+function assert(condition, string)
+@{
+ if (! condition) @{
+ printf("%s:%d: assertion failed: %s\n",
+ FILENAME, FNR, string) > "/dev/stderr"
+ _assert_exit = 1
+ exit 1
+ @}
+@}
+
+@group
+END @{
+ if (_assert_exit)
+ exit 1
+@}
+@end group
+@c endfile
+@end example
+
+The @code{assert} function tests the @code{condition} parameter. If it
+is false, it prints a message to standard error, using the @code{string}
+parameter to describe the failed condition. It then sets the variable
+@code{_assert_exit} to one and executes the @code{exit} statement.
+The @code{exit} statement jumps to the @code{END} rule. If the @code{END}
+rules finds @code{_assert_exit} to be true, it exits immediately.
+
+The purpose of the test in the @code{END} rule is to
+keep any other @code{END} rules from running. When an assertion fails, the
+program should exit immediately.
+If no assertions fail, then @code{_assert_exit} is still
+false when the @code{END} rule is run normally, and the rest of the
+program's @code{END} rules execute.
+For all of this to work correctly, @file{assert.awk} must be the
+first source file read by @command{awk}.
+The function can be used in a program in the following way:
+
+@example
+function myfunc(a, b)
+@{
+ assert(a <= 5 && b >= 17.1, "a <= 5 && b >= 17.1")
+ @dots{}
+@}
+@end example
+
+@noindent
+If the assertion fails, you see a message similar to the following:
+
+@example
+mydata:1357: assertion failed: a <= 5 && b >= 17.1
+@end example
+
+@cindex @code{END} pattern, @code{assert} user-defined function and
+There is a small problem with this version of @code{assert}.
+An @code{END} rule is automatically added
+to the program calling @code{assert}. Normally, if a program consists
+of just a @code{BEGIN} rule, the input files and/or standard input are
+not read. However, now that the program has an @code{END} rule, @command{awk}
+attempts to read the input @value{DF}s or standard input
+(@pxref{Using BEGIN/END}),
+most likely causing the program to hang as it waits for input.
+
+@cindex @code{BEGIN} pattern, @code{assert} user-defined function and
+There is a simple workaround to this:
+make sure the @code{BEGIN} rule always ends
+with an @code{exit} statement.
+@c ENDOFRANGE asse
+@c ENDOFRANGE assef
+@c ENDOFRANGE flibass
+@c ENDOFRANGE libfass
+
+@node Round Function
+@subsection Rounding Numbers
+
+@cindex rounding
+@cindex rounding numbers
+@cindex numbers, rounding
+@cindex libraries of @command{awk} functions, rounding numbers
+@cindex functions, library, rounding numbers
+@cindex @code{print} statement, @code{sprintf} function and
+@cindex @code{printf} statement, @code{sprintf} function and
+@cindex @code{sprintf} function, @code{print}/@code{printf} statements and
+The way @code{printf} and @code{sprintf}
+(@pxref{Printf})
+perform rounding often depends upon the system's C @code{sprintf}
+subroutine. On many machines, @code{sprintf} rounding is ``unbiased,''
+which means it doesn't always round a trailing @samp{.5} up, contrary
+to naive expectations. In unbiased rounding, @samp{.5} rounds to even,
+rather than always up, so 1.5 rounds to 2 but 4.5 rounds to 4. This means
+that if you are using a format that does rounding (e.g., @code{"%.0f"}),
+you should check what your system does. The following function does
+traditional rounding; it might be useful if your awk's @code{printf}
+does unbiased rounding:
+
+@cindex @code{round} user-defined function
+@example
+@c file eg/lib/round.awk
+# round.awk --- do normal rounding
+@c endfile
+@ignore
+@c file eg/lib/round.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# August, 1996
+
+@c endfile
+@end ignore
+@c file eg/lib/round.awk
+function round(x, ival, aval, fraction)
+@{
+ ival = int(x) # integer part, int() truncates
+
+ # see if fractional part
+ if (ival == x) # no fraction
+ return x
+
+ if (x < 0) @{
+ aval = -x # absolute value
+ ival = int(aval)
+ fraction = aval - ival
+ if (fraction >= .5)
+ return int(x) - 1 # -2.5 --> -3
+ else
+ return int(x) # -2.3 --> -2
+ @} else @{
+ fraction = x - ival
+ if (fraction >= .5)
+ return ival + 1
+ else
+ return ival
+ @}
+@}
+
+# test harness
+@{ print $0, round($0) @}
+@c endfile
+@end example
+
+@node Cliff Random Function
+@subsection The Cliff Random Number Generator
+@cindex random numbers, Cliff
+@cindex Cliff random numbers
+@cindex numbers, Cliff random
+@cindex functions, library, Cliff random numbers
+
+The Cliff random number
+generator@footnote{@uref{http://mathworld.wolfram.com/CliffRandomNumberGenerator.hmtl}}
+is a very simple random number generator that ``passes the noise sphere test
+for randomness by showing no structure.''
+It is easily programmed, in less than 10 lines of @command{awk} code:
+
+@cindex @code{cliff_rand} user-defined function
+@example
+@c file eg/lib/cliff_rand.awk
+# cliff_rand.awk --- generate Cliff random numbers
+@c endfile
+@ignore
+@c file eg/lib/cliff_rand.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# December 2000
+
+@c endfile
+@end ignore
+@c file eg/lib/cliff_rand.awk
+BEGIN @{ _cliff_seed = 0.1 @}
+
+function cliff_rand()
+@{
+ _cliff_seed = (100 * log(_cliff_seed)) % 1
+ if (_cliff_seed < 0)
+ _cliff_seed = - _cliff_seed
+ return _cliff_seed
+@}
+@c endfile
+@end example
+
+This algorithm requires an initial ``seed'' of 0.1. Each new value
+uses the current seed as input for the calculation.
+If the built-in @code{rand} function
+(@pxref{Numeric Functions})
+isn't random enough, you might try using this function instead.
+
+@node Ordinal Functions
+@subsection Translating Between Characters and Numbers
+
+@cindex libraries of @command{awk} functions, character values as numbers
+@cindex functions, library, character values as numbers
+@cindex characters, values of as numbers
+@cindex numbers, as values of characters
+One commercial implementation of @command{awk} supplies a built-in function,
+@code{ord}, which takes a character and returns the numeric value for that
+character in the machine's character set. If the string passed to
+@code{ord} has more than one character, only the first one is used.
+
+The inverse of this function is @code{chr} (from the function of the same
+name in Pascal), which takes a number and returns the corresponding character.
+Both functions are written very nicely in @command{awk}; there is no real
+reason to build them into the @command{awk} interpreter:
+
+@cindex @code{ord} user-defined function
+@cindex @code{chr} user-defined function
+@example
+@c file eg/lib/ord.awk
+# ord.awk --- do ord and chr
+
+# Global identifiers:
+# _ord_: numerical values indexed by characters
+# _ord_init: function to initialize _ord_
+@c endfile
+@ignore
+@c file eg/lib/ord.awk
+#
+# Arnold Robbins, arnold@@gnu.org, 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( low, high, i, t)
+@{
+ low = sprintf("%c", 7) # BEL is ascii 7
+ if (low == "\a") @{ # regular ascii
+ low = 0
+ high = 127
+ @} else if (sprintf("%c", 128 + 7) == "\a") @{
+ # ascii, mark parity
+ low = 128
+ high = 255
+ @} else @{ # ebcdic(!)
+ low = 0
+ high = 255
+ @}
+
+ for (i = low; i <= high; i++) @{
+ t = sprintf("%c", i)
+ _ord_[t] = i
+ @}
+@}
+@c endfile
+@end example
+
+@cindex character sets
+@cindex character encodings
+@cindex ASCII
+@cindex EBCDIC
+@cindex mark parity
+Some explanation of the numbers used by @code{chr} is worthwhile.
+The most prominent character set in use today is ASCII. Although an
+8-bit byte can hold 256 distinct values (from 0 to 255), ASCII only
+defines characters that use the values from 0 to 127.@footnote{ASCII
+has been extended in many countries to use the values from 128 to 255
+for country-specific characters. If your system uses these extensions,
+you can simplify @code{_ord_init} to simply loop from 0 to 255.}
+In the now distant past,
+at least one minicomputer manufacturer
+@c Pr1me, blech
+used ASCII, but with mark parity, meaning that the leftmost bit in the byte
+is always 1. This means that on those systems, characters
+have numeric values from 128 to 255.
+Finally, large mainframe systems use the EBCDIC character set, which
+uses all 256 values.
+While there are other character sets in use on some older systems,
+they are not really worth worrying about:
+
+@example
+@c file eg/lib/ord.awk
+function ord(str, c)
+@{
+ # only first character is of interest
+ c = substr(str, 1, 1)
+ return _ord_[c]
+@}
+
+function chr(c)
+@{
+ # force c to be numeric by adding 0
+ return sprintf("%c", c + 0)
+@}
+@c endfile
+
+#### test code ####
+# BEGIN \
+# @{
+# for (;;) @{
+# printf("enter a character: ")
+# if (getline var <= 0)
+# break
+# printf("ord(%s) = %d\n", var, ord(var))
+# @}
+# @}
+@c endfile
+@end example
+
+An obvious improvement to these functions is to move the code for the
+@code{@w{_ord_init}} function into the body of the @code{BEGIN} rule. It was
+written this way initially for ease of development.
+There is a ``test program'' in a @code{BEGIN} rule, to test the
+function. It is commented out for production use.
+
+@node Join Function
+@subsection Merging an Array into a String
+
+@cindex libraries of @command{awk} functions, merging arrays into strings
+@cindex functions, library, merging arrays into strings
+@cindex strings, merging arrays into
+@cindex arrays, merging into strings
+When doing string processing, it is often useful to be able to join
+all the strings in an array into one long string. The following function,
+@code{join}, accomplishes this task. It is used later in several of
+the application programs
+(@pxref{Sample Programs}).
+
+Good function design is important; this function needs to be general but it
+should also have a reasonable default behavior. It is called with an array
+as well as the beginning and ending indices of the elements in the array to be
+merged. This assumes that the array indices are numeric---a reasonable
+assumption since the array was likely created with @code{split}
+(@pxref{String Functions}):
+
+@cindex @code{join} user-defined function
+@example
+@c file eg/lib/join.awk
+# join.awk --- join an array into a string
+@c endfile
+@ignore
+@c file eg/lib/join.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/lib/join.awk
+function join(array, start, end, sep, result, i)
+@{
+ if (sep == "")
+ sep = " "
+ else if (sep == SUBSEP) # magic value
+ sep = ""
+ result = array[start]
+ for (i = start + 1; i <= end; i++)
+ result = result sep array[i]
+ return result
+@}
+@c endfile
+@end example
+
+An optional additional argument is the separator to use when joining the
+strings back together. If the caller supplies a nonempty value,
+@code{join} uses it; if it is not supplied, it has a null
+value. In this case, @code{join} uses a single blank as a default
+separator for the strings. If the value is equal to @code{SUBSEP},
+then @code{join} joins the strings with no separator between them.
+@code{SUBSEP} serves as a ``magic'' value to indicate that there should
+be no separation between the component strings.@footnote{It would
+be nice if @command{awk} had an assignment operator for concatenation.
+The lack of an explicit operator for concatenation makes string operations
+more difficult than they really need to be.}
+
+@node Gettimeofday Function
+@subsection Managing the Time of Day
+
+@cindex libraries of @command{awk} functions, managing, time
+@cindex functions, library, managing time
+@cindex timestamps, formatted
+@cindex time, managing
+The @code{systime} and @code{strftime} functions described in
+@ref{Time Functions},
+provide the minimum functionality necessary for dealing with the time of day
+in human readable form. While @code{strftime} is extensive, the control
+formats are not necessarily easy to remember or intuitively obvious when
+reading a program.
+
+The following function, @code{gettimeofday}, populates a user-supplied array
+with preformatted time information. It returns a string with the current
+time formatted in the same way as the @command{date} utility:
+
+@cindex @code{gettimeofday} user-defined function
+@example
+@c file eg/lib/gettime.awk
+# gettimeofday.awk --- get the time of day in a usable format
+@c endfile
+@ignore
+@c file eg/lib/gettime.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain, May 1993
+#
+@c endfile
+@end ignore
+@c file eg/lib/gettime.awk
+
+# Returns a string in the format of output of date(1)
+# Populates the array argument time with individual values:
+# time["second"] -- seconds (0 - 59)
+# time["minute"] -- minutes (0 - 59)
+# time["hour"] -- hours (0 - 23)
+# time["althour"] -- hours (0 - 12)
+# time["monthday"] -- day of month (1 - 31)
+# time["month"] -- month of year (1 - 12)
+# time["monthname"] -- name of the month
+# time["shortmonth"] -- short name of the month
+# time["year"] -- year modulo 100 (0 - 99)
+# time["fullyear"] -- full year
+# time["weekday"] -- day of week (Sunday = 0)
+# time["altweekday"] -- day of week (Monday = 0)
+# time["dayname"] -- name of weekday
+# time["shortdayname"] -- short name of weekday
+# time["yearday"] -- day of year (0 - 365)
+# time["timezone"] -- abbreviation of timezone name
+# time["ampm"] -- AM or PM designation
+# time["weeknum"] -- week number, Sunday first day
+# time["altweeknum"] -- week number, Monday first day
+
+function gettimeofday(time, ret, now, i)
+@{
+ # get time once, avoids unnecessary system calls
+ now = systime()
+
+ # return date(1)-style output
+ ret = strftime("%a %b %d %H:%M:%S %Z %Y", now)
+
+ # clear out target array
+ delete time
+
+ # fill in values, force numeric values to be
+ # numeric by adding 0
+ time["second"] = strftime("%S", now) + 0
+ time["minute"] = strftime("%M", now) + 0
+ time["hour"] = strftime("%H", now) + 0
+ time["althour"] = strftime("%I", now) + 0
+ time["monthday"] = strftime("%d", now) + 0
+ time["month"] = strftime("%m", now) + 0
+ time["monthname"] = strftime("%B", now)
+ time["shortmonth"] = strftime("%b", now)
+ time["year"] = strftime("%y", now) + 0
+ time["fullyear"] = strftime("%Y", now) + 0
+ time["weekday"] = strftime("%w", now) + 0
+ time["altweekday"] = strftime("%u", now) + 0
+ time["dayname"] = strftime("%A", now)
+ time["shortdayname"] = strftime("%a", now)
+ time["yearday"] = strftime("%j", now) + 0
+ time["timezone"] = strftime("%Z", now)
+ time["ampm"] = strftime("%p", now)
+ time["weeknum"] = strftime("%U", now) + 0
+ time["altweeknum"] = strftime("%W", now) + 0
+
+ return ret
+@}
+@c endfile
+@end example
+
+The string indices are easier to use and read than the various formats
+required by @code{strftime}. The @code{alarm} program presented in
+@ref{Alarm Program},
+uses this function.
+A more general design for the @code{gettimeofday} function would have
+allowed the user to supply an optional timestamp value to use instead
+of the current time.
+
+@node Data File Management
+@section @value{DDF} Management
+
+@c STARTOFRANGE dataf
+@cindex files, managing
+@c STARTOFRANGE libfdataf
+@cindex libraries of @command{awk} functions, managing, @value{DF}s
+@c STARTOFRANGE flibdataf
+@cindex functions, library, managing @value{DF}s
+This @value{SECTION} presents functions that are useful for managing
+command-line @value{DF}s.
+
+@menu
+* Filetrans Function:: A function for handling data file transitions.
+* Rewind Function:: A function for rereading the current file.
+* File Checking:: Checking that data files are readable.
+* Empty Files:: Checking for zero-length files.
+* Ignoring Assigns:: Treating assignments as file names.
+@end menu
+
+@node Filetrans Function
+@subsection Noting @value{DDF} Boundaries
+
+@cindex files, managing, @value{DF} boundaries
+@cindex files, initialization and cleanup
+The @code{BEGIN} and @code{END} rules are each executed exactly once at
+the beginning and end of your @command{awk} program, respectively
+(@pxref{BEGIN/END}).
+We (the @command{gawk} authors) once had a user who mistakenly thought that the
+@code{BEGIN} rule is executed at the beginning of each @value{DF} and the
+@code{END} rule is executed at the end of each @value{DF}. When informed
+that this was not the case, the user requested that we add new special
+patterns to @command{gawk}, named @code{BEGIN_FILE} and @code{END_FILE}, that
+would have the desired behavior. He even supplied us the code to do so.
+
+Adding these special patterns to @command{gawk} wasn't necessary;
+the job can be done cleanly in @command{awk} itself, as illustrated
+by the following library program.
+It arranges to call two user-supplied functions, @code{beginfile} and
+@code{endfile}, at the beginning and end of each @value{DF}.
+Besides solving the problem in only nine(!) lines of code, it does so
+@emph{portably}; this works with any implementation of @command{awk}:
+
+@example
+# transfile.awk
+#
+# Give the user a hook for filename transitions
+#
+# The user must supply functions beginfile() and endfile()
+# that each take the name of the file being started or
+# finished, respectively.
+@c #
+@c # Arnold Robbins, arnold@@gnu.org, Public Domain
+@c # January 1992
+
+FILENAME != _oldfilename \
+@{
+ if (_oldfilename != "")
+ endfile(_oldfilename)
+ _oldfilename = FILENAME
+ beginfile(FILENAME)
+@}
+
+END @{ endfile(FILENAME) @}
+@end example
+
+This file must be loaded before the user's ``main'' program, so that the
+rule it supplies is executed first.
+
+This rule relies on @command{awk}'s @code{FILENAME} variable that
+automatically changes for each new @value{DF}. The current @value{FN} is
+saved in a private variable, @code{_oldfilename}. If @code{FILENAME} does
+not equal @code{_oldfilename}, then a new @value{DF} is being processed and
+it is necessary to call @code{endfile} for the old file. Because
+@code{endfile} should only be called if a file has been processed, the
+program first checks to make sure that @code{_oldfilename} is not the null
+string. The program then assigns the current @value{FN} to
+@code{_oldfilename} and calls @code{beginfile} for the file.
+Because, like all @command{awk} variables, @code{_oldfilename} is
+initialized to the null string, this rule executes correctly even for the
+first @value{DF}.
+
+The program also supplies an @code{END} rule to do the final processing for
+the last file. Because this @code{END} rule comes before any @code{END} rules
+supplied in the ``main'' program, @code{endfile} is called first. Once
+again the value of multiple @code{BEGIN} and @code{END} rules should be clear.
+
+@cindex @code{beginfile} user-defined function
+@cindex @code{endfile} user-defined function
+This version has same problem as the first version of @code{nextfile}
+(@pxref{Nextfile Function}).
+If the same @value{DF} occurs twice in a row on the command line, then
+@code{endfile} and @code{beginfile} are not executed at the end of the
+first pass and at the beginning of the second pass.
+The following version solves the problem:
+
+@example
+@c file eg/lib/ftrans.awk
+# ftrans.awk --- handle data file transitions
+#
+# user supplies beginfile() and endfile() functions
+@c endfile
+@ignore
+@c file eg/lib/ftrans.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# November 1992
+
+@c endfile
+@end ignore
+@c file eg/lib/ftrans.awk
+FNR == 1 @{
+ if (_filename_ != "")
+ endfile(_filename_)
+ _filename_ = FILENAME
+ beginfile(FILENAME)
+@}
+
+END @{ endfile(_filename_) @}
+@c endfile
+@end example
+
+@ref{Wc Program},
+shows how this library function can be used and
+how it simplifies writing the main program.
+
+@node Rewind Function
+@subsection Rereading the Current File
+
+@cindex files, reading
+Another request for a new built-in function was for a @code{rewind}
+function that would make it possible to reread the current file.
+The requesting user didn't want to have to use @code{getline}
+(@pxref{Getline})
+inside a loop.
+
+However, as long as you are not in the @code{END} rule, it is
+quite easy to arrange to immediately close the current input file
+and then start over with it from the top.
+For lack of a better name, we'll call it @code{rewind}:
+
+@cindex @code{rewind} user-defined function
+@example
+@c file eg/lib/rewind.awk
+# rewind.awk --- rewind the current file and start over
+@c endfile
+@ignore
+@c file eg/lib/rewind.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# September 2000
+
+@c endfile
+@end ignore
+@c file eg/lib/rewind.awk
+function rewind( i)
+@{
+ # shift remaining arguments up
+ for (i = ARGC; i > ARGIND; i--)
+ ARGV[i] = ARGV[i-1]
+
+ # make sure gawk knows to keep going
+ ARGC++
+
+ # make current file next to get done
+ ARGV[ARGIND+1] = FILENAME
+
+ # do it
+ nextfile
+@}
+@c endfile
+@end example
+
+This code relies on the @code{ARGIND} variable
+(@pxref{Auto-set}),
+which is specific to @command{gawk}.
+If you are not using
+@command{gawk}, you can use ideas presented in
+@ifnotinfo
+the previous @value{SECTION}
+@end ifnotinfo
+@ifinfo
+@ref{Filetrans Function},
+@end ifinfo
+to either update @code{ARGIND} on your own
+or modify this code as appropriate.
+
+The @code{rewind} function also relies on the @code{nextfile} keyword
+(@pxref{Nextfile Statement}).
+@xref{Nextfile Function},
+for a function version of @code{nextfile}.
+
+@node File Checking
+@subsection Checking for Readable @value{DDF}s
+
+@cindex troubleshooting, readable @value{DF}s
+@cindex readable @value{DF}s@comma{} checking
+@cindex files, skipping
+Normally, if you give @command{awk} a @value{DF} that isn't readable,
+it stops with a fatal error. There are times when you
+might want to just ignore such files and keep going. You can
+do this by prepending the following program to your @command{awk}
+program:
+
+@cindex @code{readable.awk} program
+@example
+@c file eg/lib/readable.awk
+# readable.awk --- library file to skip over unreadable files
+@c endfile
+@ignore
+@c file eg/lib/readable.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# October 2000
+
+@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] == "-")
+ continue # assignment or standard input
+ else if ((getline junk < ARGV[i]) < 0) # unreadable
+ delete ARGV[i]
+ else
+ close(ARGV[i])
+ @}
+@}
+@c endfile
+@end example
+
+@cindex troubleshooting, @code{getline} function
+In @command{gawk}, the @code{getline} won't be fatal (unless
+@option{--posix} is in force).
+Removing the element from @code{ARGV} with @code{delete}
+skips the file (since it's no longer in the list).
+
+@c This doesn't handle /dev/stdin etc. Not worth the hassle to mention or fix.
+
+@node Empty Files
+@subsection Checking For Zero-length Files
+
+All known @command{awk} implementations silently skip over zero-length files.
+This is a by-product of @command{awk}'s implicit
+read-a-record-and-match-against-the-rules loop: when @command{awk}
+tries to read a record from an empty file, it immediately receives an
+end of file indication, closes the file, and proceeds on to the next
+command-line @value{DF}, @emph{without} executing any user-level
+@command{awk} program code.
+
+Using @command{gawk}'s @code{ARGIND} variable
+(@pxref{Built-in Variables}), it is possible to detect when an empty
+@value{DF} has been skipped. Similar to the library file presented
+in @ref{Filetrans Function}, the following library file calls a function named
+@code{zerofile} that the user must provide. The arguments passed are
+the @value{FN} and the position in @code{ARGV} where it was found:
+
+@cindex @code{zerofile.awk} program
+@example
+@c file eg/lib/zerofile.awk
+# zerofile.awk --- library file to process empty input files
+@c endfile
+@ignore
+@c file eg/lib/zerofile.awk
+#
+# Arnold Robbins, arnold@@gnu.org, 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
+
+The user-level variable @code{Argind} allows the @command{awk} program
+to track its progress through @code{ARGV}. Whenever the program detects
+that @code{ARGIND} is greater than @samp{Argind + 1}, it means that one or
+more empty files were skipped. The action then calls @code{zerofile} for
+each such file, incrementing @code{Argind} along the way.
+
+The @samp{Argind != ARGIND} rule simply keeps @code{Argind} up to date
+in the normal case.
+
+Finally, the @code{END} rule catches the case of any empty files at
+the end of the command-line arguments. Note that the test in the
+condition of the @code{for} loop uses the @samp{<=} operator,
+not @code{<}.
+
+As an exercise, you might consider whether this same problem can
+be solved without relying on @command{gawk}'s @code{ARGIND} variable.
+
+As a second exercise, revise this code to handle the case where
+an intervening value in @code{ARGV} is a variable assignment.
+
+@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
+
+@node Ignoring Assigns
+@subsection Treating Assignments as @value{FFN}s
+
+@cindex assignments as filenames
+@cindex filenames, assignments as
+Occasionally, you might not want @command{awk} to process command-line
+variable assignments
+(@pxref{Assignment Options}).
+In particular, if you have @value{FN}s that contain an @samp{=} character,
+@command{awk} treats the @value{FN} as an assignment, and does not process it.
+
+Some users have suggested an additional command-line option for @command{gawk}
+to disable command-line assignments. However, some simple programming with
+a library file does the trick:
+
+@cindex @code{noassign.awk} program
+@example
+@c file eg/lib/noassign.awk
+# noassign.awk --- library file to avoid the need for a
+# special option that disables command-line assignments
+@c endfile
+@ignore
+@c file eg/lib/noassign.awk
+#
+# Arnold Robbins, arnold@@gnu.org, 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-z_0-9]*=.*/)
+ argv[i] = ("./" argv[i])
+@}
+
+BEGIN @{
+ if (No_command_assign)
+ disable_assigns(ARGC, ARGV)
+@}
+@c endfile
+@end example
+
+You then run your program this way:
+
+@example
+awk -v No_command_assign=1 -f noassign.awk -f yourprog.awk *
+@end example
+
+The function works by looping through the arguments.
+It prepends @samp{./} to
+any argument that matches the form
+of a variable assignment, turning that argument into a @value{FN}.
+
+The use of @code{No_command_assign} allows you to disable command-line
+assignments at invocation time, by giving the variable a true value.
+When not set, it is initially zero (i.e., false), so the command-line arguments
+are left alone.
+@c ENDOFRANGE dataf
+@c ENDOFRANGE flibdataf
+@c ENDOFRANGE libfdataf
+
+@node Getopt Function
+@section Processing Command-Line Options
+
+@c STARTOFRANGE libfclo
+@cindex libraries of @command{awk} functions, command-line options
+@c STARTOFRANGE flibclo
+@cindex functions, library, command-line options
+@c STARTOFRANGE clop
+@cindex command-line options, processing
+@c STARTOFRANGE oclp
+@cindex options, command-line, processing
+@c STARTOFRANGE clibf
+@cindex functions, library, C library
+@cindex arguments, processing
+Most utilities on POSIX compatible systems take options, or ``switches,'' on
+the command line that can be used to change the way a program behaves.
+@command{awk} is an example of such a program
+(@pxref{Options}).
+Often, options take @dfn{arguments}; i.e., data that the program needs to
+correctly obey the command-line option. For example, @command{awk}'s
+@option{-F} option requires a string to use as the field separator.
+The first occurrence on the command line of either @option{--} or a
+string that does not begin with @samp{-} ends the options.
+
+@cindex @code{getopt} function (C library)
+Modern Unix systems provide a C function named @code{getopt} for processing
+command-line arguments. The programmer provides a string describing the
+one-letter options. If an option requires an argument, it is followed in the
+string with a colon. @code{getopt} is also passed the
+count and values of the command-line arguments and is called in a loop.
+@code{getopt} processes the command-line arguments for option letters.
+Each time around the loop, it returns a single character representing the
+next option letter that it finds, or @samp{?} if it finds an invalid option.
+When it returns @minus{}1, there are no options left on the command line.
+
+When using @code{getopt}, options that do not take arguments can be
+grouped together. Furthermore, options that take arguments require that the
+argument is present. The argument can immediately follow the option letter,
+or it can be a separate command-line argument.
+
+Given a hypothetical program that takes
+three command-line options, @option{-a}, @option{-b}, and @option{-c}, where
+@option{-b} requires an argument, all of the following are valid ways of
+invoking the program:
+
+@example
+prog -a -b foo -c data1 data2 data3
+prog -ac -bfoo -- data1 data2 data3
+prog -acbfoo data1 data2 data3
+@end example
+
+Notice that when the argument is grouped with its option, the rest of
+the argument is considered to be the option's argument.
+In this example, @option{-acbfoo} indicates that all of the
+@option{-a}, @option{-b}, and @option{-c} options were supplied,
+and that @samp{foo} is the argument to the @option{-b} option.
+
+@code{getopt} provides four external variables that the programmer can use:
+
+@table @code
+@item optind
+The index in the argument value array (@code{argv}) where the first
+nonoption command-line argument can be found.
+
+@item optarg
+The string value of the argument to an option.
+
+@item opterr
+Usually @code{getopt} prints an error message when it finds an invalid
+option. Setting @code{opterr} to zero disables this feature. (An
+application might want to print its own error message.)
+
+@item optopt
+The letter representing the command-line option.
+@c While not usually documented, most versions supply this variable.
+@end table
+
+The following C fragment shows how @code{getopt} might process command-line
+arguments for @command{awk}:
+
+@example
+int
+main(int argc, char *argv[])
+@{
+ @dots{}
+ /* print our own message */
+ opterr = 0;
+ while ((c = getopt(argc, argv, "v:f:F:W:")) != -1) @{
+ switch (c) @{
+ case 'f': /* file */
+ @dots{}
+ break;
+ case 'F': /* field separator */
+ @dots{}
+ break;
+ case 'v': /* variable assignment */
+ @dots{}
+ break;
+ case 'W': /* extension */
+ @dots{}
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ @}
+ @}
+ @dots{}
+@}
+@end example
+
+As a side point, @command{gawk} actually uses the GNU @code{getopt_long}
+function to process both normal and GNU-style long options
+(@pxref{Options}).
+
+The abstraction provided by @code{getopt} is very useful and is quite
+handy in @command{awk} programs as well. Following is an @command{awk}
+version of @code{getopt}. This function highlights one of the
+greatest weaknesses in @command{awk}, which is that it is very poor at
+manipulating single characters. Repeated calls to @code{substr} are
+necessary for accessing individual characters
+(@pxref{String Functions}).@footnote{This
+function was written before @command{gawk} acquired the ability to
+split strings into single characters using @code{""} as the separator.
+We have left it alone, since using @code{substr} is more portable.}
+
+The discussion that follows walks through the code a bit at a time:
+
+@cindex @code{getopt} user-defined function
+@example
+@c file eg/lib/getopt.awk
+# getopt.awk --- do C library getopt(3) function in awk
+@c endfile
+@ignore
+@c file eg/lib/getopt.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+#
+# Initial version: March, 1991
+# Revised: May, 1993
+
+@c endfile
+@end ignore
+@c file eg/lib/getopt.awk
+# External variables:
+# Optind -- index in ARGV of first nonoption argument
+# Optarg -- string value of argument to current option
+# Opterr -- if nonzero, print our own diagnostic
+# Optopt -- current option letter
+
+# Returns:
+# -1 at end of options
+# ? for unrecognized option
+# <c> a character representing the current option
+
+# Private Data:
+# _opti -- index in multi-flag option, e.g., -abc
+@c endfile
+@end example
+
+The function starts out with
+a list of the global variables it uses,
+what the return values are, what they mean, and any global variables that
+are ``private'' to this library function. Such documentation is essential
+for any program, and particularly for library functions.
+
+The @code{getopt} function first checks that it was indeed called with a string of options
+(the @code{options} parameter). If @code{options} has a zero length,
+@code{getopt} immediately returns @minus{}1:
+
+@cindex @code{getopt} user-defined function
+@example
+@c file eg/lib/getopt.awk
+function getopt(argc, argv, options, thisopt, i)
+@{
+ if (length(options) == 0) # no options given
+ return -1
+
+@group
+ if (argv[Optind] == "--") @{ # all done
+ Optind++
+ _opti = 0
+ return -1
+@end group
+ @} else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) @{
+ _opti = 0
+ return -1
+ @}
+@c endfile
+@end example
+
+The next thing to check for is the end of the options. A @option{--}
+ends the command-line options, as does any command-line argument that
+does not begin with a @samp{-}. @code{Optind} is used to step through
+the array of command-line arguments; it retains its value across calls
+to @code{getopt}, because it is a global variable.
+
+The regular expression that is used, @code{@w{/^-[^: \t\n\f\r\v\b]/}}, is
+perhaps a bit of overkill; it checks for a @samp{-} followed by anything
+that is not whitespace and not a colon.
+If the current command-line argument does not match this pattern,
+it is not an option, and it ends option processing:
+
+@example
+@c file eg/lib/getopt.awk
+ if (_opti == 0)
+ _opti = 2
+ thisopt = substr(argv[Optind], _opti, 1)
+ Optopt = thisopt
+ i = index(options, thisopt)
+ if (i == 0) @{
+ if (Opterr)
+ printf("%c -- invalid option\n",
+ thisopt) > "/dev/stderr"
+ if (_opti >= length(argv[Optind])) @{
+ Optind++
+ _opti = 0
+ @} else
+ _opti++
+ return "?"
+ @}
+@c endfile
+@end example
+
+The @code{_opti} variable tracks the position in the current command-line
+argument (@code{argv[Optind]}). If multiple options are
+grouped together with one @samp{-} (e.g., @option{-abx}), it is necessary
+to return them to the user one at a time.
+
+If @code{_opti} is equal to zero, it is set to two, which is the index in
+the string of the next character to look at (we skip the @samp{-}, which
+is at position one). The variable @code{thisopt} holds the character,
+obtained with @code{substr}. It is saved in @code{Optopt} for the main
+program to use.
+
+If @code{thisopt} is not in the @code{options} string, then it is an
+invalid option. If @code{Opterr} is nonzero, @code{getopt} prints an error
+message on the standard error that is similar to the message from the C
+version of @code{getopt}.
+
+Because the option is invalid, it is necessary to skip it and move on to the
+next option character. If @code{_opti} is greater than or equal to the
+length of the current command-line argument, it is necessary to move on
+to the next argument, so @code{Optind} is incremented and @code{_opti} is reset
+to zero. Otherwise, @code{Optind} is left alone and @code{_opti} is merely
+incremented.
+
+In any case, because the option is invalid, @code{getopt} returns @samp{?}.
+The main program can examine @code{Optopt} if it needs to know what the
+invalid option letter actually is. Continuing on:
+
+@example
+@c file eg/lib/getopt.awk
+ if (substr(options, i + 1, 1) == ":") @{
+ # get option argument
+ 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
+
+If the option requires an argument, the option letter is followed by a colon
+in the @code{options} string. If there are remaining characters in the
+current command-line argument (@code{argv[Optind]}), then the rest of that
+string is assigned to @code{Optarg}. Otherwise, the next command-line
+argument is used (@samp{-xFOO} versus @samp{@w{-x FOO}}). In either case,
+@code{_opti} is reset to zero, because there are no more characters left to
+examine in the current command-line argument. Continuing:
+
+@example
+@c file eg/lib/getopt.awk
+ if (_opti == 0 || _opti >= length(argv[Optind])) @{
+ Optind++
+ _opti = 0
+ @} else
+ _opti++
+ return thisopt
+@}
+@c endfile
+@end example
+
+Finally, if @code{_opti} is either zero or greater than the length of the
+current command-line argument, it means this element in @code{argv} is
+through being processed, so @code{Optind} is incremented to point to the
+next element in @code{argv}. If neither condition is true, then only
+@code{_opti} is incremented, so that the next option letter can be processed
+on the next call to @code{getopt}.
+
+The @code{BEGIN} rule initializes both @code{Opterr} and @code{Optind} to one.
+@code{Opterr} is set to one, since the default behavior is for @code{getopt}
+to print a diagnostic message upon seeing an invalid option. @code{Optind}
+is set to one, since there's no reason to look at the program name, which is
+in @code{ARGV[0]}:
+
+@example
+@c file eg/lib/getopt.awk
+BEGIN @{
+ Opterr = 1 # default is to diagnose
+ Optind = 1 # skip ARGV[0]
+
+ # test program
+ if (_getopt_test) @{
+ while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
+ printf("c = <%c>, optarg = <%s>\n",
+ _go_c, Optarg)
+ printf("non-option arguments:\n")
+ for (; Optind < ARGC; Optind++)
+ printf("\tARGV[%d] = <%s>\n",
+ Optind, ARGV[Optind])
+ @}
+@}
+@c endfile
+@end example
+
+The rest of the @code{BEGIN} rule is a simple test program. Here is the
+result of two sample runs of the test program:
+
+@example
+$ 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{} non-option arguments:
+@print{} ARGV[3] = <bax>
+@print{} ARGV[4] = <-x>
+
+$ awk -f getopt.awk -v _getopt_test=1 -- -a -x -- xyz abc
+@print{} c = <a>, optarg = <>
+@error{} x -- invalid option
+@print{} c = <?>, optarg = <>
+@print{} non-option arguments:
+@print{} ARGV[4] = <xyz>
+@print{} ARGV[5] = <abc>
+@end example
+
+In both runs,
+the first @option{--} terminates the arguments to @command{awk}, so that it does
+not try to interpret the @option{-a}, etc., as its own options.
+Several of the sample programs presented in
+@ref{Sample Programs},
+use @code{getopt} to process their arguments.
+@c ENDOFRANGE libfclo
+@c ENDOFRANGE flibclo
+@c ENDOFRANGE clop
+@c ENDOFRANGE oclp
+
+@node Passwd Functions
+@section Reading the User Database
+
+@c STARTOFRANGE libfudata
+@cindex libraries of @command{awk} functions, user database, reading
+@c STARTOFRANGE flibudata
+@cindex functions, library, user database, reading
+@c STARTOFRANGE udatar
+@cindex user database@comma{} reading
+@c STARTOFRANGE dataur
+@cindex database, users@comma{} reading
+@cindex @code{PROCINFO} array
+The @code{PROCINFO} array
+(@pxref{Built-in Variables})
+provides access to the current user's real and effective user and group ID
+numbers, and if available, the user's supplementary group set.
+However, because these are numbers, they do not provide very useful
+information to the average user. There needs to be some way to find the
+user information associated with the user and group ID numbers. This
+@value{SECTION} presents a suite of functions for retrieving information from the
+user database. @xref{Group Functions},
+for a similar suite that retrieves information from the group database.
+
+@cindex @code{getpwent} function (C library)
+@cindex @code{getpwent} user-defined function
+@cindex users, information about, retrieving
+@cindex login information
+@cindex account information
+@cindex password file
+@cindex files, password
+The POSIX standard does not define the file where user information is
+kept. Instead, it provides the @code{<pwd.h>} header file
+and several C language subroutines for obtaining user information.
+The primary function is @code{getpwent}, for ``get password entry.''
+The ``password'' comes from the original user database file,
+@file{/etc/passwd}, which stores user information, along with the
+encrypted passwords (hence the name).
+
+@cindex @command{pwcat} program
+While an @command{awk} program could simply read @file{/etc/passwd}
+directly, this file may not contain complete information about the
+system's set of users.@footnote{It is often the case that password
+information is stored in a network database.} To be sure you are able to
+produce a readable and complete version of the user database, it is necessary
+to write a small C program that calls @code{getpwent}. @code{getpwent}
+is defined as returning a pointer to a @code{struct passwd}. Each time it
+is called, it returns the next entry in the database. When there are
+no more entries, it returns @code{NULL}, the null pointer. When this
+happens, the C program should call @code{endpwent} to close the database.
+Following is @command{pwcat}, a C program that ``cats'' the password database:
+
+@c Use old style function header for portability to old systems (SunOS, HP/UX).
+
+@example
+@c file eg/lib/pwcat.c
+/*
+ * pwcat.c
+ *
+ * Generate a printable version of the password database
+ */
+@c endfile
+@ignore
+@c file eg/lib/pwcat.c
+/*
+ * Arnold Robbins, arnold@@gnu.org, May 1993
+ * Public Domain
+ */
+
+#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(argc, argv)
+int argc;
+char **argv;
+@{
+ struct passwd *p;
+
+ while ((p = getpwent()) != NULL)
+ 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);
+
+ endpwent();
+ return 0;
+@}
+@c endfile
+@end example
+
+If you don't understand C, don't worry about it.
+The output from @command{pwcat} is the user database, in the traditional
+@file{/etc/passwd} format of colon-separated fields. The fields are:
+
+@ignore
+@table @asis
+@item Login name
+The user's login name.
+
+@item Encrypted password
+The user's encrypted password. This may not be available on some systems.
+
+@item User-ID
+The user's numeric user ID number.
+(On some systems it's a C @code{long}, and not an @code{int}. Thus
+we cast it to @code{long} for all cases.)
+
+@item Group-ID
+The user's numeric group ID number.
+(Similar comments about @code{long} vs.@: @code{int} apply here.)
+
+@item Full name
+The user's full name, and perhaps other information associated with the
+user.
+
+@item Home directory
+The user's login (or ``home'') directory (familiar to shell programmers as
+@code{$HOME}).
+
+@item Login shell
+The program that is run when the user logs in. This is usually a
+shell, such as @command{bash}.
+@end table
+@end ignore
+
+@multitable {Encrypted password} {1234567890123456789012345678901234567890123456}
+@item Login name @tab The user's login name.
+
+@item Encrypted password @tab The user's encrypted password. This may not be available on some systems.
+
+@item User-ID @tab The user's numeric user ID number.
+
+@item Group-ID @tab The user's numeric group ID number.
+
+@item Full name @tab The user's full name, and perhaps other information associated with the
+user.
+
+@item Home directory @tab The user's login (or ``home'') directory (familiar to shell programmers as
+@code{$HOME}).
+
+@item Login shell @tab The program that is run when the user logs in. This is usually a
+shell, such as @command{bash}.
+@end multitable
+
+A few lines representative of @command{pwcat}'s output are as follows:
+
+@cindex Jacobs, Andrew
+@cindex Robbins, Arnold
+@cindex Robbins, Miriam
+@example
+$ pwcat
+@print{} root:3Ov02d5VaUPB6:0:1:Operator:/:/bin/sh
+@print{} nobody:*:65534:65534::/:
+@print{} daemon:*:1:1::/:
+@print{} sys:*:2:2::/:/bin/csh
+@print{} bin:*:3:3::/bin:
+@print{} arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/sh
+@print{} miriam:yxaay:112:10:Miriam Robbins:/home/miriam:/bin/sh
+@print{} andy:abcca2:113:10:Andy Jacobs:/home/andy:/bin/sh
+@dots{}
+@end example
+
+With that introduction, following is a group of functions for getting user
+information. There are several functions here, corresponding to the C
+functions of the same names:
+
+@c Exercise: simplify all these functions that return values.
+@c Answer: return foo[key] returns "" if key not there, no need to check with `in'.
+
+@cindex @code{_pw_init} user-defined function
+@example
+@c file eg/lib/passwdawk.in
+# passwd.awk --- access password file information
+@c endfile
+@ignore
+@c file eg/lib/passwdawk.in
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+# Revised October 2000
+
+@c endfile
+@end ignore
+@c file eg/lib/passwdawk.in
+BEGIN @{
+ # tailor this to suit your system
+ _pw_awklib = "/usr/local/libexec/awk/"
+@}
+
+function _pw_init( oldfs, oldrs, olddol0, pwcat, using_fw)
+@{
+ if (_pw_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ FS = ":"
+ RS = "\n"
+
+ pwcat = _pw_awklib "pwcat"
+ while ((pwcat | getline) > 0) @{
+ _pw_byname[$1] = $0
+ _pw_byuid[$3] = $0
+ _pw_bycount[++_pw_total] = $0
+ @}
+ close(pwcat)
+ _pw_count = 0
+ _pw_inited = 1
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+@}
+@c endfile
+@end example
+
+@cindex @code{BEGIN} pattern, @code{pwcat} program
+The @code{BEGIN} rule sets a private variable to the directory where
+@command{pwcat} is stored. Because it is used to help out an @command{awk} library
+routine, we have chosen to put it in @file{/usr/local/libexec/awk};
+however, you might want it to be in a different directory on your system.
+
+The function @code{_pw_init} keeps three copies of the user information
+in three associative arrays. The arrays are indexed by username
+(@code{_pw_byname}), by user ID number (@code{_pw_byuid}), and by order of
+occurrence (@code{_pw_bycount}).
+The variable @code{_pw_inited} is used for efficiency; @code{_pw_init}
+needs only to be called once.
+
+@cindex @code{getline} command, @code{_pw_init} function
+Because this function uses @code{getline} to read information from
+@command{pwcat}, it first saves the values of @code{FS}, @code{RS}, and @code{$0}.
+It notes in the variable @code{using_fw} whether field splitting
+with @code{FIELDWIDTHS} is in effect or not.
+Doing so is necessary, since these functions could be called
+from anywhere within a user's program, and the user may have his
+or her
+own way of splitting records and fields.
+
+The @code{using_fw} variable checks @code{PROCINFO["FS"]}, which
+is @code{"FIELDWIDTHS"} if field splitting is being done with
+@code{FIELDWIDTHS}. This makes it possible to restore the correct
+field-splitting mechanism later. The test can only be true for
+@command{gawk}. It is false if using @code{FS} or on some other
+@command{awk} implementation.
+
+The main part of the function uses a loop to read database lines, split
+the line into fields, and then store the line into each array as necessary.
+When the loop is done, @code{@w{_pw_init}} cleans up by closing the pipeline,
+setting @code{@w{_pw_inited}} to one, and restoring @code{FS} (and @code{FIELDWIDTHS}
+if necessary), @code{RS}, and @code{$0}.
+The use of @code{@w{_pw_count}} is explained shortly.
+
+@c NEXT ED: All of these functions don't need the ... in ... test. Just
+@c return the array element, which will be "" if not already there. Duh.
+@cindex @code{getpwnam} function (C library)
+The @code{getpwnam} function takes a username as a string argument. If that
+user is in the database, it returns the appropriate line. Otherwise, it
+returns the null string:
+
+@cindex @code{getpwnam} user-defined function
+@example
+@group
+@c file eg/lib/passwdawk.in
+function getpwnam(name)
+@{
+ _pw_init()
+ if (name in _pw_byname)
+ return _pw_byname[name]
+ return ""
+@}
+@c endfile
+@end group
+@end example
+
+@cindex @code{getpwuid} function (C library)
+Similarly,
+the @code{getpwuid} function takes a user ID number argument. If that
+user number is in the database, it returns the appropriate line. Otherwise, it
+returns the null string:
+
+@cindex @code{getpwuid} user-defined function
+@example
+@c file eg/lib/passwdawk.in
+function getpwuid(uid)
+@{
+ _pw_init()
+ if (uid in _pw_byuid)
+ return _pw_byuid[uid]
+ return ""
+@}
+@c endfile
+@end example
+
+@cindex @code{getpwent} function (C library)
+The @code{getpwent} function simply steps through the database, one entry at
+a time. It uses @code{_pw_count} to track its current position in the
+@code{_pw_bycount} array:
+
+@cindex @code{getpwent} user-defined function
+@example
+@c file eg/lib/passwdawk.in
+function getpwent()
+@{
+ _pw_init()
+ if (_pw_count < _pw_total)
+ return _pw_bycount[++_pw_count]
+ return ""
+@}
+@c endfile
+@end example
+
+@cindex @code{endpwent} function (C library)
+The @code{@w{endpwent}} function resets @code{@w{_pw_count}} to zero, so that
+subsequent calls to @code{getpwent} start over again:
+
+@cindex @code{endpwent} user-defined function
+@example
+@c file eg/lib/passwdawk.in
+function endpwent()
+@{
+ _pw_count = 0
+@}
+@c endfile
+@end example
+
+A conscious design decision in this suite was made that each subroutine calls
+@code{@w{_pw_init}} to initialize the database arrays. The overhead of running
+a separate process to generate the user database, and the I/O to scan it,
+are only incurred if the user's main program actually calls one of these
+functions. If this library file is loaded along with a user's program, but
+none of the routines are ever called, then there is no extra runtime overhead.
+(The alternative is move the body of @code{@w{_pw_init}} into a
+@code{BEGIN} rule, which always runs @command{pwcat}. This simplifies the
+code but runs an extra process that may never be needed.)
+
+In turn, calling @code{_pw_init} is not too expensive, because the
+@code{_pw_inited} variable keeps the program from reading the data more than
+once. If you are worried about squeezing every last cycle out of your
+@command{awk} program, the check of @code{_pw_inited} could be moved out of
+@code{_pw_init} and duplicated in all the other functions. In practice,
+this is not necessary, since most @command{awk} programs are I/O-bound, and it
+clutters up the code.
+
+The @command{id} program in @ref{Id Program},
+uses these functions.
+@c ENDOFRANGE libfudata
+@c ENDOFRANGE flibudata
+@c ENDOFRANGE udatar
+@c ENDOFRANGE dataur
+
+@node Group Functions
+@section Reading the Group Database
+
+@c STARTOFRANGE libfgdata
+@cindex libraries of @command{awk} functions, group database, reading
+@c STARTOFRANGE flibgdata
+@cindex functions, library, group database, reading
+@c STARTOFRANGE gdatar
+@cindex group database, reading
+@c STARTOFRANGE datagr
+@cindex database, group, reading
+@cindex @code{PROCINFO} array
+@cindex @code{getgrent} function (C library)
+@cindex @code{getgrent} user-defined function
+@cindex groups@comma{} information about
+@cindex account information
+@cindex group file
+@cindex files, group
+Much of the discussion presented in
+@ref{Passwd Functions},
+applies to the group database as well. Although there has traditionally
+been a well-known file (@file{/etc/group}) in a well-known format, the POSIX
+standard only provides a set of C library routines
+(@code{<grp.h>} and @code{getgrent})
+for accessing the information.
+Even though this file may exist, it likely does not have
+complete information. Therefore, as with the user database, it is necessary
+to have a small C program that generates the group database as its output.
+
+@cindex @command{grcat} program
+@command{grcat}, a C program that ``cats'' the group database,
+is as follows:
+
+@example
+@c file eg/lib/grcat.c
+/*
+ * grcat.c
+ *
+ * Generate a printable version of the group database
+ */
+@c endfile
+@ignore
+@c file eg/lib/grcat.c
+/*
+ * Arnold Robbins, arnold@@gnu.org, May 1993
+ * Public Domain
+ */
+
+/* For OS/2, do nothing. */
+#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(argc, argv)
+int argc;
+char **argv;
+@{
+ struct group *g;
+ int i;
+
+ while ((g = getgrent()) != NULL) @{
+ printf("%s:%s:%ld:", g->gr_name, g->gr_passwd,
+ (long) g->gr_gid);
+ 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
+@end example
+@ignore
+@c file eg/lib/grcat.c
+#endif /* HAVE_GETGRENT */
+@c endfile
+@end ignore
+
+Each line in the group database represents one group. The fields are
+separated with colons and represent the following information:
+
+@ignore
+@table @asis
+@item Group Name
+The name of the group.
+
+@item Group Password
+The encrypted group password. In practice, this field is never used. It is
+usually empty or set to @samp{*}.
+
+@item Group ID Number
+The numeric group ID number. This number is unique within the file.
+(On some systems it's a C @code{long}, and not an @code{int}. Thus
+we cast it to @code{long} for all cases.)
+
+@item Group Member List
+A comma-separated list of usernames. These users are members of the group.
+Modern Unix systems allow users to be members of several groups
+simultaneously. If your system does, then there are elements
+@code{"group1"} through @code{"group@var{N}"} in @code{PROCINFO}
+for those group ID numbers.
+(Note that @code{PROCINFO} is a @command{gawk} extension;
+@pxref{Built-in Variables}.)
+@end table
+@end ignore
+
+@multitable {Encrypted password} {1234567890123456789012345678901234567890123456}
+@item Group name @tab The group's name.
+
+@item Group password @tab The group's encrypted password. In practice, this field is never used;
+it is usually empty or set to @samp{*}.
+
+@item Group-ID @tab
+The group's numeric group ID number; this number should be unique within the file.
+
+@item Group member list @tab
+A comma-separated list of usernames. These users are members of the group.
+Modern Unix systems allow users to be members of several groups
+simultaneously. If your system does, then there are elements
+@code{"group1"} through @code{"group@var{N}"} in @code{PROCINFO}
+for those group ID numbers.
+(Note that @code{PROCINFO} is a @command{gawk} extension;
+@pxref{Built-in Variables}.)
+@end multitable
+
+Here is what running @command{grcat} might produce:
+
+@example
+$ grcat
+@print{} wheel:*:0:arnold
+@print{} nogroup:*:65534:
+@print{} daemon:*:1:
+@print{} kmem:*:2:
+@print{} staff:*:10:arnold,miriam,andy
+@print{} other:*:20:
+@dots{}
+@end example
+
+Here are the functions for obtaining information from the group database.
+There are several, modeled after the C library functions of the same names:
+
+@cindex @code{getline} command, @code{_gr_init} user-defined function
+@cindex @code{_gr_init} user-defined function
+@example
+@c file eg/lib/groupawk.in
+# group.awk --- functions for dealing with the group file
+@c endfile
+@ignore
+@c file eg/lib/groupawk.in
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+# Revised October 2000
+
+@c endfile
+@end ignore
+@c line break on _gr_init for smallbook
+@c file eg/lib/groupawk.in
+BEGIN \
+@{
+ # Change to suit your system
+ _gr_awklib = "/usr/local/libexec/awk/"
+@}
+
+function _gr_init( oldfs, oldrs, olddol0, grcat,
+ using_fw, n, a, i)
+@{
+ if (_gr_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ 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_count] = $0
+ @}
+ close(grcat)
+ _gr_count = 0
+ _gr_inited++
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ RS = oldrs
+ $0 = olddol0
+@}
+@c endfile
+@end example
+
+The @code{BEGIN} rule sets a private variable to the directory where
+@command{grcat} is stored. Because it is used to help out an @command{awk} library
+routine, we have chosen to put it in @file{/usr/local/libexec/awk}. You might
+want it to be in a different directory on your system.
+
+These routines follow the same general outline as the user database routines
+(@pxref{Passwd Functions}).
+The @code{@w{_gr_inited}} variable is used to
+ensure that the database is scanned no more than once.
+The @code{@w{_gr_init}} function first saves @code{FS}, @code{FIELDWIDTHS}, @code{RS}, and
+@code{$0}, and then sets @code{FS} and @code{RS} to the correct values for
+scanning the group information.
+
+The group information is stored is several associative arrays.
+The arrays are indexed by group name (@code{@w{_gr_byname}}), by group ID number
+(@code{@w{_gr_bygid}}), and by position in the database (@code{@w{_gr_bycount}}).
+There is an additional array indexed by username (@code{@w{_gr_groupsbyuser}}),
+which is a space-separated list of groups to which each user belongs.
+
+Unlike the user database, it is possible to have multiple records in the
+database for the same group. This is common when a group has a large number
+of members. A pair of such entries might look like the following:
+
+@example
+tvpeople:*:101:johnny,jay,arsenio
+tvpeople:*:101:david,conan,tom,joan
+@end example
+
+For this reason, @code{_gr_init} looks to see if a group name or
+group ID number is already seen. If it is, then the usernames are
+simply concatenated onto the previous list of users. (There is actually a
+subtle problem with the code just presented. Suppose that
+the first time there were no names. This code adds the names with
+a leading comma. It also doesn't check that there is a @code{$4}.)
+
+Finally, @code{_gr_init} closes the pipeline to @command{grcat}, restores
+@code{FS} (and @code{FIELDWIDTHS} if necessary), @code{RS}, and @code{$0},
+initializes @code{_gr_count} to zero
+(it is used later), and makes @code{_gr_inited} nonzero.
+
+@cindex @code{getgrnam} function (C library)
+The @code{getgrnam} function takes a group name as its argument, and if that
+group exists, it is returned. Otherwise, @code{getgrnam} returns the null
+string:
+
+@cindex @code{getgrnam} user-defined function
+@example
+@c file eg/lib/groupawk.in
+function getgrnam(group)
+@{
+ _gr_init()
+ if (group in _gr_byname)
+ return _gr_byname[group]
+ return ""
+@}
+@c endfile
+@end example
+
+@cindex @code{getgrgid} function (C library)
+The @code{getgrgid} function is similar, it takes a numeric group ID and
+looks up the information associated with that group ID:
+
+@cindex @code{getgrgid} user-defined function
+@example
+@c file eg/lib/groupawk.in
+function getgrgid(gid)
+@{
+ _gr_init()
+ if (gid in _gr_bygid)
+ return _gr_bygid[gid]
+ return ""
+@}
+@c endfile
+@end example
+
+@cindex @code{getgruser} function (C library)
+The @code{getgruser} function does not have a C counterpart. It takes a
+username and returns the list of groups that have the user as a member:
+
+@cindex @code{getgruser} function, user-defined
+@example
+@c file eg/lib/groupawk.in
+function getgruser(user)
+@{
+ _gr_init()
+ if (user in _gr_groupsbyuser)
+ return _gr_groupsbyuser[user]
+ return ""
+@}
+@c endfile
+@end example
+
+@cindex @code{getgrent} function (C library)
+The @code{getgrent} function steps through the database one entry at a time.
+It uses @code{_gr_count} to track its position in the list:
+
+@cindex @code{getgrent} user-defined function
+@example
+@c file eg/lib/groupawk.in
+function getgrent()
+@{
+ _gr_init()
+ if (++_gr_count in _gr_bycount)
+ return _gr_bycount[_gr_count]
+ return ""
+@}
+@c endfile
+@end example
+@c ENDOFRANGE clibf
+
+@cindex @code{endgrent} function (C library)
+The @code{endgrent} function resets @code{_gr_count} to zero so that @code{getgrent} can
+start over again:
+
+@cindex @code{endgrent} user-defined function
+@example
+@c file eg/lib/groupawk.in
+function endgrent()
+@{
+ _gr_count = 0
+@}
+@c endfile
+@end example
+
+As with the user database routines, each function calls @code{_gr_init} to
+initialize the arrays. Doing so only incurs the extra overhead of running
+@command{grcat} if these functions are used (as opposed to moving the body of
+@code{_gr_init} into a @code{BEGIN} rule).
+
+Most of the work is in scanning the database and building the various
+associative arrays. The functions that the user calls are themselves very
+simple, relying on @command{awk}'s associative arrays to do work.
+
+The @command{id} program in @ref{Id Program},
+uses these functions.
+@c ENDOFRANGE libfgdata
+@c ENDOFRANGE flibgdata
+@c ENDOFRANGE gdatar
+@c ENDOFRANGE libf
+@c ENDOFRANGE flib
+@c ENDOFRANGE fudlib
+@c ENDOFRANGE datagr
+
+@node Sample Programs
+@chapter Practical @command{awk} Programs
+@c STARTOFRANGE awkpex
+@cindex @command{awk} programs, examples of
+
+@ref{Library Functions},
+presents the idea that reading programs in a language contributes to
+learning that language. This @value{CHAPTER} continues that theme,
+presenting a potpourri of @command{awk} programs for your reading
+enjoyment.
+@ifnotinfo
+There are three sections.
+The first describes how to run the programs presented
+in this @value{CHAPTER}.
+
+The second presents @command{awk}
+versions of several common POSIX utilities.
+These are programs that you are hopefully already familiar with,
+and therefore, whose problems are understood.
+By reimplementing these programs in @command{awk},
+you can focus on the @command{awk}-related aspects of solving
+the programming problem.
+
+The third is a grab bag of interesting programs.
+These solve a number of different data-manipulation and management
+problems. Many of the programs are short, which emphasizes @command{awk}'s
+ability to do a lot in just a few lines of code.
+@end ifnotinfo
+
+Many of these programs use the library functions presented in
+@ref{Library Functions}.
+
+@menu
+* Running Examples:: How to run these examples.
+* Clones:: Clones of common utilities.
+* Miscellaneous Programs:: Some interesting @command{awk} programs.
+@end menu
+
+@node Running Examples
+@section Running the Example Programs
+
+To run a given program, you would typically do something like this:
+
+@example
+awk -f @var{program} -- @var{options} @var{files}
+@end example
+
+@noindent
+Here, @var{program} is the name of the @command{awk} program (such as
+@file{cut.awk}), @var{options} are any command-line options for the
+program that start with a @samp{-}, and @var{files} are the actual @value{DF}s.
+
+If your system supports the @samp{#!} executable interpreter mechanism
+(@pxref{Executable Scripts}),
+you can instead run your program directly:
+
+@example
+cut.awk -c1-8 myfiles > results
+@end example
+
+If your @command{awk} is not @command{gawk}, you may instead need to use this:
+
+@example
+cut.awk -- -c1-8 myfiles > results
+@end example
+
+@node Clones
+@section Reinventing Wheels for Fun and Profit
+@c STARTOFRANGE posimawk
+@cindex POSIX, programs@comma{} implementing in @command{awk}
+
+This @value{SECTION} presents a number of POSIX utilities that are implemented in
+@command{awk}. Reinventing these programs in @command{awk} is often enjoyable,
+because the algorithms can be very clearly expressed, and the code is usually
+very concise and simple. This is true because @command{awk} does so much for you.
+
+It should be noted that these programs are not necessarily intended to
+replace the installed versions on your system. Instead, their
+purpose is to illustrate @command{awk} language programming for ``real world''
+tasks.
+
+The programs are presented in alphabetical order.
+
+@menu
+* Cut Program:: The @command{cut} utility.
+* Egrep Program:: The @command{egrep} utility.
+* Id Program:: The @command{id} utility.
+* Split Program:: The @command{split} utility.
+* Tee Program:: The @command{tee} utility.
+* Uniq Program:: The @command{uniq} utility.
+* Wc Program:: The @command{wc} utility.
+@end menu
+
+@node Cut Program
+@subsection Cutting out Fields and Columns
+
+@cindex @command{cut} utility
+@c STARTOFRANGE cut
+@cindex @command{cut} utility
+@c STARTOFRANGE ficut
+@cindex fields, cutting
+@c STARTOFRANGE colcut
+@cindex columns, cutting
+The @command{cut} utility selects, or ``cuts,'' characters or fields
+from its standard input and sends them to its standard output.
+Fields are separated by tabs by default,
+but you may supply a command-line option to change the field
+@dfn{delimiter} (i.e., the field-separator character). @command{cut}'s
+definition of fields is less general than @command{awk}'s.
+
+A common use of @command{cut} might be to pull out just the login name of
+logged-on users from the output of @command{who}. For example, the following
+pipeline generates a sorted, unique list of the logged-on users:
+
+@example
+who | cut -c1-8 | sort | uniq
+@end example
+
+The options for @command{cut} are:
+
+@table @code
+@item -c @var{list}
+Use @var{list} as the list of characters to cut out. Items within the list
+may be separated by commas, and ranges of characters can be separated with
+dashes. The list @samp{1-8,15,22-35} specifies characters 1 through
+8, 15, and 22 through 35.
+
+@item -f @var{list}
+Use @var{list} as the list of fields to cut out.
+
+@item -d @var{delim}
+Use @var{delim} as the field-separator character instead of the tab
+character.
+
+@item -s
+Suppress printing of lines that do not contain the field delimiter.
+@end table
+
+The @command{awk} implementation of @command{cut} uses the @code{getopt} library
+function (@pxref{Getopt Function})
+and the @code{join} library function
+(@pxref{Join Function}).
+
+The program begins with a comment describing the options, the library
+functions needed, and a @code{usage} function that prints out a usage
+message and exits. @code{usage} is called if invalid arguments are
+supplied:
+
+@cindex @code{cut.awk} program
+@example
+@c file eg/prog/cut.awk
+# cut.awk --- implement cut in awk
+@c endfile
+@ignore
+@c file eg/prog/cut.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/cut.awk
+# Options:
+# -f list Cut fields
+# -d c Field delimiter character
+# -c list Cut characters
+#
+# -s Suppress lines without the delimiter
+#
+# Requires getopt and join library functions
+
+@group
+function usage( e1, e2)
+@{
+ e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
+ e2 = "usage: cut [-c list] [files...]"
+ print e1 > "/dev/stderr"
+ print e2 > "/dev/stderr"
+ exit 1
+@}
+@end group
+@c endfile
+@end example
+
+@noindent
+The variables @code{e1} and @code{e2} are used so that the function
+fits nicely on the
+@ifnotinfo
+page.
+@end ifnotinfo
+@ifnottex
+screen.
+@end ifnottex
+
+@cindex @code{BEGIN} pattern, running @command{awk} programs and
+@cindex @code{FS} variable, running @command{awk} programs and
+Next comes a @code{BEGIN} rule that parses the command-line options.
+It sets @code{FS} to a single TAB character, because that is @command{cut}'s
+default field separator. The output field separator is also set to be the
+same as the input field separator. Then @code{getopt} is used to step
+through the command-line options. Exactly one of the variables
+@code{by_fields} or @code{by_chars} is set to true, to indicate that
+processing should be done by fields or by characters, respectively.
+When cutting by characters, the output field separator is set to the null
+string:
+
+@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") @{
+ by_fields = 1
+ fieldlist = Optarg
+ @} else if (c == "c") @{
+ by_chars = 1
+ fieldlist = Optarg
+ OFS = ""
+ @} else if (c == "d") @{
+ if (length(Optarg) > 1) @{
+ printf("Using first character of %s" \
+ " for delimiter\n", Optarg) > "/dev/stderr"
+ Optarg = substr(Optarg, 1, 1)
+ @}
+ FS = Optarg
+ OFS = FS
+ if (FS == " ") # defeat awk semantics
+ FS = "[ ]"
+ @} else if (c == "s")
+ suppress++
+ else
+ usage()
+ @}
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+@c endfile
+@end example
+
+@cindex field separators, spaces as
+Special care is taken when the field delimiter is a space. Using
+a single space (@code{@w{" "}}) for the value of @code{FS} is
+incorrect---@command{awk} would separate fields with runs of spaces,
+tabs, and/or newlines, and we want them to be separated with individual
+spaces. Also, note that after @code{getopt} is through, we have to
+clear out all the elements of @code{ARGV} from 1 to @code{Optind},
+so that @command{awk} does not try to process the command-line options
+as @value{FN}s.
+
+After dealing with the command-line options, the program verifies that the
+options make sense. Only one or the other of @option{-c} and @option{-f}
+should be used, and both require a field list. Then the program calls
+either @code{set_fieldlist} or @code{set_charlist} to pull apart the
+list of fields or characters:
+
+@example
+@c file eg/prog/cut.awk
+ if (by_fields && by_chars)
+ usage()
+
+ if (by_fields == 0 && by_chars == 0)
+ by_fields = 1 # default
+
+ if (fieldlist == "") @{
+ print "cut: needs list for -c or -f" > "/dev/stderr"
+ exit 1
+ @}
+
+ if (by_fields)
+ set_fieldlist()
+ else
+ set_charlist()
+@}
+@c endfile
+@end example
+
+@code{set_fieldlist} is used to split the field list apart at the commas
+and into an array. Then, for each element of the array, it looks to
+see if it is actually a range, and if so, splits it apart. The range
+is verified to make sure the first number is smaller than the second.
+Each number in the list is added to the @code{flist} array, which
+simply lists the fields that will be printed. Normal field splitting
+is used. The program lets @command{awk} handle the job of doing the
+field splitting:
+
+@example
+@c file eg/prog/cut.awk
+function set_fieldlist( n, m, i, j, k, f, g)
+@{
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) @{
+ if (index(f[i], "-") != 0) @{ # a range
+ m = split(f[i], g, "-")
+@group
+ if (m != 2 || g[1] >= g[2]) @{
+ printf("bad field list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ @}
+@end group
+ for (k = g[1]; k <= g[2]; k++)
+ flist[j++] = k
+ @} else
+ flist[j++] = f[i]
+ @}
+ nfields = j - 1
+@}
+@c endfile
+@end example
+
+The @code{set_charlist} function is more complicated than @code{set_fieldlist}.
+The idea here is to use @command{gawk}'s @code{FIELDWIDTHS} variable
+(@pxref{Constant Size}),
+which describes constant-width input. When using a character list, that is
+exactly what we have.
+
+Setting up @code{FIELDWIDTHS} is more complicated than simply listing the
+fields that need to be printed. We have to keep track of the fields to
+print and also the intervening characters that have to be skipped.
+For example, suppose you wanted characters 1 through 8, 15, and
+22 through 35. You would use @samp{-c 1-8,15,22-35}. The necessary value
+for @code{FIELDWIDTHS} is @code{@w{"8 6 1 6 14"}}. This yields five
+fields, and the fields to print
+are @code{$1}, @code{$3}, and @code{$5}.
+The intermediate fields are @dfn{filler},
+which is stuff in between the desired data.
+@code{flist} lists the fields to print, and @code{t} tracks the
+complete field list, including filler fields:
+
+@example
+@c file eg/prog/cut.awk
+function set_charlist( field, i, j, f, g, t,
+ filler, last, len)
+@{
+ field = 1 # count total fields
+ n = split(fieldlist, f, ",")
+ j = 1 # index in flist
+ for (i = 1; i <= n; i++) @{
+ if (index(f[i], "-") != 0) @{ # range
+ m = split(f[i], g, "-")
+ if (m != 2 || g[1] >= g[2]) @{
+ printf("bad character list: %s\n",
+ f[i]) > "/dev/stderr"
+ exit 1
+ @}
+ len = g[2] - g[1] + 1
+ if (g[1] > 1) # compute length of filler
+ filler = g[1] - last - 1
+ else
+ filler = 0
+@group
+ if (filler)
+ t[field++] = filler
+@end group
+ t[field++] = len # length of field
+ last = g[2]
+ flist[j++] = field - 1
+ @} else @{
+ if (f[i] > 1)
+ filler = f[i] - last - 1
+ else
+ filler = 0
+ if (filler)
+ t[field++] = filler
+ t[field++] = 1
+ last = f[i]
+ flist[j++] = field - 1
+ @}
+ @}
+ FIELDWIDTHS = join(t, 1, field - 1)
+ nfields = j - 1
+@}
+@c endfile
+@end example
+
+Next is the rule that actually processes the data. If the @option{-s} option
+is given, then @code{suppress} is true. The first @code{if} statement
+makes sure that the input record does have the field separator. If
+@command{cut} is processing fields, @code{suppress} is true, and the field
+separator character is not in the record, then the record is skipped.
+
+If the record is valid, then @command{gawk} has split the data
+into fields, either using the character in @code{FS} or using fixed-length
+fields and @code{FIELDWIDTHS}. The loop goes through the list of fields
+that should be printed. The corresponding field is printed if it contains data.
+If the next field also has data, then the separator character is
+written out between the fields:
+
+@example
+@c file eg/prog/cut.awk
+@{
+ if (by_fields && suppress && index($0, FS) != 0)
+ next
+
+ for (i = 1; i <= nfields; i++) @{
+ if ($flist[i] != "") @{
+ printf "%s", $flist[i]
+ if (i < nfields && $flist[i+1] != "")
+ printf "%s", OFS
+ @}
+ @}
+ print ""
+@}
+@c endfile
+@end example
+
+This version of @command{cut} relies on @command{gawk}'s @code{FIELDWIDTHS}
+variable to do the character-based cutting. While it is possible in
+other @command{awk} implementations to use @code{substr}
+(@pxref{String Functions}),
+it is also extremely painful.
+The @code{FIELDWIDTHS} variable supplies an elegant solution to the problem
+of picking the input line apart by characters.
+@c ENDOFRANGE cut
+@c ENDOFRANGE ficut
+@c ENDOFRANGE colcut
+
+@c Exercise: Rewrite using split with "".
+
+@node Egrep Program
+@subsection Searching for Regular Expressions in Files
+
+@c STARTOFRANGE regexps
+@cindex regular expressions, searching for
+@c STARTOFRANGE sfregexp
+@cindex searching, files for regular expressions
+@c STARTOFRANGE fsregexp
+@cindex files, searching for regular expressions
+@cindex @command{egrep} utility
+The @command{egrep} utility searches files for patterns. It uses regular
+expressions that are almost identical to those available in @command{awk}
+(@pxref{Regexp}).
+It is used in the following manner:
+
+@example
+egrep @r{[} @var{options} @r{]} '@var{pattern}' @var{files} @dots{}
+@end example
+
+The @var{pattern} is a regular expression. In typical usage, the regular
+expression is quoted to prevent the shell from expanding any of the
+special characters as @value{FN} wildcards. Normally, @command{egrep}
+prints the lines that matched. If multiple @value{FN}s are provided on
+the command line, each output line is preceded by the name of the file
+and a colon.
+
+The options to @command{egrep} are as follows:
+
+@table @code
+@item -c
+Print out a count of the lines that matched the pattern, instead of the
+lines themselves.
+
+@item -s
+Be silent. No output is produced and the exit value indicates whether
+the pattern was matched.
+
+@item -v
+Invert the sense of the test. @command{egrep} prints the lines that do
+@emph{not} match the pattern and exits successfully if the pattern is not
+matched.
+
+@item -i
+Ignore case distinctions in both the pattern and the input data.
+
+@item -l
+Only print (list) the names of the files that matched, not the lines that matched.
+
+@item -e @var{pattern}
+Use @var{pattern} as the regexp to match. The purpose of the @option{-e}
+option is to allow patterns that start with a @samp{-}.
+@end table
+
+This version uses the @code{getopt} library function
+(@pxref{Getopt Function})
+and the file transition library program
+(@pxref{Filetrans Function}).
+
+The program begins with a descriptive comment and then a @code{BEGIN} rule
+that processes the command-line arguments with @code{getopt}. The @option{-i}
+(ignore case) option is particularly easy with @command{gawk}; we just use the
+@code{IGNORECASE} built-in variable
+(@pxref{Built-in Variables}):
+
+@cindex @code{egrep.awk} program
+@example
+@c file eg/prog/egrep.awk
+# egrep.awk --- simulate egrep in awk
+@c endfile
+@ignore
+@c file eg/prog/egrep.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/egrep.awk
+# Options:
+# -c count of lines
+# -s silent - use exit value
+# -v invert test, success if no match
+# -i ignore case
+# -l print filenames only
+# -e argument is pattern
+#
+# Requires getopt and file transition library functions
+
+BEGIN @{
+ while ((c = getopt(ARGC, ARGV, "ce:svil")) != -1) @{
+ if (c == "c")
+ count_only++
+ else if (c == "s")
+ no_print++
+ else if (c == "v")
+ invert++
+ else if (c == "i")
+ IGNORECASE = 1
+ else if (c == "l")
+ filenames_only++
+ else if (c == "e")
+ pattern = Optarg
+ else
+ usage()
+ @}
+@c endfile
+@end example
+
+Next comes the code that handles the @command{egrep}-specific behavior. If no
+pattern is supplied with @option{-e}, the first nonoption on the
+command line is used. The @command{awk} command-line arguments up to @code{ARGV[Optind]}
+are cleared, so that @command{awk} won't try to process them as files. If no
+files are specified, the standard input is used, and if multiple files are
+specified, we make sure to note this so that the @value{FN}s can precede the
+matched lines in the output:
+
+@example
+@c file eg/prog/egrep.awk
+ if (pattern == "")
+ pattern = ARGV[Optind++]
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+ if (Optind >= ARGC) @{
+ ARGV[1] = "-"
+ ARGC = 2
+ @} else if (ARGC - Optind > 1)
+ do_filenames++
+
+# if (IGNORECASE)
+# pattern = tolower(pattern)
+@}
+@c endfile
+@end example
+
+The last two lines are commented out, since they are not needed in
+@command{gawk}. They should be uncommented if you have to use another version
+of @command{awk}.
+
+The next set of lines should be uncommented if you are not using
+@command{gawk}. This rule translates all the characters in the input line
+into lowercase if the @option{-i} option is specified.@footnote{It
+also introduces a subtle bug;
+if a match happens, we output the translated line, not the original.}
+The rule is
+commented out since it is not necessary with @command{gawk}:
+
+@c Exercise: Fix this, w/array and new line as key to original line
+
+@example
+@c file eg/prog/egrep.awk
+#@{
+# if (IGNORECASE)
+# $0 = tolower($0)
+#@}
+@c endfile
+@end example
+
+The @code{beginfile} function is called by the rule in @file{ftrans.awk}
+when each new file is processed. In this case, it is very simple; all it
+does is initialize a variable @code{fcount} to zero. @code{fcount} tracks
+how many lines in the current file matched the pattern
+(naming the parameter @code{junk} shows we know that @code{beginfile}
+is called with a parameter, but that we're not interested in its value):
+
+@example
+@c file eg/prog/egrep.awk
+function beginfile(junk)
+@{
+ fcount = 0
+@}
+@c endfile
+@end example
+
+The @code{endfile} function is called after each file has been processed.
+It affects the output only when the user wants a count of the number of lines that
+matched. @code{no_print} is true only if the exit status is desired.
+@code{count_only} is true if line counts are desired. @command{egrep}
+therefore only prints line counts if printing and counting are enabled.
+The output format must be adjusted depending upon the number of files to
+process. Finally, @code{fcount} is added to @code{total}, so that we
+know the total number of lines that matched the pattern:
+
+@example
+@c file eg/prog/egrep.awk
+function endfile(file)
+@{
+ if (! no_print && count_only)
+ if (do_filenames)
+ print file ":" fcount
+ else
+ print fcount
+
+ total += fcount
+@}
+@c endfile
+@end example
+
+The following rule does most of the work of matching lines. The variable
+@code{matches} is true if the line matched the pattern. If the user
+wants lines that did not match, the sense of @code{matches} is inverted
+using the @samp{!} operator. @code{fcount} is incremented with the value of
+@code{matches}, which is either one or zero, depending upon a
+successful or unsuccessful match. If the line does not match, the
+@code{next} statement just moves on to the next record.
+
+@cindex @code{!} (exclamation point), @code{!} operator
+@cindex exclamation point (@code{!}), @code{!} operator
+A number of additional tests are made, but they are only done if we
+are not counting lines. First, if the user only wants exit status
+(@code{no_print} is true), then it is enough to know that @emph{one}
+line in this file matched, and we can skip on to the next file with
+@code{nextfile}. Similarly, if we are only printing @value{FN}s, we can
+print the @value{FN}, and then skip to the next file with @code{nextfile}.
+Finally, each line is printed, with a leading @value{FN} and colon
+if necessary:
+
+@cindex @code{!} operator
+@example
+@c file eg/prog/egrep.awk
+@{
+ matches = ($0 ~ pattern)
+ if (invert)
+ matches = ! matches
+
+ fcount += matches # 1 or 0
+
+ if (! matches)
+ next
+
+ if (! count_only) @{
+ if (no_print)
+ nextfile
+
+ if (filenames_only) @{
+ print FILENAME
+ nextfile
+ @}
+
+ if (do_filenames)
+ print FILENAME ":" $0
+ else
+ print
+ @}
+@}
+@c endfile
+@end example
+
+The @code{END} rule takes care of producing the correct exit status. If
+there are no matches, the exit status is one; otherwise it is zero:
+
+@example
+@c file eg/prog/egrep.awk
+END \
+@{
+ if (total == 0)
+ exit 1
+ exit 0
+@}
+@c endfile
+@end example
+
+The @code{usage} function prints a usage message in case of invalid options,
+and then exits:
+
+@example
+@c file eg/prog/egrep.awk
+function usage( e)
+@{
+ e = "Usage: egrep [-csvil] [-e pat] [files ...]"
+ e = e "\n\tegrep [-csvil] pat [files ...]"
+ print e > "/dev/stderr"
+ exit 1
+@}
+@c endfile
+@end example
+
+The variable @code{e} is used so that the function fits nicely
+on the printed page.
+
+@cindex @code{END} pattern, backslash continuation and
+@cindex @code{\} (backslash), continuing lines and
+@cindex backslash (@code{\}), continuing lines and
+Just a note on programming style: you may have noticed that the @code{END}
+rule uses backslash continuation, with the open brace on a line by
+itself. This is so that it more closely resembles the way functions
+are written. Many of the examples
+in this @value{CHAPTER}
+use this style. You can decide for yourself if you like writing
+your @code{BEGIN} and @code{END} rules this way
+or not.
+@c ENDOFRANGE regexps
+@c ENDOFRANGE sfregexp
+@c ENDOFRANGE fsregexp
+
+@node Id Program
+@subsection Printing out User Information
+
+@cindex printing, user information
+@cindex users, information about, printing
+@cindex @command{id} utility
+The @command{id} utility lists a user's real and effective user ID numbers,
+real and effective group ID numbers, and the user's group set, if any.
+@command{id} only prints the effective user ID and group ID if they are
+different from the real ones. If possible, @command{id} also supplies the
+corresponding user and group names. The output might look like this:
+
+@example
+$ id
+@print{} uid=2076(arnold) gid=10(staff) groups=10(staff),4(tty)
+@end example
+
+This information is part of what is provided by @command{gawk}'s
+@code{PROCINFO} array (@pxref{Built-in Variables}).
+However, the @command{id} utility provides a more palatable output than just
+individual numbers.
+
+Here is a simple version of @command{id} written in @command{awk}.
+It uses the user database library functions
+(@pxref{Passwd Functions})
+and the group database library functions
+(@pxref{Group Functions}):
+
+The program is fairly straightforward. All the work is done in the
+@code{BEGIN} rule. The user and group ID numbers are obtained from
+@code{PROCINFO}.
+The code is repetitive. The entry in the user database for the real user ID
+number is split into parts at the @samp{:}. The name is the first field.
+Similar code is used for the effective user ID number and the group
+numbers:
+
+@cindex @code{id.awk} program
+@example
+@c file eg/prog/id.awk
+# id.awk --- implement id in awk
+#
+# Requires user and group library functions
+@c endfile
+@ignore
+@c file eg/prog/id.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+# Revised February 1996
+
+@c endfile
+@end ignore
+@c file eg/prog/id.awk
+# output is:
+# uid=12(foo) euid=34(bar) gid=3(baz) \
+# egid=5(blat) groups=9(nine),2(two),1(one)
+
+@group
+BEGIN \
+@{
+ uid = PROCINFO["uid"]
+ euid = PROCINFO["euid"]
+ gid = PROCINFO["gid"]
+ egid = PROCINFO["egid"]
+@end group
+
+ printf("uid=%d", uid)
+ pw = getpwuid(uid)
+ if (pw != "") @{
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ @}
+
+ if (euid != uid) @{
+ printf(" euid=%d", euid)
+ pw = getpwuid(euid)
+ if (pw != "") @{
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ @}
+ @}
+
+ printf(" gid=%d", gid)
+ pw = getgrgid(gid)
+ if (pw != "") @{
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ @}
+
+ if (egid != gid) @{
+ printf(" egid=%d", egid)
+ pw = getgrgid(egid)
+ if (pw != "") @{
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ @}
+ @}
+
+ for (i = 1; ("group" i) in PROCINFO; i++) @{
+ if (i == 1)
+ printf(" groups=")
+ group = PROCINFO["group" i]
+ printf("%d", group)
+ pw = getgrgid(group)
+ if (pw != "") @{
+ split(pw, a, ":")
+ printf("(%s)", a[1])
+ @}
+ if (("group" (i+1)) in PROCINFO)
+ printf(",")
+ @}
+
+ print ""
+@}
+@c endfile
+@end example
+
+@cindex @code{in} operator
+The test in the @code{for} loop is worth noting.
+Any supplementary groups in the @code{PROCINFO} array have the
+indices @code{"group1"} through @code{"group@var{N}"} for some
+@var{N}, i.e., the total number of supplementary groups.
+However, we don't know in advance how many of these groups
+there are.
+
+This loop works by starting at one, concatenating the value with
+@code{"group"}, and then using @code{in} to see if that value is
+in the array. Eventually, @code{i} is incremented past
+the last group in the array and the loop exits.
+
+The loop is also correct if there are @emph{no} supplementary
+groups; then the condition is false the first time it's
+tested, and the loop body never executes.
+
+@c exercise!!!
+@ignore
+The POSIX version of @command{id} takes arguments that control which
+information is printed. Modify this version to accept the same
+arguments and perform in the same way.
+@end ignore
+
+@node Split Program
+@subsection Splitting a Large File into Pieces
+
+@c STARTOFRANGE filspl
+@cindex files, splitting
+@cindex @code{split} utility
+The @code{split} program splits large text files into smaller pieces.
+Usage is as follows:
+
+@example
+split @r{[}-@var{count}@r{]} file @r{[} @var{prefix} @r{]}
+@end example
+
+By default,
+the output files are named @file{xaa}, @file{xab}, and so on. Each file has
+1000 lines in it, with the likely exception of the last file. To change the
+number of lines in each file, supply a number on the command line
+preceded with a minus; e.g., @samp{-500} for files with 500 lines in them
+instead of 1000. To change the name of the output files to something like
+@file{myfileaa}, @file{myfileab}, and so on, supply an additional
+argument that specifies the @value{FN} prefix.
+
+Here is a version of @code{split} in @command{awk}. It uses the @code{ord} and
+@code{chr} functions presented in
+@ref{Ordinal Functions}.
+
+The program first sets its defaults, and then tests to make sure there are
+not too many arguments. It then looks at each argument in turn. The
+first argument could be a minus sign followed by a number. If it is, this happens
+to look like a negative number, so it is made positive, and that is the
+count of lines. The data @value{FN} is skipped over and the final argument
+is used as the prefix for the output @value{FN}s:
+
+@cindex @code{split.awk} program
+@example
+@c file eg/prog/split.awk
+# split.awk --- do split in awk
+#
+# Requires ord and chr library functions
+@c endfile
+@ignore
+@c file eg/prog/split.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/split.awk
+# usage: split [-num] [file] [outname]
+
+BEGIN @{
+ outfile = "x" # default
+ count = 1000
+ if (ARGC > 4)
+ usage()
+
+ i = 1
+ if (ARGV[i] ~ /^-[0-9]+$/) @{
+ count = -ARGV[i]
+ ARGV[i] = ""
+ i++
+ @}
+ # test argv in case reading from stdin instead of file
+ if (i in ARGV)
+ i++ # skip data file name
+ if (i in ARGV) @{
+ outfile = ARGV[i]
+ ARGV[i] = ""
+ @}
+
+ s1 = s2 = "a"
+ out = (outfile s1 s2)
+@}
+@c endfile
+@end example
+
+The next rule does most of the work. @code{tcount} (temporary count) tracks
+how many lines have been printed to the output file so far. If it is greater
+than @code{count}, it is time to close the current file and start a new one.
+@code{s1} and @code{s2} track the current suffixes for the @value{FN}. If
+they are both @samp{z}, the file is just too big. Otherwise, @code{s1}
+moves to the next letter in the alphabet and @code{s2} starts over again at
+@samp{a}:
+
+@c else on separate line here for page breaking
+@example
+@c file eg/prog/split.awk
+@{
+ if (++tcount > count) @{
+ close(out)
+ if (s2 == "z") @{
+ if (s1 == "z") @{
+ printf("split: %s is too large to split\n",
+ FILENAME) > "/dev/stderr"
+ exit 1
+ @}
+ s1 = chr(ord(s1) + 1)
+ s2 = "a"
+ @}
+@group
+ else
+ s2 = chr(ord(s2) + 1)
+@end group
+ out = (outfile s1 s2)
+ tcount = 1
+ @}
+ print > out
+@}
+@c endfile
+@end example
+
+@c Exercise: do this with just awk builtin functions, index("abc..."), substr, etc.
+
+@noindent
+The @code{usage} function simply prints an error message and exits:
+
+@example
+@c file eg/prog/split.awk
+function usage( e)
+@{
+ e = "usage: split [-num] [file] [outname]"
+ print e > "/dev/stderr"
+ exit 1
+@}
+@c endfile
+@end example
+
+@noindent
+The variable @code{e} is used so that the function
+fits nicely on the
+@ifinfo
+screen.
+@end ifinfo
+@ifnotinfo
+page.
+@end ifnotinfo
+
+This program is a bit sloppy; it relies on @command{awk} to automatically close the last file
+instead of doing it in an @code{END} rule.
+It also assumes that letters are contiguous in the character set,
+which isn't true for EBCDIC systems.
+@c BFD...
+@c ENDOFRANGE filspl
+
+@node Tee Program
+@subsection Duplicating Output into Multiple Files
+
+@cindex files, multiple@comma{} duplicating output into
+@cindex output, duplicating into files
+@cindex @code{tee} utility
+The @code{tee} program is known as a ``pipe fitting.'' @code{tee} copies
+its standard input to its standard output and also duplicates it to the
+files named on the command line. Its usage is as follows:
+
+@example
+tee @r{[}-a@r{]} file @dots{}
+@end example
+
+The @option{-a} option tells @code{tee} to append to the named files, instead of
+truncating them and starting over.
+
+The @code{BEGIN} rule first makes a copy of all the command-line arguments
+into an array named @code{copy}.
+@code{ARGV[0]} is not copied, since it is not needed.
+@code{tee} cannot use @code{ARGV} directly, since @command{awk} attempts to
+process each @value{FN} in @code{ARGV} as input data.
+
+@cindex flag variables
+If the first argument is @option{-a}, then the flag variable
+@code{append} is set to true, and both @code{ARGV[1]} and
+@code{copy[1]} are deleted. If @code{ARGC} is less than two, then no
+@value{FN}s were supplied and @code{tee} prints a usage message and exits.
+Finally, @command{awk} is forced to read the standard input by setting
+@code{ARGV[1]} to @code{"-"} and @code{ARGC} to two:
+
+@c NEXT ED: Add more leading commentary in this program
+@cindex @code{tee.awk} program
+@example
+@c file eg/prog/tee.awk
+# tee.awk --- tee in awk
+@c endfile
+@ignore
+@c file eg/prog/tee.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+# Revised December 1995
+
+@c endfile
+@end ignore
+@c file eg/prog/tee.awk
+BEGIN \
+@{
+ for (i = 1; i < ARGC; i++)
+ copy[i] = ARGV[i]
+
+ if (ARGV[1] == "-a") @{
+ append = 1
+ delete ARGV[1]
+ delete copy[1]
+ ARGC--
+ @}
+ if (ARGC < 2) @{
+ print "usage: tee [-a] file ..." > "/dev/stderr"
+ exit 1
+ @}
+ ARGV[1] = "-"
+ ARGC = 2
+@}
+@c endfile
+@end example
+
+The single rule does all the work. Since there is no pattern, it is
+executed for each line of input. The body of the rule simply prints the
+line into each file on the command line, and then to the standard output:
+
+@example
+@c file eg/prog/tee.awk
+@{
+ # moving the if outside the loop makes it run faster
+ if (append)
+ for (i in copy)
+ print >> copy[i]
+ else
+ for (i in copy)
+ print > copy[i]
+ print
+@}
+@c endfile
+@end example
+
+@noindent
+It is also possible to write the loop this way:
+
+@example
+for (i in copy)
+ if (append)
+ print >> copy[i]
+ else
+ print > copy[i]
+@end example
+
+@noindent
+This is more concise but it is also less efficient. The @samp{if} is
+tested for each record and for each output file. By duplicating the loop
+body, the @samp{if} is only tested once for each input record. If there are
+@var{N} input records and @var{M} output files, the first method only
+executes @var{N} @samp{if} statements, while the second executes
+@var{N}@code{*}@var{M} @samp{if} statements.
+
+Finally, the @code{END} rule cleans up by closing all the output files:
+
+@example
+@c file eg/prog/tee.awk
+END \
+@{
+ for (i in copy)
+ close(copy[i])
+@}
+@c endfile
+@end example
+
+@node Uniq Program
+@subsection Printing Nonduplicated Lines of Text
+
+@c STARTOFRANGE prunt
+@cindex printing, unduplicated lines of text
+@c STARTOFRANGE tpul
+@cindex text@comma{} printing, unduplicated lines of
+@cindex @command{uniq} utility
+The @command{uniq} utility reads sorted lines of data on its standard
+input, and by default removes duplicate lines. In other words, it only
+prints unique lines---hence the name. @command{uniq} has a number of
+options. The usage is as follows:
+
+@example
+uniq @r{[}-udc @r{[}-@var{n}@r{]]} @r{[}+@var{n}@r{]} @r{[} @var{input file} @r{[} @var{output file} @r{]]}
+@end example
+
+The options for @command{uniq} are:
+
+@table @code
+@item -d
+Pnly print only repeated lines.
+
+@item -u
+Print only nonrepeated lines.
+
+@item -c
+Count lines. This option overrides @option{-d} and @option{-u}. Both repeated
+and nonrepeated lines are counted.
+
+@item -@var{n}
+Skip @var{n} fields before comparing lines. The definition of fields
+is similar to @command{awk}'s default: nonwhitespace characters separated
+by runs of spaces and/or tabs.
+
+@item +@var{n}
+Skip @var{n} characters before comparing lines. Any fields specified with
+@samp{-@var{n}} are skipped first.
+
+@item @var{input file}
+Data is read from the input file named on the command line, instead of from
+the standard input.
+
+@item @var{output file}
+The generated output is sent to the named output file, instead of to the
+standard output.
+@end table
+
+Normally @command{uniq} behaves as if both the @option{-d} and
+@option{-u} options are provided.
+
+@command{uniq} uses the
+@code{getopt} library function
+(@pxref{Getopt Function})
+and the @code{join} library function
+(@pxref{Join Function}).
+
+The program begins with a @code{usage} function and then a brief outline of
+the options and their meanings in a comment.
+The @code{BEGIN} rule deals with the command-line arguments and options. It
+uses a trick to get @code{getopt} to handle options of the form @samp{-25},
+treating such an option as the option letter @samp{2} with an argument of
+@samp{5}. If indeed two or more digits are supplied (@code{Optarg} looks
+like a number), @code{Optarg} is
+concatenated with the option digit and then the result is added to zero to make
+it into a number. If there is only one digit in the option, then
+@code{Optarg} is not needed. In this case, @code{Optind} must be decremented so that
+@code{getopt} processes it next time. This code is admittedly a bit
+tricky.
+
+If no options are supplied, then the default is taken, to print both
+repeated and nonrepeated lines. The output file, if provided, is assigned
+to @code{outputfile}. Early on, @code{outputfile} is initialized to the
+standard output, @file{/dev/stdout}:
+
+@cindex @code{uniq.awk} program
+@example
+@c file eg/prog/uniq.awk
+@group
+# uniq.awk --- do uniq in awk
+#
+# Requires getopt and join library functions
+@end group
+@c endfile
+@ignore
+@c file eg/prog/uniq.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/uniq.awk
+function usage( e)
+@{
+ e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
+ print e > "/dev/stderr"
+ exit 1
+@}
+
+# -c count lines. overrides -d and -u
+# -d only repeated lines
+# -u only non-repeated lines
+# -n skip n fields
+# +n skip n characters, skip fields first
+
+BEGIN \
+@{
+ count = 1
+ outputfile = "/dev/stdout"
+ opts = "udc0:1:2:3:4:5:6:7:8:9:"
+ while ((c = getopt(ARGC, ARGV, opts)) != -1) @{
+ if (c == "u")
+ non_repeated_only++
+ else if (c == "d")
+ repeated_only++
+ else if (c == "c")
+ do_count++
+ else if (index("0123456789", c) != 0) @{
+ # getopt requires args to options
+ # this messes us up for things like -5
+ if (Optarg ~ /^[0-9]+$/)
+ fcount = (c Optarg) + 0
+ else @{
+ fcount = c + 0
+ Optind--
+ @}
+ @} else
+ usage()
+ @}
+
+ if (ARGV[Optind] ~ /^\+[0-9]+$/) @{
+ charcount = substr(ARGV[Optind], 2) + 0
+ Optind++
+ @}
+
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ if (repeated_only == 0 && non_repeated_only == 0)
+ repeated_only = non_repeated_only = 1
+
+ if (ARGC - Optind == 2) @{
+ outputfile = ARGV[ARGC - 1]
+ ARGV[ARGC - 1] = ""
+ @}
+@}
+@c endfile
+@end example
+
+The following function, @code{are_equal}, compares the current line,
+@code{$0}, to the
+previous line, @code{last}. It handles skipping fields and characters.
+If no field count and no character count are specified, @code{are_equal}
+simply returns one or zero depending upon the result of a simple string
+comparison of @code{last} and @code{$0}. Otherwise, things get more
+complicated.
+If fields have to be skipped, each line is broken into an array using
+@code{split}
+(@pxref{String Functions});
+the desired fields are then joined back into a line using @code{join}.
+The joined lines are stored in @code{clast} and @code{cline}.
+If no fields are skipped, @code{clast} and @code{cline} are set to
+@code{last} and @code{$0}, respectively.
+Finally, if characters are skipped, @code{substr} is used to strip off the
+leading @code{charcount} characters in @code{clast} and @code{cline}. The
+two strings are then compared and @code{are_equal} returns the result:
+
+@example
+@c file eg/prog/uniq.awk
+function are_equal( n, m, clast, cline, alast, aline)
+@{
+ if (fcount == 0 && charcount == 0)
+ return (last == $0)
+
+ if (fcount > 0) @{
+ n = split(last, alast)
+ m = split($0, aline)
+ clast = join(alast, fcount+1, n)
+ cline = join(aline, fcount+1, m)
+ @} else @{
+ clast = last
+ cline = $0
+ @}
+ if (charcount) @{
+ clast = substr(clast, charcount + 1)
+ cline = substr(cline, charcount + 1)
+ @}
+
+ return (clast == cline)
+@}
+@c endfile
+@end example
+
+The following two rules are the body of the program. The first one is
+executed only for the very first line of data. It sets @code{last} equal to
+@code{$0}, so that subsequent lines of text have something to be compared to.
+
+The second rule does the work. The variable @code{equal} is one or zero,
+depending upon the results of @code{are_equal}'s comparison. If @command{uniq}
+is counting repeated lines, and the lines are equal, then it increments the @code{count} variable.
+Otherwise, it prints the line and resets @code{count},
+since the two lines are not equal.
+
+If @command{uniq} is not counting, and if the lines are equal, @code{count} is incremented.
+Nothing is printed, since the point is to remove duplicates.
+Otherwise, if @command{uniq} is counting repeated lines and more than
+one line is seen, or if @command{uniq} is counting nonrepeated lines
+and only one line is seen, then the line is printed, and @code{count}
+is reset.
+
+Finally, similar logic is used in the @code{END} rule to print the final
+line of input data:
+
+@example
+@c file eg/prog/uniq.awk
+NR == 1 @{
+ last = $0
+ next
+@}
+
+@{
+ equal = are_equal()
+
+ if (do_count) @{ # overrides -d and -u
+ if (equal)
+ count++
+ else @{
+ printf("%4d %s\n", count, last) > outputfile
+ last = $0
+ count = 1 # reset
+ @}
+ next
+ @}
+
+ if (equal)
+ count++
+ else @{
+ if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+ last = $0
+ count = 1
+ @}
+@}
+
+END @{
+ if (do_count)
+ printf("%4d %s\n", count, last) > outputfile
+ else if ((repeated_only && count > 1) ||
+ (non_repeated_only && count == 1))
+ print last > outputfile
+@}
+@c endfile
+@end example
+@c ENDOFRANGE prunt
+@c ENDOFRANGE tpul
+
+@node Wc Program
+@subsection Counting Things
+
+@c STARTOFRANGE count
+@cindex counting
+@c STARTOFRANGE infco
+@cindex input files, counting elements in
+@c STARTOFRANGE woco
+@cindex words, counting
+@c STARTOFRANGE chco
+@cindex characters, counting
+@c STARTOFRANGE lico
+@cindex lines, counting
+@cindex @command{wc} utility
+The @command{wc} (word count) utility counts lines, words, and characters in
+one or more input files. Its usage is as follows:
+
+@example
+wc @r{[}-lwc@r{]} @r{[} @var{files} @dots{} @r{]}
+@end example
+
+If no files are specified on the command line, @command{wc} reads its standard
+input. If there are multiple files, it also prints total counts for all
+the files. The options and their meanings are shown in the following list:
+
+@table @code
+@item -l
+Count only lines.
+
+@item -w
+Count only words.
+A ``word'' is a contiguous sequence of nonwhitespace characters, separated
+by spaces and/or tabs. Luckily, this is the normal way @command{awk} separates
+fields in its input data.
+
+@item -c
+Count only characters.
+@end table
+
+Implementing @command{wc} in @command{awk} is particularly elegant,
+since @command{awk} does a lot of the work for us; it splits lines into
+words (i.e., fields) and counts them, it counts lines (i.e., records),
+and it can easily tell us how long a line is.
+
+This uses the @code{getopt} library function
+(@pxref{Getopt Function})
+and the file-transition functions
+(@pxref{Filetrans Function}).
+
+This version has one notable difference from traditional versions of
+@command{wc}: it always prints the counts in the order lines, words,
+and characters. Traditional versions note the order of the @option{-l},
+@option{-w}, and @option{-c} options on the command line, and print the
+counts in that order.
+
+The @code{BEGIN} rule does the argument processing. The variable
+@code{print_total} is true if more than one file is named on the
+command line:
+
+@cindex @code{wc.awk} program
+@example
+@c file eg/prog/wc.awk
+# wc.awk --- count lines, words, characters
+@c endfile
+@ignore
+@c file eg/prog/wc.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+@c endfile
+@end ignore
+@c file eg/prog/wc.awk
+
+# Options:
+# -l only count lines
+# -w only count words
+# -c only count characters
+#
+# Default is to count lines, words, characters
+#
+# Requires getopt and file transition library functions
+
+BEGIN @{
+ # let getopt print a message about
+ # invalid options. we ignore them
+ while ((c = getopt(ARGC, ARGV, "lwc")) != -1) @{
+ if (c == "l")
+ do_lines = 1
+ else if (c == "w")
+ do_words = 1
+ else if (c == "c")
+ do_chars = 1
+ @}
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+
+ # if no options, do all
+ if (! do_lines && ! do_words && ! do_chars)
+ do_lines = do_words = do_chars = 1
+
+ print_total = (ARGC - i > 2)
+@}
+@c endfile
+@end example
+
+The @code{beginfile} function is simple; it just resets the counts of lines,
+words, and characters to zero, and saves the current @value{FN} in
+@code{fname}:
+
+@c NEXT ED: make it lines = words = chars = 0
+@example
+@c file eg/prog/wc.awk
+function beginfile(file)
+@{
+ chars = lines = words = 0
+ fname = FILENAME
+@}
+@c endfile
+@end example
+
+The @code{endfile} function adds the current file's numbers to the running
+totals of lines, words, and characters.@footnote{@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.} It then prints out those numbers
+for the file that was just read. It relies on @code{beginfile} to reset the
+numbers for the following @value{DF}:
+@c ONE DAY: make the above footnote an exercise, instead of giving away the answer.
+
+@c NEXT ED: make order for += be lines, words, chars
+@example
+@c file eg/prog/wc.awk
+function endfile(file)
+@{
+ tchars += chars
+ tlines += lines
+ twords += words
+ if (do_lines)
+ printf "\t%d", lines
+@group
+ if (do_words)
+ printf "\t%d", words
+@end group
+ if (do_chars)
+ printf "\t%d", chars
+ printf "\t%s\n", fname
+@}
+@c endfile
+@end example
+
+There is one rule that is executed for each line. It adds the length of
+the record, plus one, to @code{chars}. Adding one plus the record length
+is needed because the newline character separating records (the value
+of @code{RS}) is not part of the record itself, and thus not included
+in its length. Next, @code{lines} is incremented for each line read,
+and @code{words} is incremented by the value of @code{NF}, which is the
+number of ``words'' on this line:
+
+@example
+@c file eg/prog/wc.awk
+# do per line
+@{
+ chars += length($0) + 1 # get newline
+ lines++
+ words += NF
+@}
+@c endfile
+@end example
+
+Finally, the @code{END} rule simply prints the totals for all the files:
+
+@example
+@c file eg/prog/wc.awk
+END @{
+ if (print_total) @{
+ if (do_lines)
+ printf "\t%d", tlines
+ if (do_words)
+ printf "\t%d", twords
+ if (do_chars)
+ printf "\t%d", tchars
+ print "\ttotal"
+ @}
+@}
+@c endfile
+@end example
+@c ENDOFRANGE count
+@c ENDOFRANGE infco
+@c ENDOFRANGE lico
+@c ENDOFRANGE woco
+@c ENDOFRANGE chco
+@c ENDOFRANGE posimawk
+
+@node Miscellaneous Programs
+@section A Grab Bag of @command{awk} Programs
+
+This @value{SECTION} is a large ``grab bag'' of miscellaneous programs.
+We hope you find them both interesting and enjoyable.
+
+@menu
+* Dupword Program:: Finding duplicated words in a document.
+* Alarm Program:: An alarm clock.
+* Translate Program:: A program similar to the @command{tr} utility.
+* Labels Program:: Printing mailing labels.
+* Word Sorting:: A program to produce a word usage count.
+* History Sorting:: Eliminating duplicate entries from a history
+ file.
+* Extract Program:: Pulling out programs from Texinfo source
+ files.
+* Simple Sed:: A Simple Stream Editor.
+* Igawk Program:: A wrapper for @command{awk} that includes
+ files.
+@end menu
+
+@node Dupword Program
+@subsection Finding Duplicated Words in a Document
+
+@cindex words, duplicate@comma{} searching for
+@cindex searching, for words
+@cindex documents@comma{} searching
+A common error when writing large amounts of prose is to accidentally
+duplicate words. Typically you will see this in text as something like ``the
+the program does the following@dots{}'' When the text is online, often
+the duplicated words occur at the end of one line and the beginning of
+another, making them very difficult to spot.
+@c as here!
+
+This program, @file{dupword.awk}, scans through a file one line at a time
+and looks for adjacent occurrences of the same word. It also saves the last
+word on a line (in the variable @code{prev}) for comparison with the first
+word on the next line.
+
+@cindex Texinfo
+The first two statements make sure that the line is all lowercase,
+so that, for example, ``The'' and ``the'' compare equal to each other.
+The next statement replaces nonalphanumeric and nonwhitespace characters
+with spaces, so that punctuation does not affect the comparison either.
+The characters are replaced with spaces so that formatting controls
+don't create nonsense words (e.g., the Texinfo @samp{@@code@{NF@}}
+becomes @samp{codeNF} if punctuation is simply deleted). The record is
+then resplit into fields, yielding just the actual words on the line,
+and ensuring that there are no empty fields.
+
+If there are no fields left after removing all the punctuation, the
+current record is skipped. Otherwise, the program loops through each
+word, comparing it to the previous one:
+
+@cindex @code{dupword.awk} program
+@example
+@c file eg/prog/dupword.awk
+# dupword.awk --- find duplicate words in text
+@c endfile
+@ignore
+@c file eg/prog/dupword.awk
+#
+# Arnold Robbins, arnold@@gnu.org, 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 # re-split
+ if (NF == 0)
+ next
+ if ($1 == prev)
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $1)
+ for (i = 2; i <= NF; i++)
+ if ($i == $(i-1))
+ printf("%s:%d: duplicate %s\n",
+ FILENAME, FNR, $i)
+ prev = $NF
+@}
+@c endfile
+@end example
+
+@node Alarm Program
+@subsection An Alarm Clock Program
+@cindex insomnia, cure for
+@cindex Robbins, Arnold
+@quotation
+@i{Nothing cures insomnia like a ringing alarm clock.}@*
+Arnold Robbins
+@end quotation
+
+@c STARTOFRANGE tialarm
+@cindex time, alarm clock example program
+@c STARTOFRANGE alaex
+@cindex alarm clock example program
+The following program is a simple ``alarm clock'' program.
+You give it a time of day and an optional message. At the specified time,
+it prints the message on the standard output. In addition, you can give it
+the number of times to repeat the message as well as a delay between
+repetitions.
+
+This program uses the @code{gettimeofday} function from
+@ref{Gettimeofday Function}.
+
+All the work is done in the @code{BEGIN} rule. The first part is argument
+checking and setting of defaults: the delay, the count, and the message to
+print. If the user supplied a message without the ASCII BEL
+character (known as the ``alert'' character, @code{"\a"}), then it is added to
+the message. (On many systems, printing the ASCII BEL generates an
+audible alert. Thus when the alarm goes off, the system calls attention
+to itself in case the user is not looking at the computer or terminal.)
+Here is the program:
+
+@cindex @code{alarm.awk} program
+@example
+@c file eg/prog/alarm.awk
+# alarm.awk --- set an alarm
+#
+# Requires gettimeofday library function
+@c endfile
+@ignore
+@c file eg/prog/alarm.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/alarm.awk
+# usage: alarm time [ "message" [ count [ delay ] ] ]
+
+BEGIN \
+@{
+ # Initial argument sanity checking
+ usage1 = "usage: alarm time ['message' [count [delay]]]"
+ usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
+
+ if (ARGC < 2) @{
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ @} else if (ARGC == 5) @{
+ delay = ARGV[4] + 0
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ @} else if (ARGC == 4) @{
+ count = ARGV[3] + 0
+ message = ARGV[2]
+ @} else if (ARGC == 3) @{
+ message = ARGV[2]
+ @} else if (ARGV[1] !~ /[0-9]?[0-9]:[0-9][0-9]/) @{
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ @}
+
+ # set defaults for once we reach the desired time
+ if (delay == 0)
+ delay = 180 # 3 minutes
+@group
+ if (count == 0)
+ count = 5
+@end group
+ if (message == "")
+ message = sprintf("\aIt is now %s!\a", ARGV[1])
+ else if (index(message, "\a") == 0)
+ message = "\a" message "\a"
+@c endfile
+@end example
+
+The next @value{SECTION} of code turns the alarm time into hours and minutes,
+converts it (if necessary) to a 24-hour clock, and then turns that
+time into a count of the seconds since midnight. Next it turns the current
+time into a count of seconds since midnight. The difference between the two
+is how long to wait before setting off the alarm:
+
+@example
+@c file eg/prog/alarm.awk
+ # split up alarm time
+ split(ARGV[1], atime, ":")
+ hour = atime[1] + 0 # force numeric
+ minute = atime[2] + 0 # force numeric
+
+ # get current broken down time
+ gettimeofday(now)
+
+ # if time given is 12-hour hours and it's after that
+ # hour, e.g., `alarm 5:30' at 9 a.m. means 5:30 p.m.,
+ # then add 12 to real hour
+ if (hour < 12 && now["hour"] > hour)
+ hour += 12
+
+ # set target time in seconds since midnight
+ target = (hour * 60 * 60) + (minute * 60)
+
+ # get current time in seconds since midnight
+ current = (now["hour"] * 60 * 60) + \
+ (now["minute"] * 60) + now["second"]
+
+ # how long to sleep for
+ naptime = target - current
+ if (naptime <= 0) @{
+ print "time is in the past!" > "/dev/stderr"
+ exit 1
+ @}
+@c endfile
+@end example
+
+@cindex @command{sleep} utility
+Finally, the program uses the @code{system} function
+(@pxref{I/O Functions})
+to call the @command{sleep} utility. The @command{sleep} utility simply pauses
+for the given number of seconds. If the exit status is not zero,
+the program assumes that @command{sleep} was interrupted and exits. If
+@command{sleep} exited with an OK status (zero), then the program prints the
+message in a loop, again using @command{sleep} to delay for however many
+seconds are necessary:
+
+@example
+@c file eg/prog/alarm.awk
+ # zzzzzz..... go away if interrupted
+ if (system(sprintf("sleep %d", naptime)) != 0)
+ exit 1
+
+ # time to notify!
+ command = sprintf("sleep %d", delay)
+ for (i = 1; i <= count; i++) @{
+ print message
+ # if sleep command interrupted, go away
+ if (system(command) != 0)
+ break
+ @}
+
+ exit 0
+@}
+@c endfile
+@end example
+@c ENDOFRANGE tialarm
+@c ENDOFRANGE alaex
+
+@node Translate Program
+@subsection Transliterating Characters
+
+@c STARTOFRANGE chtra
+@cindex characters, transliterating
+@cindex @command{tr} utility
+The system @command{tr} utility transliterates characters. For example, it is
+often used to map uppercase letters into lowercase for further processing:
+
+@example
+@var{generate data} | tr 'A-Z' 'a-z' | @var{process data} @dots{}
+@end example
+
+@command{tr} requires two lists of characters.@footnote{On some older
+System V systems,
+@ifset ORA
+including Solaris,
+@end ifset
+@command{tr} may require that the lists be written as
+range expressions enclosed in square brackets (@samp{[a-z]}) and quoted,
+to prevent the shell from attempting a @value{FN} expansion. This is
+not a feature.} When processing the input, the first character in the
+first list is replaced with the first character in the second list,
+the second character in the first list is replaced with the second
+character in the second list, and so on. If there are more characters
+in the ``from'' list than in the ``to'' list, the last character of the
+``to'' list is used for the remaining characters in the ``from'' list.
+
+Some time ago,
+@c early or mid-1989!
+a user proposed that a transliteration function should
+be added to @command{gawk}.
+@c Wishing to avoid gratuitous new features,
+@c at least theoretically
+The following program was written to
+prove that character transliteration could be done with a user-level
+function. This program is not as complete as the system @command{tr} utility
+but it does most of the job.
+
+The @command{translate} program demonstrates one of the few weaknesses
+of standard @command{awk}: dealing with individual characters is very
+painful, requiring repeated use of the @code{substr}, @code{index},
+and @code{gsub} built-in functions
+(@pxref{String Functions}).@footnote{This
+program was written before @command{gawk} acquired the ability to
+split each character in a string into separate array elements.}
+@c Exercise: How might you use this new feature to simplify the program?
+There are two functions. The first, @code{stranslate}, takes three
+arguments:
+
+@table @code
+@item from
+A list of characters from which to translate.
+
+@item to
+A list of characters to which to translate.
+
+@item target
+The string on which to do the translation.
+@end table
+
+Associative arrays make the translation part fairly easy. @code{t_ar} holds
+the ``to'' characters, indexed by the ``from'' characters. Then a simple
+loop goes through @code{from}, one character at a time. For each character
+in @code{from}, if the character appears in @code{target}, @code{gsub}
+is used to change it to the corresponding @code{to} character.
+
+The @code{translate} function simply calls @code{stranslate} using @code{$0}
+as the target. The main program sets two global variables, @code{FROM} and
+@code{TO}, from the command line, and then changes @code{ARGV} so that
+@command{awk} reads from the standard input.
+
+Finally, the processing rule simply calls @code{translate} for each record:
+
+@cindex @code{translate.awk} program
+@example
+@c file eg/prog/translate.awk
+# translate.awk --- do tr-like stuff
+@c endfile
+@ignore
+@c file eg/prog/translate.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# August 1989
+
+@c endfile
+@end ignore
+@c file eg/prog/translate.awk
+# Bugs: does not handle things like: tr A-Z a-z, it has
+# to be spelled out. However, if `to' is shorter than `from',
+# the last character in `to' is used for the rest of `from'.
+
+function stranslate(from, to, target, lf, lt, t_ar, i, c)
+@{
+ lf = length(from)
+ lt = length(to)
+ for (i = 1; i <= lt; i++)
+ t_ar[substr(from, i, 1)] = substr(to, i, 1)
+ if (lt < lf)
+ for (; i <= lf; i++)
+ t_ar[substr(from, i, 1)] = substr(to, lt, 1)
+ for (i = 1; i <= lf; i++) @{
+ c = substr(from, i, 1)
+ if (index(target, c) > 0)
+ gsub(c, t_ar[c], target)
+ @}
+ return target
+@}
+
+function translate(from, to)
+@{
+ return $0 = stranslate(from, to, $0)
+@}
+
+# main program
+BEGIN @{
+@group
+ if (ARGC < 3) @{
+ print "usage: translate from to" > "/dev/stderr"
+ exit
+ @}
+@end group
+ FROM = ARGV[1]
+ TO = ARGV[2]
+ ARGC = 2
+ ARGV[1] = "-"
+@}
+
+@{
+ translate(FROM, TO)
+ print
+@}
+@c endfile
+@end example
+
+While it is possible to do character transliteration in a user-level
+function, it is not necessarily efficient, and we (the @command{gawk}
+authors) started to consider adding a built-in function. However,
+shortly after writing this program, we learned that the System V Release 4
+@command{awk} had added the @code{toupper} and @code{tolower} functions
+(@pxref{String Functions}).
+These functions handle the vast majority of the
+cases where character transliteration is necessary, and so we chose to
+simply add those functions to @command{gawk} as well and then leave well
+enough alone.
+
+An obvious improvement to this program would be to set up the
+@code{t_ar} array only once, in a @code{BEGIN} rule. However, this
+assumes that the ``from'' and ``to'' lists
+will never change throughout the lifetime of the program.
+@c ENDOFRANGE chtra
+
+@node Labels Program
+@subsection Printing Mailing Labels
+
+@c STARTOFRANGE prml
+@cindex printing, mailing labels
+@c STARTOFRANGE mlprint
+@cindex mailing labels@comma{} printing
+Here is a ``real world''@footnote{``Real world'' is defined as
+``a program actually used to get something done.''}
+program. This
+script reads lists of names and
+addresses and generates mailing labels. Each page of labels has 20 labels
+on it, 2 across and 10 down. The addresses are guaranteed to be no more
+than 5 lines of data. Each address is separated from the next by a blank
+line.
+
+The basic idea is to read 20 labels worth of data. Each line of each label
+is stored in the @code{line} array. The single rule takes care of filling
+the @code{line} array and printing the page when 20 labels have been read.
+
+The @code{BEGIN} rule simply sets @code{RS} to the empty string, so that
+@command{awk} splits records at blank lines
+(@pxref{Records}).
+It sets @code{MAXLINES} to 100, since 100 is the maximum number
+of lines on the page (20 * 5 = 100).
+
+Most of the work is done in the @code{printpage} function.
+The label lines are stored sequentially in the @code{line} array. But they
+have to print horizontally; @code{line[1]} next to @code{line[6]},
+@code{line[2]} next to @code{line[7]}, and so on. Two loops are used to
+accomplish this. The outer loop, controlled by @code{i}, steps through
+every 10 lines of data; this is each row of labels. The inner loop,
+controlled by @code{j}, goes through the lines within the row.
+As @code{j} goes from 0 to 4, @samp{i+j} is the @code{j}-th line in
+the row, and @samp{i+j+5} is the entry next to it. The output ends up
+looking something like this:
+
+@example
+line 1 line 6
+line 2 line 7
+line 3 line 8
+line 4 line 9
+line 5 line 10
+@dots{}
+@end example
+
+As a final note, an extra blank line is printed at lines 21 and 61, to keep
+the output lined up on the labels. This is dependent on the particular
+brand of labels in use when the program was written. You will also note
+that there are 2 blank lines at the top and 2 blank lines at the bottom.
+
+The @code{END} rule arranges to flush the final page of labels; there may
+not have been an even multiple of 20 labels in the data:
+
+@cindex @code{labels.awk} program
+@example
+@c file eg/prog/labels.awk
+# labels.awk --- print mailing labels
+@c endfile
+@ignore
+@c file eg/prog/labels.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# June 1992
+@c endfile
+@end ignore
+@c file eg/prog/labels.awk
+
+# Each label is 5 lines of data that may have blank lines.
+# The label sheets have 2 blank lines at the top and 2 at
+# the bottom.
+
+BEGIN @{ RS = "" ; MAXLINES = 100 @}
+
+function printpage( i, j)
+@{
+ if (Nlines <= 0)
+ return
+
+ printf "\n\n" # header
+
+ for (i = 1; i <= Nlines; i += 10) @{
+ if (i == 21 || i == 61)
+ print ""
+ for (j = 0; j < 5; j++) @{
+ if (i + j > MAXLINES)
+ break
+ printf " %-41s %s\n", line[i+j], line[i+j+5]
+ @}
+ print ""
+ @}
+
+ printf "\n\n" # footer
+
+ for (i in line)
+ line[i] = ""
+@}
+
+# main rule
+@{
+ if (Count >= 20) @{
+ printpage()
+ Count = 0
+ Nlines = 0
+ @}
+ n = split($0, a, "\n")
+ for (i = 1; i <= n; i++)
+ line[++Nlines] = a[i]
+ for (; i <= 5; i++)
+ line[++Nlines] = ""
+ Count++
+@}
+
+END \
+@{
+ printpage()
+@}
+@c endfile
+@end example
+@c ENDOFRANGE prml
+@c ENDOFRANGE mlprint
+
+@node Word Sorting
+@subsection Generating Word-Usage Counts
+
+@c STARTOFRANGE worus
+@cindex words, usage counts@comma{} generating
+@c NEXT ED: Rewrite this whole section and example
+The following @command{awk} program prints
+the number of occurrences of each word in its input. It illustrates the
+associative nature of @command{awk} arrays by using strings as subscripts. It
+also demonstrates the @samp{for @var{index} in @var{array}} mechanism.
+Finally, it shows how @command{awk} is used in conjunction with other
+utility programs to do a useful task of some complexity with a minimum of
+effort. Some explanations follow the program listing:
+
+@example
+# Print list of word frequencies
+@{
+ for (i = 1; i <= NF; i++)
+ freq[$i]++
+@}
+
+END @{
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+@}
+@end example
+
+@c Exercise: Use asort() here
+
+This program has two rules. The
+first rule, because it has an empty pattern, is executed for every input line.
+It uses @command{awk}'s field-accessing mechanism
+(@pxref{Fields}) to pick out the individual words from
+the line, and the built-in variable @code{NF} (@pxref{Built-in Variables})
+to know how many fields are available.
+For each input word, it increments an element of the array @code{freq} to
+reflect that the word has been seen an additional time.
+
+The second rule, because it has the pattern @code{END}, is not executed
+until the input has been exhausted. It prints out the contents of the
+@code{freq} table that has been built up inside the first action.
+This program has several problems that would prevent it from being
+useful by itself on real text files:
+
+@itemize @bullet
+@item
+Words are detected using the @command{awk} convention that fields are
+separated just by whitespace. Other characters in the input (except
+newlines) don't have any special meaning to @command{awk}. This means that
+punctuation characters count as part of words.
+
+@item
+The @command{awk} language considers upper- and lowercase characters to be
+distinct. Therefore, ``bartender'' and ``Bartender'' are not treated
+as the same word. This is undesirable, since in normal text, words
+are capitalized if they begin sentences, and a frequency analyzer should not
+be sensitive to capitalization.
+
+@item
+The output does not come out in any useful order. You're more likely to be
+interested in which words occur most frequently or in having an alphabetized
+table of how frequently each word occurs.
+@end itemize
+
+@cindex @command{sort} utility
+The way to solve these problems is to use some of @command{awk}'s more advanced
+features. First, we use @code{tolower} to remove
+case distinctions. Next, we use @code{gsub} to remove punctuation
+characters. Finally, we use the system @command{sort} utility to process the
+output of the @command{awk} script. Here is the new version of
+the program:
+
+@cindex @code{wordfreq.awk} program
+@example
+@c file eg/prog/wordfreq.awk
+# wordfreq.awk --- print list of word frequencies
+
+@{
+ $0 = tolower($0) # remove case distinctions
+ # remove punctuation
+ gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
+ for (i = 1; i <= NF; i++)
+ freq[$i]++
+@}
+
+END @{
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+@}
+@c endfile
+@end example
+
+Assuming we have saved this program in a file named @file{wordfreq.awk},
+and that the data is in @file{file1}, the following pipeline:
+
+@example
+awk -f wordfreq.awk file1 | sort -k 2nr
+@end example
+
+@noindent
+produces a table of the words appearing in @file{file1} in order of
+decreasing frequency. The @command{awk} program suitably massages the
+data and produces a word frequency table, which is not ordered.
+
+The @command{awk} script's output is then sorted by the @command{sort}
+utility and printed on the terminal. The options given to @command{sort}
+specify a sort that uses the second field of each input line (skipping
+one field), that the sort keys should be treated as numeric quantities
+(otherwise @samp{15} would come before @samp{5}), and that the sorting
+should be done in descending (reverse) order.
+
+The @command{sort} could even be done from within the program, by changing
+the @code{END} action to:
+
+@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
+
+This way of sorting must be used on systems that do not
+have true pipes at the command-line (or batch-file) level.
+See the general operating system documentation for more information on how
+to use the @command{sort} program.
+@c ENDOFRANGE worus
+
+@node History Sorting
+@subsection Removing Duplicates from Unsorted Text
+
+@c STARTOFRANGE lidu
+@cindex lines, duplicate@comma{} removing
+The @command{uniq} program
+(@pxref{Uniq Program}),
+removes duplicate lines from @emph{sorted} data.
+
+Suppose, however, you need to remove duplicate lines from a @value{DF} but
+that you want to preserve the order the lines are in. A good example of
+this might be a shell history file. The history file keeps a copy of all
+the commands you have entered, and it is not unusual to repeat a command
+several times in a row. Occasionally you might want to compact the history
+by removing duplicate entries. Yet it is desirable to maintain the order
+of the original commands.
+
+This simple program does the job. It uses two arrays. The @code{data}
+array is indexed by the text of each line.
+For each line, @code{data[$0]} is incremented.
+If a particular line has not
+been seen before, then @code{data[$0]} is zero.
+In this case, the text of the line is stored in @code{lines[count]}.
+Each element of @code{lines} is a unique command, and the indices of
+@code{lines} indicate the order in which those lines are encountered.
+The @code{END} rule simply prints out the lines, in order:
+
+@cindex Rakitzis, Byron
+@cindex @code{histsort.awk} program
+@example
+@c file eg/prog/histsort.awk
+# histsort.awk --- compact a shell history file
+# Thanks to Byron Rakitzis for the general idea
+@c endfile
+@ignore
+@c file eg/prog/histsort.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# May 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/histsort.awk
+@group
+@{
+ if (data[$0]++ == 0)
+ lines[++count] = $0
+@}
+@end group
+
+END @{
+ for (i = 1; i <= count; i++)
+ print lines[i]
+@}
+@c endfile
+@end example
+
+This program also provides a foundation for generating other useful
+information. For example, using the following @code{print} statement in the
+@code{END} rule indicates how often a particular command is used:
+
+@example
+print data[lines[i]], lines[i]
+@end example
+
+This works because @code{data[$0]} is incremented each time a line is
+seen.
+@c ENDOFRANGE lidu
+
+@node Extract Program
+@subsection Extracting Programs from Texinfo Source Files
+
+@c STARTOFRANGE texse
+@cindex Texinfo, extracting programs from source files
+@c STARTOFRANGE fitex
+@cindex files, Texinfo@comma{} extracting programs from
+@ifnotinfo
+Both this chapter and the previous chapter
+(@ref{Library Functions})
+present a large number of @command{awk} programs.
+@end ifnotinfo
+@ifinfo
+The nodes
+@ref{Library Functions},
+and @ref{Sample Programs},
+are the top level nodes for a large number of @command{awk} programs.
+@end ifinfo
+If you want to experiment with these programs, it is tedious to have to type
+them in by hand. Here we present a program that can extract parts of a
+Texinfo input file into separate files.
+
+@cindex Texinfo
+This @value{DOCUMENT} is written in Texinfo, the GNU project's document
+formatting
+language.
+A single Texinfo source file can be used to produce both
+printed and online documentation.
+@ifnotinfo
+Texinfo is fully documented in the book
+@cite{Texinfo---The GNU Documentation Format},
+available from the Free Software Foundation.
+@end ifnotinfo
+@ifinfo
+The Texinfo language is described fully, starting with
+@ref{Top}.
+@end ifinfo
+
+For our purposes, it is enough to know three things about Texinfo input
+files:
+
+@itemize @bullet
+@item
+The ``at'' symbol (@samp{@@}) is special in Texinfo, much as
+the backslash (@samp{\}) is in C
+or @command{awk}. Literal @samp{@@} symbols are represented in Texinfo source
+files as @samp{@@@@}.
+
+@item
+Comments start with either @samp{@@c} or @samp{@@comment}.
+The file-extraction program works by using special comments that start
+at the beginning of a line.
+
+@item
+Lines containing @samp{@@group} and @samp{@@end group} commands bracket
+example text that should not be split across a page boundary.
+(Unfortunately, @TeX{} isn't always smart enough to do things exactly right,
+and we have to give it some help.)
+@end itemize
+
+The following program, @file{extract.awk}, reads through a Texinfo source
+file and does two things, based on the special comments.
+Upon seeing @samp{@w{@@c system @dots{}}},
+it runs a command, by extracting the command text from the
+control line and passing it on to the @code{system} function
+(@pxref{I/O Functions}).
+Upon seeing @samp{@@c file @var{filename}}, each subsequent line is sent to
+the file @var{filename}, until @samp{@@c endfile} is encountered.
+The rules in @file{extract.awk} match either @samp{@@c} or
+@samp{@@comment} by letting the @samp{omment} part be optional.
+Lines containing @samp{@@group} and @samp{@@end group} are simply removed.
+@file{extract.awk} uses the @code{join} library function
+(@pxref{Join Function}).
+
+The example programs in the online Texinfo source for @cite{@value{TITLE}}
+(@file{gawk.texi}) have all been bracketed inside @samp{file} and
+@samp{endfile} lines. The @command{gawk} distribution uses a copy of
+@file{extract.awk} to extract the sample programs and install many
+of them in a standard directory where @command{gawk} can find them.
+The Texinfo file looks something like this:
+
+@example
+@dots{}
+This program has a @@code@{BEGIN@} rule,
+that prints a nice message:
+
+@@example
+@@c file examples/messages.awk
+BEGIN @@@{ print "Don't panic!" @@@}
+@@c end file
+@@end example
+
+It also prints some final advice:
+
+@@example
+@@c file examples/messages.awk
+END @@@{ print "Always avoid bored archeologists!" @@@}
+@@c end file
+@@end example
+@dots{}
+@end example
+
+@file{extract.awk} begins by setting @code{IGNORECASE} to one, so that
+mixed upper- and lowercase letters in the directives won't matter.
+
+The first rule handles calling @code{system}, checking that a command is
+given (@code{NF} is at least three) and also checking that the command
+exits with a zero exit status, signifying OK:
+
+@cindex @code{extract.awk} program
+@example
+@c file eg/prog/extract.awk
+# extract.awk --- extract files and run programs
+# from texinfo files
+@c endfile
+@ignore
+@c file eg/prog/extract.awk
+#
+# Arnold Robbins, arnold@@gnu.org, 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 = (FILENAME ":" FNR)
+ e = (e ": badly formed `system' line")
+ print e > "/dev/stderr"
+ next
+ @}
+ $1 = ""
+ $2 = ""
+ stat = system($0)
+ if (stat != 0) @{
+ e = (FILENAME ":" FNR)
+ e = (e ": warning: system returned " stat)
+ print e > "/dev/stderr"
+ @}
+@}
+@c endfile
+@end example
+
+@noindent
+The variable @code{e} is used so that the function
+fits nicely on the
+@ifnotinfo
+page.
+@end ifnotinfo
+@ifnottex
+screen.
+@end ifnottex
+
+The second rule handles moving data into files. It verifies that a
+@value{FN} is given in the directive. If the file named is not the
+current file, then the current file is closed. Keeping the current file
+open until a new file is encountered allows the use of the @samp{>}
+redirection for printing the contents, keeping open file management
+simple.
+
+The @samp{for} loop does the work. It reads lines using @code{getline}
+(@pxref{Getline}).
+For an unexpected end of file, it calls the @code{@w{unexpected_eof}}
+function. If the line is an ``endfile'' line, then it breaks out of
+the loop.
+If the line is an @samp{@@group} or @samp{@@end group} line, then it
+ignores it and goes on to the next line.
+Similarly, comments within examples are also ignored.
+
+Most of the work is in the following few lines. If the line has no @samp{@@}
+symbols, the program can print it directly.
+Otherwise, each leading @samp{@@} must be stripped off.
+To remove the @samp{@@} symbols, the line is split into separate elements of
+the array @code{a}, using the @code{split} function
+(@pxref{String Functions}).
+The @samp{@@} symbol is used as the separator character.
+Each element of @code{a} that is empty indicates two successive @samp{@@}
+symbols in the original line. For each two empty elements (@samp{@@@@} in
+the original file), we have to add a single @samp{@@} symbol back in.
+
+When the processing of the array is finished, @code{join} is called with the
+value of @code{SUBSEP}, to rejoin the pieces back into a single
+line. That line is then printed to the output file:
+
+@example
+@c file eg/prog/extract.awk
+/^@@c(omment)?[ \t]+file/ \
+@{
+ if (NF != 3) @{
+ e = (FILENAME ":" FNR ": badly formed `file' line")
+ print e > "/dev/stderr"
+ next
+ @}
+ if ($3 != curfile) @{
+ if (curfile != "")
+ close(curfile)
+ curfile = $3
+ @}
+
+ for (;;) @{
+ if ((getline line) <= 0)
+ unexpected_eof()
+ if (line ~ /^@@c(omment)?[ \t]+endfile/)
+ break
+ else if (line ~ /^@@(end[ \t]+)?group/)
+ continue
+ else if (line ~ /^@@c(omment+)?[ \t]+/)
+ continue
+ if (index(line, "@@") == 0) @{
+ print line > curfile
+ continue
+ @}
+ n = split(line, a, "@@")
+ # if a[1] == "", means leading @@,
+ # don't add one back in.
+ for (i = 2; i <= n; i++) @{
+ if (a[i] == "") @{ # was an @@@@
+ a[i] = "@@"
+ if (a[i+1] == "")
+ i++
+ @}
+ @}
+ print join(a, 1, n, SUBSEP) > curfile
+ @}
+@}
+@c endfile
+@end example
+
+An important thing to note is the use of the @samp{>} redirection.
+Output done with @samp{>} only opens the file once; it stays open and
+subsequent output is appended to the file
+(@pxref{Redirection}).
+This makes it easy to mix program text and explanatory prose for the same
+sample source file (as has been done here!) without any hassle. The file is
+only closed when a new data @value{FN} is encountered or at the end of the
+input file.
+
+Finally, the function @code{@w{unexpected_eof}} prints an appropriate
+error message and then exits.
+The @code{END} rule handles the final cleanup, closing the open file:
+
+@c function lb put on same line for page breaking. sigh
+@example
+@c file eg/prog/extract.awk
+@group
+function unexpected_eof() @{
+ printf("%s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
+ exit 1
+@}
+@end group
+
+END @{
+ if (curfile)
+ close(curfile)
+@}
+@c endfile
+@end example
+@c ENDOFRANGE texse
+@c ENDOFRANGE fitex
+
+@node Simple Sed
+@subsection A Simple Stream Editor
+
+@cindex @command{sed} utility
+@cindex stream editors
+The @command{sed} utility is a stream editor, a program that reads a
+stream of data, makes changes to it, and passes it on.
+It is often used to make global changes to a large file or to a stream
+of data generated by a pipeline of commands.
+While @command{sed} is a complicated program in its own right, its most common
+use is to perform global substitutions in the middle of a pipeline:
+
+@example
+command1 < orig.data | sed 's/old/new/g' | command2 > result
+@end example
+
+Here, @samp{s/old/new/g} tells @command{sed} to look for the regexp
+@samp{old} on each input line and globally replace it with the text
+@samp{new}, i.e., all the occurrences on a line. This is similar to
+@command{awk}'s @code{gsub} function
+(@pxref{String Functions}).
+
+The following program, @file{awksed.awk}, accepts at least two command-line
+arguments: the pattern to look for and the text to replace it with. Any
+additional arguments are treated as data @value{FN}s to process. If none
+are provided, the standard input is used:
+
+@cindex Brennan, Michael
+@cindex @command{awksed.awk} program
+@c @cindex simple stream editor
+@c @cindex stream editor, simple
+@example
+@c file eg/prog/awksed.awk
+# awksed.awk --- do s/foo/bar/g using just print
+# Thanks to Michael Brennan for the idea
+@c endfile
+@ignore
+@c file eg/prog/awksed.awk
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# August 1995
+
+@c endfile
+@end ignore
+@c file eg/prog/awksed.awk
+function usage()
+@{
+ print "usage: awksed pat repl [files...]" > "/dev/stderr"
+ exit 1
+@}
+
+BEGIN @{
+ # validate arguments
+ if (ARGC < 3)
+ usage()
+
+ RS = ARGV[1]
+ ORS = ARGV[2]
+
+ # don't use arguments as files
+ ARGV[1] = ARGV[2] = ""
+@}
+
+@group
+# look ma, no hands!
+@{
+ if (RT == "")
+ printf "%s", $0
+ else
+ print
+@}
+@end group
+@c endfile
+@end example
+
+The program relies on @command{gawk}'s ability to have @code{RS} be a regexp,
+as well as on the setting of @code{RT} to the actual text that terminates the
+record (@pxref{Records}).
+
+The idea is to have @code{RS} be the pattern to look for. @command{gawk}
+automatically sets @code{$0} to the text between matches of the pattern.
+This is text that we want to keep, unmodified. Then, by setting @code{ORS}
+to the replacement text, a simple @code{print} statement outputs the
+text we want to keep, followed by the replacement text.
+
+There is one wrinkle to this scheme, which is what to do if the last record
+doesn't end with text that matches @code{RS}. Using a @code{print}
+statement unconditionally prints the replacement text, which is not correct.
+However, if the file did not end in text that matches @code{RS}, @code{RT}
+is set to the null string. In this case, we can print @code{$0} using
+@code{printf}
+(@pxref{Printf}).
+
+The @code{BEGIN} rule handles the setup, checking for the right number
+of arguments and calling @code{usage} if there is a problem. Then it sets
+@code{RS} and @code{ORS} from the command-line arguments and sets
+@code{ARGV[1]} and @code{ARGV[2]} to the null string, so that they are
+not treated as @value{FN}s
+(@pxref{ARGC and ARGV}).
+
+The @code{usage} function prints an error message and exits.
+Finally, the single rule handles the printing scheme outlined above,
+using @code{print} or @code{printf} as appropriate, depending upon the
+value of @code{RT}.
+
+@ignore
+Exercise, compare the performance of this version with the more
+straightforward:
+
+BEGIN {
+ pat = ARGV[1]
+ repl = ARGV[2]
+ ARGV[1] = ARGV[2] = ""
+}
+
+{ gsub(pat, repl); print }
+
+Exercise: what are the advantages and disadvantages of this version versus sed?
+ Advantage: egrep regexps
+ speed (?)
+ Disadvantage: no & in replacement text
+
+Others?
+@end ignore
+
+@node Igawk Program
+@subsection An Easy Way to Use Library Functions
+
+@c STARTOFRANGE libfex
+@cindex libraries of @command{awk} functions, example program for using
+@c STARTOFRANGE flibex
+@cindex functions, library, example program for using
+Using library functions in @command{awk} can be very beneficial. It
+encourages code reuse and the writing of general functions. Programs are
+smaller and therefore clearer.
+However, using library functions is only easy when writing @command{awk}
+programs; it is painful when running them, requiring multiple @option{-f}
+options. If @command{gawk} is unavailable, then so too is the @env{AWKPATH}
+environment variable and the ability to put @command{awk} functions into a
+library directory (@pxref{Options}).
+It would be nice to be able to write programs in the following manner:
+
+@example
+# library functions
+@@include getopt.awk
+@@include join.awk
+@dots{}
+
+# main program
+BEGIN @{
+ while ((c = getopt(ARGC, ARGV, "a:b:cde")) != -1)
+ @dots{}
+ @dots{}
+@}
+@end example
+
+The following program, @file{igawk.sh}, provides this service.
+It simulates @command{gawk}'s searching of the @env{AWKPATH} variable
+and also allows @dfn{nested} includes; i.e., a file that is included
+with @samp{@@include} can contain further @samp{@@include} statements.
+@command{igawk} makes an effort to only include files once, so that nested
+includes don't accidentally include a library function twice.
+
+@command{igawk} should behave just like @command{gawk} externally. This
+means it should accept all of @command{gawk}'s command-line arguments,
+including the ability to have multiple source files specified via
+@option{-f}, and the ability to mix command-line and library source files.
+
+The program is written using the POSIX Shell (@command{sh}) command
+language.@footnote{Fully explaining the @command{sh} language is beyond
+the scope of this book. We provide some minimal explanations, but see
+a good shell programming book if you wish to understand things in more
+depth.} It works as follows:
+
+@enumerate
+@item
+Loop through the arguments, saving anything that doesn't represent
+@command{awk} source code for later, when the expanded program is run.
+
+@item
+For any arguments that do represent @command{awk} text, put the arguments into
+a shell variable that will be expanded. There are two cases:
+
+@enumerate a
+@item
+Literal text, provided with @option{--source} or @option{--source=}. This
+text is just appended directly.
+
+@item
+Source @value{FN}s, provided with @option{-f}. We use a neat trick and append
+@samp{@@include @var{filename}} to the shell variable's contents. Since the file-inclusion
+program works the way @command{gawk} does, this gets the text
+of the file included into the program at the correct point.
+@end enumerate
+
+@item
+Run an @command{awk} program (naturally) over the shell variable's contents to expand
+@samp{@@include} statements. The expanded program is placed in a second
+shell variable.
+
+@item
+Run the expanded program with @command{gawk} and any other original command-line
+arguments that the user supplied (such as the data @value{FN}s).
+@end enumerate
+
+This program uses shell variables extensively; for storing command line arguments,
+the text of the @command{awk} program that will expand the user's program, for the
+user's original program, and for the expanded program. Doing so removes some
+potential problems that might arise were we to use temporary files instead,
+at the cost of making the script somewhat more complicated.
+
+The initial part of the program turns on shell tracing if the first
+argument is @samp{debug}.
+
+The next part loops through all the command-line arguments.
+There are several cases of interest:
+
+@table @code
+@item --
+This ends the arguments to @command{igawk}. Anything else should be passed on
+to the user's @command{awk} program without being evaluated.
+
+@item -W
+This indicates that the next option is specific to @command{gawk}. To make
+argument processing easier, the @option{-W} is appended to the front of the
+remaining arguments and the loop continues. (This is an @command{sh}
+programming trick. Don't worry about it if you are not familiar with
+@command{sh}.)
+
+@item -v@r{,} -F
+These are saved and passed on to @command{gawk}.
+
+@item -f@r{,} --file@r{,} --file=@r{,} -Wfile=
+The @value{FN} is appended to the shell variable @code{program} with an
+@samp{@@include} statement.
+The @command{expr} utility is used to remove the leading option part of the
+argument (e.g., @samp{--file=}).
+(Typical @command{sh} usage would be to use the @command{echo} and @command{sed}
+utilities to do this work. Unfortunately, some versions of @command{echo} evaluate
+escape sequences in their arguments, possibly mangling the program text.
+Using @command{expr} avoids this problem.)
+
+@item --source@r{,} --source=@r{,} -Wsource=
+The source text is appended to @code{program}.
+
+@item --version@r{,} -Wversion
+@command{igawk} prints its version number, runs @samp{gawk --version}
+to get the @command{gawk} version information, and then exits.
+@end table
+
+If none of the @option{-f}, @option{--file}, @option{-Wfile}, @option{--source},
+or @option{-Wsource} arguments are supplied, then the first nonoption argument
+should be the @command{awk} program. If there are no command-line
+arguments left, @command{igawk} prints an error message and exits.
+Otherwise, the first argument is appended to @code{program}.
+In any case, after the arguments have been processed,
+@code{program} contains the complete text of the original @command{awk}
+program.
+
+The program is as follows:
+
+@cindex @code{igawk.sh} program
+@example
+@c file eg/prog/igawk.sh
+#! /bin/sh
+# igawk --- like gawk but do @@include processing
+@c endfile
+@ignore
+@c file eg/prog/igawk.sh
+#
+# Arnold Robbins, arnold@@gnu.org, Public Domain
+# July 1993
+
+@c endfile
+@end ignore
+@c file eg/prog/igawk.sh
+if [ "$1" = debug ]
+then
+ set -x
+ shift
+fi
+
+# A literal newline, so that program text is formmatted correctly
+n='
+'
+
+# Initialize variables to empty
+program=
+opts=
+
+while [ $# -ne 0 ] # loop over arguments
+do
+ case $1 in
+ --) shift; break;;
+
+ -W) shift
+ # The $@{x?'message here'@} construct prints a
+ # diagnostic if $x is the null string
+ set -- -W"$@{@@?'missing operand'@}"
+ continue;;
+
+ -[vF]) opts="$opts $1 '$@{2?'missing operand'@}'"
+ shift;;
+
+ -[vF]*) opts="$opts '$1'" ;;
+
+ -f) program="$program$n@@include $@{2?'missing operand'@}"
+ shift;;
+
+ -f*) f=`expr "$1" : '-f\(.*\)'`
+ program="$program$n@@include $f";;
+
+ -[W-]file=*)
+ f=`expr "$1" : '-.file=\(.*\)'`
+ program="$program$n@@include $f";;
+
+ -[W-]file)
+ program="$program$n@@include $@{2?'missing operand'@}"
+ shift;;
+
+ -[W-]source=*)
+ t=`expr "$1" : '-.source=\(.*\)'`
+ program="$program$n$t";;
+
+ -[W-]source)
+ program="$program$n$@{2?'missing operand'@}"
+ shift;;
+
+ -[W-]version)
+ echo igawk: version 2.0 1>&2
+ gawk --version
+ exit 0 ;;
+
+ -[W-]*) opts="$opts '$1'" ;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if [ -z "$program" ]
+then
+ program=$@{1?'missing program'@}
+ shift
+fi
+
+# At this point, `program' has the program.
+@c endfile
+@end example
+
+The @command{awk} program to process @samp{@@include} directives
+is stored in the shell variable @code{expand_prog}. Doing this keeps
+the shell script readable. The @command{awk} program
+reads through the user's program, one line at a time, using @code{getline}
+(@pxref{Getline}). The input
+@value{FN}s and @samp{@@include} statements are managed using a stack.
+As each @samp{@@include} is encountered, the current @value{FN} is
+``pushed'' onto the stack and the file named in the @samp{@@include}
+directive becomes the current @value{FN}. As each file is finished,
+the stack is ``popped,'' and the previous input file becomes the current
+input file again. The process is started by making the original file
+the first one on the stack.
+
+The @code{pathto} function does the work of finding the full path to
+a file. It simulates @command{gawk}'s behavior when searching the
+@env{AWKPATH} environment variable
+(@pxref{AWKPATH Variable}).
+If a @value{FN} has a @samp{/} in it, no path search is done. Otherwise,
+the @value{FN} is concatenated with the name of each directory in
+the path, and an attempt is made to open the generated @value{FN}.
+The only way to test if a file can be read in @command{awk} is to go
+ahead and try to read it with @code{getline}; this is what @code{pathto}
+does.@footnote{On some very old versions of @command{awk}, the test
+@samp{getline junk < t} can loop forever if the file exists but is empty.
+Caveat emptor.} If the file can be read, it is closed and the @value{FN}
+is returned:
+
+@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
+expand_prog='
+
+function pathto(file, i, t, junk)
+@{
+ if (index(file, "/") != 0)
+ return file
+
+ for (i = 1; i <= ndirs; i++) @{
+ t = (pathlist[i] "/" file)
+@group
+ if ((getline junk < t) > 0) @{
+ # found it
+ close(t)
+ return t
+ @}
+@end group
+ @}
+ return ""
+@}
+@c endfile
+@end example
+
+The main program is contained inside one @code{BEGIN} rule. The first thing it
+does is set up the @code{pathlist} array that @code{pathto} uses. After
+splitting the path on @samp{:}, null elements are replaced with @code{"."},
+which represents the current directory:
+
+@example
+@c file eg/prog/igawk.sh
+BEGIN @{
+ path = ENVIRON["AWKPATH"]
+ ndirs = split(path, pathlist, ":")
+ for (i = 1; i <= ndirs; i++) @{
+ if (pathlist[i] == "")
+ pathlist[i] = "."
+ @}
+@c endfile
+@end example
+
+The stack is initialized with @code{ARGV[1]}, which will be @file{/dev/stdin}.
+The main loop comes next. Input lines are read in succession. Lines that
+do not start with @samp{@@include} are printed verbatim.
+If the line does start with @samp{@@include}, the @value{FN} is in @code{$2}.
+@code{pathto} is called to generate the full path. If it cannot, then we
+print an error message and continue.
+
+The next thing to check is if the file is included already. The
+@code{processed} array is indexed by the full @value{FN} of each included
+file and it tracks this information for us. If the file is
+seen again, a warning message is printed. Otherwise, the new @value{FN} is
+pushed onto the stack and processing continues.
+
+Finally, when @code{getline} encounters the end of the input file, the file
+is closed and the stack is popped. When @code{stackptr} is less than zero,
+the program is done:
+
+@example
+@c file eg/prog/igawk.sh
+ stackptr = 0
+ input[stackptr] = ARGV[1] # ARGV[1] is first file
+
+ for (; stackptr >= 0; stackptr--) @{
+ while ((getline < input[stackptr]) > 0) @{
+ if (tolower($1) != "@@include") @{
+ print
+ continue
+ @}
+ fpath = pathto($2)
+@group
+ if (fpath == "") @{
+ printf("igawk:%s:%d: cannot find %s\n",
+ input[stackptr], FNR, $2) > "/dev/stderr"
+ continue
+ @}
+@end group
+ if (! (fpath in processed)) @{
+ processed[fpath] = input[stackptr]
+ input[++stackptr] = fpath # push onto stack
+ @} else
+ print $2, "included in", input[stackptr],
+ "already included in",
+ processed[fpath] > "/dev/stderr"
+ @}
+ close(input[stackptr])
+ @}
+@}' # close quote ends `expand_prog' variable
+
+processed_program=`gawk -- "$expand_prog" /dev/stdin <<EOF
+$program
+EOF
+`
+@c endfile
+@end example
+
+The shell construct @samp{@var{command} << @var{marker}} is called a @dfn{here document}.
+Everything in the shell script up to the @var{marker} is fed to @var{command} as input.
+The shell processes the contents of the here document for variable and command substitution
+(and possibly other things as well, depending upon the shell).
+
+The shell construct @samp{`@dots{}`} is called @dfn{command substitution}.
+The output of the command between the two backquotes (grave accents) is substituted
+into the command line. It is saved as a single string, even if the results
+contain whitespace.
+
+The expanded program is saved in the variable @code{processed_program}.
+It's done in these steps:
+
+@enumerate
+@item
+Run @command{gawk} with the @samp{@@include}-processing program (the
+value of the @code{expand_prog} shell variable) on standard input.
+
+@item
+Standard input is the contents of the user's program, from the shell variable @code{program}.
+Its contents are fed to @command{gawk} via a here document.
+
+@item
+The results of this processing are saved in the shell variable @code{processed_program} by using command substitution.
+@end enumerate
+
+The last step is to call @command{gawk} with the expanded program,
+along with the original
+options and command-line arguments that the user supplied.
+
+@c this causes more problems than it solves, so leave it out.
+@ignore
+The special file @file{/dev/null} is passed as a @value{DF} to @command{gawk}
+to handle an interesting case. Suppose that the user's program only has
+a @code{BEGIN} rule and there are no @value{DF}s to read.
+The program should exit without reading any @value{DF}s.
+However, suppose that an included library file defines an @code{END}
+rule of its own. In this case, @command{gawk} will hang, reading standard
+input. In order to avoid this, @file{/dev/null} is explicitly added to the
+command-line. Reading from @file{/dev/null} always returns an immediate
+end of file indication.
+
+@c Hmm. Add /dev/null if $# is 0? Still messes up ARGV. Sigh.
+@end ignore
+
+@example
+@c file eg/prog/igawk.sh
+eval gawk $opts -- '"$processed_program"' '"$@@"'
+@c endfile
+@end example
+
+The @command{eval} command is a shell construct that reruns the shell's parsing
+process. This keeps things properly quoted.
+
+This version of @command{igawk} represents my fourth attempt at this program.
+There are four key simplifications that make the program work better:
+
+@itemize @bullet
+@item
+Using @samp{@@include} even for the files named with @option{-f} makes building
+the initial collected @command{awk} program much simpler; all the
+@samp{@@include} processing can be done once.
+
+@item
+Not trying to save the line read with @code{getline}
+in the @code{pathto} function when testing for the
+file's accessibility for use with the main program simplifies things
+considerably.
+@c what problem does this engender though - exercise
+@c answer, reading from "-" or /dev/stdin
+
+@item
+Using a @code{getline} loop in the @code{BEGIN} rule does it all in one
+place. It is not necessary to call out to a separate loop for processing
+nested @samp{@@include} statements.
+
+@item
+Instead of saving the expanded program in a temporary file, putting it in a shell variable
+avoids some potential security problems.
+This has the disadvantage that the script relies upon more features
+of the @command{sh} language, making it harder to follow for those who
+aren't familiar with @command{sh}.
+@end itemize
+
+Also, this program illustrates that it is often worthwhile to combine
+@command{sh} and @command{awk} programming together. You can usually
+accomplish quite a lot, without having to resort to low-level programming
+in C or C++, and it is frequently easier to do certain kinds of string
+and argument manipulation using the shell than it is in @command{awk}.
+
+Finally, @command{igawk} shows that it is not always necessary to add new
+features to a program; they can often be layered on top. With @command{igawk},
+there is no real reason to build @samp{@@include} processing into
+@command{gawk} itself.
+
+@cindex search paths, for source files
+@cindex source files@comma{} search path for
+@cindex files, source@comma{} search path for
+@cindex directories, searching
+As an additional example of this, consider the idea of having two
+files in a directory in the search path:
+
+@table @file
+@item default.awk
+This file contains a set of default library functions, such
+as @code{getopt} and @code{assert}.
+
+@item site.awk
+This file contains library functions that are specific to a site or
+installation; i.e., locally developed functions.
+Having a separate file allows @file{default.awk} to change with
+new @command{gawk} releases, without requiring the system administrator to
+update it each time by adding the local functions.
+@end table
+
+One user
+@c Karl Berry, karl@ileaf.com, 10/95
+suggested that @command{gawk} be modified to automatically read these files
+upon startup. Instead, it would be very simple to modify @command{igawk}
+to do this. Since @command{igawk} can process nested @samp{@@include}
+directives, @file{default.awk} could simply contain @samp{@@include}
+statements for the desired library functions.
+@c ENDOFRANGE libfex
+@c ENDOFRANGE flibex
+@c ENDOFRANGE awkpex
+
+@c Exercise: make this change
+
+@ignore
+@c Try this
+@iftex
+@page
+@headings off
+@majorheading III@ @ @ Appendixes
+Part III provides the appendixes, the Glossary, and two licenses that cover
+the @command{gawk} source code and this @value{DOCUMENT}, respectively.
+It contains the following appendixes:
+
+@itemize @bullet
+@item
+@ref{Language History}.
+
+@item
+@ref{Installation}.
+
+@item
+@ref{Notes}.
+
+@item
+@ref{Basic Concepts}.
+
+@item
+@ref{Glossary}.
+
+@item
+@ref{Copying}.
+
+@item
+@ref{GNU Free Documentation License}.
+@end itemize
+
+@page
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+@end ignore
+
+@node Language History
+@appendix The Evolution of the @command{awk} Language
+
+This @value{DOCUMENT} describes the GNU implementation of @command{awk}, which follows
+the POSIX specification.
+Many long-time @command{awk} users learned @command{awk} programming
+with the original @command{awk} implementation in Version 7 Unix.
+(This implementation was the basis for @command{awk} in Berkeley Unix,
+through 4.3-Reno. Subsequent versions of Berkeley Unix, and systems
+derived from 4.4BSD-Lite, use various versions of @command{gawk}
+for their @command{awk}.)
+This @value{CHAPTER} briefly describes the
+evolution of the @command{awk} language, with cross-references to other parts
+of the @value{DOCUMENT} where you can find more information.
+
+@menu
+* V7/SVR3.1:: The major changes between V7 and System V
+ Release 3.1.
+* SVR4:: Minor changes between System V Releases 3.1
+ and 4.
+* POSIX:: New features from the POSIX standard.
+* BTL:: New features from the Bell Laboratories
+ version of @command{awk}.
+* POSIX/GNU:: The extensions in @command{gawk} not in POSIX
+ @command{awk}.
+* Contributors:: The major contributors to @command{gawk}.
+@end menu
+
+@node V7/SVR3.1
+@appendixsec Major Changes Between V7 and SVR3.1
+@c STARTOFRANGE gawkv
+@cindex @command{awk}, versions of
+@c STARTOFRANGE gawkv1
+@cindex @command{awk}, versions of, changes between V7 and SVR3.1
+
+The @command{awk} language evolved considerably between the release of
+Version 7 Unix (1978) and the new version that was first made generally available in
+System V Release 3.1 (1987). This @value{SECTION} summarizes the changes, with
+cross-references to further details:
+
+@itemize @bullet
+@item
+The requirement for @samp{;} to separate rules on a line
+(@pxref{Statements/Lines}).
+
+@item
+User-defined functions and the @code{return} statement
+(@pxref{User-defined}).
+
+@item
+The @code{delete} statement (@pxref{Delete}).
+
+@item
+The @code{do}-@code{while} statement
+(@pxref{Do Statement}).
+
+@item
+The built-in functions @code{atan2}, @code{cos}, @code{sin}, @code{rand}, and
+@code{srand} (@pxref{Numeric Functions}).
+
+@item
+The built-in functions @code{gsub}, @code{sub}, and @code{match}
+(@pxref{String Functions}).
+
+@item
+The built-in functions @code{close} and @code{system}
+(@pxref{I/O Functions}).
+
+@item
+The @code{ARGC}, @code{ARGV}, @code{FNR}, @code{RLENGTH}, @code{RSTART},
+and @code{SUBSEP} built-in variables (@pxref{Built-in Variables}).
+
+@item
+The conditional expression using the ternary operator @samp{?:}
+(@pxref{Conditional Exp}).
+
+@item
+The exponentiation operator @samp{^}
+(@pxref{Arithmetic Ops}) and its assignment operator
+form @samp{^=} (@pxref{Assignment Ops}).
+
+@item
+C-compatible operator precedence, which breaks some old @command{awk}
+programs (@pxref{Precedence}).
+
+@item
+Regexps as the value of @code{FS}
+(@pxref{Field Separators}) and as the
+third argument to the @code{split} function
+(@pxref{String Functions}).
+
+@item
+Dynamic regexps as operands of the @samp{~} and @samp{!~} operators
+(@pxref{Regexp Usage}).
+
+@item
+The escape sequences @samp{\b}, @samp{\f}, and @samp{\r}
+(@pxref{Escape Sequences}).
+(Some vendors have updated their old versions of @command{awk} to
+recognize @samp{\b}, @samp{\f}, and @samp{\r}, but this is not
+something you can rely on.)
+
+@item
+Redirection of input for the @code{getline} function
+(@pxref{Getline}).
+
+@item
+Multiple @code{BEGIN} and @code{END} rules
+(@pxref{BEGIN/END}).
+
+@item
+Multidimensional arrays
+(@pxref{Multi-dimensional}).
+@end itemize
+@c ENDOFRANGE gawkv1
+
+@node SVR4
+@appendixsec Changes Between SVR3.1 and SVR4
+
+@cindex @command{awk}, versions of, changes between SVR3.1 and SVR4
+The System V Release 4 (1989) version of Unix @command{awk} added these features
+(some of which originated in @command{gawk}):
+
+@itemize @bullet
+@item
+The @code{ENVIRON} variable (@pxref{Built-in Variables}).
+@c gawk and MKS awk
+
+@item
+Multiple @option{-f} options on the command line
+(@pxref{Options}).
+@c MKS awk
+
+@item
+The @option{-v} option for assigning variables before program execution begins
+(@pxref{Options}).
+@c GNU, Bell Laboratories & MKS together
+
+@item
+The @option{--} option for terminating command-line options.
+
+@item
+The @samp{\a}, @samp{\v}, and @samp{\x} escape sequences
+(@pxref{Escape Sequences}).
+@c GNU, for ANSI C compat
+
+@item
+A defined return value for the @code{srand} built-in function
+(@pxref{Numeric Functions}).
+
+@item
+The @code{toupper} and @code{tolower} built-in string functions
+for case translation
+(@pxref{String Functions}).
+
+@item
+A cleaner specification for the @samp{%c} format-control letter in the
+@code{printf} function
+(@pxref{Control Letters}).
+
+@item
+The ability to dynamically pass the field width and precision (@code{"%*.*d"})
+in the argument list of the @code{printf} function
+(@pxref{Control Letters}).
+
+@item
+The use of regexp constants, such as @code{/foo/}, as expressions, where
+they are equivalent to using the matching operator, as in @samp{$0 ~ /foo/}
+(@pxref{Using Constant Regexps}).
+
+@item
+Processing of escape sequences inside command-line variable assignments
+(@pxref{Assignment Options}).
+@end itemize
+
+@node POSIX
+@appendixsec Changes Between SVR4 and POSIX @command{awk}
+@cindex @command{awk}, versions of, changes between SVR4 and POSIX @command{awk}
+@cindex POSIX @command{awk}, changes in @command{awk} versions
+
+The POSIX Command Language and Utilities standard for @command{awk} (1992)
+introduced the following changes into the language:
+
+@itemize @bullet
+@item
+The use of @option{-W} for implementation-specific options
+(@pxref{Options}).
+
+@item
+The use of @code{CONVFMT} for controlling the conversion of numbers
+to strings (@pxref{Conversion}).
+
+@item
+The concept of a numeric string and tighter comparison rules to go
+with it (@pxref{Typing and Comparison}).
+
+@item
+More complete documentation of many of the previously undocumented
+features of the language.
+@end itemize
+
+The following common extensions are not permitted by the POSIX
+standard:
+
+@c IMPORTANT! Keep this list in sync with the one in node Options
+
+@itemize @bullet
+@item
+@code{\x} escape sequences are not recognized
+(@pxref{Escape Sequences}).
+
+@item
+Newlines do not act as whitespace to separate fields when @code{FS} is
+equal to a single space
+(@pxref{Fields}).
+
+@item
+Newlines are not allowed after @samp{?} or @samp{:}
+(@pxref{Conditional Exp}).
+
+@item
+The synonym @code{func} for the keyword @code{function} is not
+recognized (@pxref{Definition Syntax}).
+
+@item
+The operators @samp{**} and @samp{**=} cannot be used in
+place of @samp{^} and @samp{^=} (@pxref{Arithmetic Ops},
+and @ref{Assignment Ops}).
+
+@item
+Specifying @samp{-Ft} on the command line does not set the value
+of @code{FS} to be a single TAB character
+(@pxref{Field Separators}).
+
+@item
+The @code{fflush} built-in function is not supported
+(@pxref{I/O Functions}).
+@end itemize
+@c ENDOFRANGE gawkv
+
+@node BTL
+@appendixsec Extensions in the Bell Laboratories @command{awk}
+
+@cindex @command{awk}, versions of, See Also Bell Laboratories @command{awk}
+@cindex extensions, Bell Laboratories @command{awk}
+@cindex Bell Laboratories @command{awk} extensions
+@cindex Kernighan, Brian
+Brian Kernighan, one of the original designers of Unix @command{awk},
+has made his version available via his home page
+(@pxref{Other Versions}).
+This @value{SECTION} describes extensions in his version of @command{awk} that are
+not in POSIX @command{awk}:
+
+@itemize @bullet
+@item
+The @samp{-mf @var{N}} and @samp{-mr @var{N}} command-line options
+to set the maximum number of fields and the maximum
+record size, respectively
+(@pxref{Options}).
+As a side note, his @command{awk} no longer needs these options;
+it continues to accept them to avoid breaking old programs.
+
+@item
+The @code{fflush} built-in function for flushing buffered output
+(@pxref{I/O Functions}).
+
+@item
+The @samp{**} and @samp{**=} operators
+(@pxref{Arithmetic Ops}
+and
+@ref{Assignment Ops}).
+
+@item
+The use of @code{func} as an abbreviation for @code{function}
+(@pxref{Definition Syntax}).
+
+@ignore
+@item
+The @code{SYMTAB} array, that allows access to @command{awk}'s internal symbol
+table. This feature is not documented, largely because
+it is somewhat shakily implemented. For instance, you cannot access arrays
+or array elements through it.
+@end ignore
+@end itemize
+
+The Bell Laboratories @command{awk} also incorporates the following extensions,
+originally developed for @command{gawk}:
+
+@itemize @bullet
+@item
+The @samp{\x} escape sequence
+(@pxref{Escape Sequences}).
+
+@item
+The @file{/dev/stdin}, @file{/dev/stdout}, and @file{/dev/stderr}
+special files
+(@pxref{Special Files}).
+
+@item
+The ability for @code{FS} and for the third
+argument to @code{split} to be null strings
+(@pxref{Single Character Fields}).
+
+@item
+The @code{nextfile} statement
+(@pxref{Nextfile Statement}).
+
+@item
+The ability to delete all of an array at once with @samp{delete @var{array}}
+(@pxref{Delete}).
+@end itemize
+
+@node POSIX/GNU
+@appendixsec Extensions in @command{gawk} Not in POSIX @command{awk}
+
+@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
+ new ports
+Within each category, be alphabetical.
+@end ignore
+
+@c STARTOFRANGE fripls
+@cindex compatibility mode (@command{gawk}), extensions
+@c STARTOFRANGE exgnot
+@cindex extensions, in @command{gawk}, not in POSIX @command{awk}
+@c STARTOFRANGE posnot
+@cindex POSIX, @command{gawk} extensions not included in
+The GNU implementation, @command{gawk}, adds a large number of features.
+This @value{SECTION} lists them in the order they were added to @command{gawk}.
+They can all be disabled with either the @option{--traditional} or
+@option{--posix} options
+(@pxref{Options}).
+
+Version 2.10 of @command{gawk} introduced the following features:
+
+@itemize @bullet
+@item
+The @env{AWKPATH} environment variable for specifying a path search for
+the @option{-f} command-line option
+(@pxref{Options}).
+
+@item
+The @code{IGNORECASE} variable and its effects
+(@pxref{Case-sensitivity}).
+
+@item
+The @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} and
+@file{/dev/fd/@var{N}} special @value{FN}s
+(@pxref{Special Files}).
+@end itemize
+
+Version 2.13 of @command{gawk} introduced the following features:
+
+@itemize @bullet
+@item
+The @code{FIELDWIDTHS} variable and its effects
+(@pxref{Constant Size}).
+
+@item
+The @code{systime} and @code{strftime} built-in functions for obtaining
+and printing timestamps
+(@pxref{Time Functions}).
+
+@item
+The @option{-W lint} option to provide error and portability checking
+for both the source code and at runtime
+(@pxref{Options}).
+
+@item
+The @option{-W compat} option to turn off the GNU extensions
+(@pxref{Options}).
+
+@item
+The @option{-W posix} option for full POSIX compliance
+(@pxref{Options}).
+@end itemize
+
+Version 2.14 of @command{gawk} introduced the following feature:
+
+@itemize @bullet
+@item
+The @code{next file} statement for skipping to the next @value{DF}
+(@pxref{Nextfile Statement}).
+@end itemize
+
+Version 2.15 of @command{gawk} introduced the following features:
+
+@itemize @bullet
+@item
+The @code{ARGIND} variable, which tracks the movement of @code{FILENAME}
+through @code{ARGV} (@pxref{Built-in Variables}).
+
+@item
+The @code{ERRNO} variable, which contains the system error message when
+@code{getline} returns @minus{}1 or @code{close} fails
+(@pxref{Built-in Variables}).
+
+@item
+The @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid}, and
+@file{/dev/user} @value{FN} interpretation
+(@pxref{Special Files}).
+
+@item
+The ability to delete all of an array at once with @samp{delete @var{array}}
+(@pxref{Delete}).
+
+@item
+The ability to use GNU-style long-named options that start with @option{--}
+(@pxref{Options}).
+
+@item
+The @option{--source} option for mixing command-line and library-file
+source code
+(@pxref{Options}).
+@end itemize
+
+Version 3.0 of @command{gawk} introduced the following features:
+
+@itemize @bullet
+@item
+@code{IGNORECASE} changed, now applying to string comparison as well
+as regexp operations
+(@pxref{Case-sensitivity}).
+
+@item
+The @code{RT} variable that contains the input text that
+matched @code{RS}
+(@pxref{Records}).
+
+@item
+Full support for both POSIX and GNU regexps
+(@pxref{Regexp}).
+
+@item
+The @code{gensub} function for more powerful text manipulation
+(@pxref{String Functions}).
+
+@item
+The @code{strftime} function acquired a default time format,
+allowing it to be called with no arguments
+(@pxref{Time Functions}).
+
+@item
+The ability for @code{FS} and for the third
+argument to @code{split} to be null strings
+(@pxref{Single Character Fields}).
+
+@item
+The ability for @code{RS} to be a regexp
+(@pxref{Records}).
+
+@item
+The @code{next file} statement became @code{nextfile}
+(@pxref{Nextfile Statement}).
+
+@item
+The @option{--lint-old} option to
+warn about constructs that are not available in
+the original Version 7 Unix version of @command{awk}
+(@pxref{V7/SVR3.1}).
+
+@item
+The @option{-m} option and the @code{fflush} function from the
+Bell Laboratories research version of @command{awk}
+(@pxref{Options}; also
+@pxref{I/O Functions}).
+
+@item
+The @option{--re-interval} option to provide interval expressions in regexps
+(@pxref{Regexp Operators}).
+
+@item
+The @option{--traditional} option was added as a better name for
+@option{--compat} (@pxref{Options}).
+
+@item
+The use of GNU Autoconf to control the configuration process
+(@pxref{Quick Installation}).
+
+@item
+Amiga support
+(@pxref{Amiga Installation}).
+
+@end itemize
+
+Version 3.1 of @command{gawk} introduced the following features:
+
+@itemize @bullet
+@item
+The @code{BINMODE} special variable for non-POSIX systems,
+which allows binary I/O for input and/or output files
+(@pxref{PC Using}).
+
+@item
+The @code{LINT} special variable, which dynamically controls lint warnings
+(@pxref{Built-in Variables}).
+
+@item
+The @code{PROCINFO} array for providing process-related information
+(@pxref{Built-in Variables}).
+
+@item
+The @code{TEXTDOMAIN} special variable for setting an application's
+internationalization text domain
+(@pxref{Built-in Variables},
+and
+@ref{Internationalization}).
+
+@item
+The ability to use octal and hexadecimal constants in @command{awk}
+program source code
+(@pxref{Nondecimal-numbers}).
+
+@item
+The @samp{|&} operator for two-way I/O to a coprocess
+(@pxref{Two-way I/O}).
+
+@item
+The @file{/inet} special files for TCP/IP networking using @samp{|&}
+(@pxref{TCP/IP Networking}).
+
+@item
+The optional second argument to @code{close} that allows closing one end
+of a two-way pipe to a coprocess
+(@pxref{Two-way I/O}).
+
+@item
+The optional third argument to the @code{match} function
+for capturing text-matching subexpressions within a regexp
+(@pxref{String Functions}).
+
+@item
+Positional specifiers in @code{printf} formats for
+making translations easier
+(@pxref{Printf Ordering}).
+
+@item
+The @code{asort} and @code{asorti} functions for sorting arrays
+(@pxref{Array Sorting}).
+
+@item
+The @code{bindtextdomain}, @code{dcgettext} and @code{dcngettext} functions
+for internationalization
+(@pxref{Programmer i18n}).
+
+@item
+The @code{extension} built-in function and the ability to add
+new built-in functions dynamically
+(@pxref{Dynamic Extensions}).
+
+@item
+The @code{mktime} built-in function for creating timestamps
+(@pxref{Time Functions}).
+
+@item
+The
+@code{and},
+@code{or},
+@code{xor},
+@code{compl},
+@code{lshift},
+@code{rshift},
+and
+@code{strtonum} built-in
+functions
+(@pxref{Bitwise Functions}).
+
+@item
+@cindex @code{next file} statement
+The support for @samp{next file} as two words was removed completely
+(@pxref{Nextfile Statement}).
+
+@item
+The @option{--dump-variables} option to print a list of all global variables
+(@pxref{Options}).
+
+@item
+The @option{--gen-po} command-line option and the use of a leading
+underscore to mark strings that should be translated
+(@pxref{String Extraction}).
+
+@item
+The @option{--non-decimal-data} option to allow non-decimal
+input data
+(@pxref{Nondecimal Data}).
+
+@item
+The @option{--profile} option and @command{pgawk}, the
+profiling version of @command{gawk}, for producing execution
+profiles of @command{awk} programs
+(@pxref{Profiling}).
+
+@item
+The @option{--enable-portals} configuration option to enable special treatment of
+pathnames that begin with @file{/p} as BSD portals
+(@pxref{Portal Files}).
+
+@item
+The use of GNU Automake to help in standardizing the configuration process
+(@pxref{Quick Installation}).
+
+@item
+The use of GNU @code{gettext} for @command{gawk}'s own message output
+(@pxref{Gawk I18N}).
+
+@item
+BeOS support
+(@pxref{BeOS Installation}).
+
+@item
+Tandem support
+(@pxref{Tandem Installation}).
+
+@item
+The Atari port became officially unsupported
+(@pxref{Atari Installation}).
+
+@item
+The source code now uses new-style function definitions, with
+@command{ansi2knr} to convert the code on systems with old compilers.
+
+@item
+The @option{--disable-lint} configuration option to disable lint checking
+at compile time
+(@pxref{Additional Configuration Options}).
+
+@item
+POSIX compliance for @code{sub} and @code{gsub}
+(@pxref{Gory Details}).
+
+@item
+The @option{--exec} option, for use in CGI scripts.
+(@pxref{Options}).
+
+@item
+The @code{length} function was extended to accept an array argument
+and return the number of elements in the array
+(@pxref{String Functions}).
+
+@end itemize
+
+@c XXX ADD MORE STUFF HERE
+
+@c ENDOFRANGE fripls
+@c ENDOFRANGE exgnot
+@c ENDOFRANGE posnot
+
+@node Contributors
+@appendixsec Major Contributors to @command{gawk}
+@cindex @command{gawk}, list of contributors to
+@quotation
+@i{Always give credit where credit is due.}@*
+Anonymous
+@end quotation
+
+This @value{SECTION} names the major contributors to @command{gawk}
+and/or this @value{DOCUMENT}, in approximate chronological order:
+
+@itemize @bullet
+@item
+@cindex Aho, Alfred
+@cindex Weinberger, Peter
+@cindex Kernighan, Brian
+Dr.@: Alfred V.@: Aho,
+Dr.@: Peter J.@: Weinberger, and
+Dr.@: Brian W.@: Kernighan, all of Bell Laboratories,
+designed and implemented Unix @command{awk},
+from which @command{gawk} gets the majority of its feature set.
+
+@item
+@cindex Rubin, Paul
+Paul Rubin
+did the initial design and implementation in 1986, and wrote
+the first draft (around 40 pages) of this @value{DOCUMENT}.
+
+@item
+@cindex Fenlason, Jay
+Jay Fenlason
+finished the initial implementation.
+
+@item
+@cindex Close, Diane
+Diane Close
+revised the first draft of this @value{DOCUMENT}, bringing it
+to around 90 pages.
+
+@item
+@cindex Stallman, Richard
+Richard Stallman
+helped finish the implementation and the initial draft of this
+@value{DOCUMENT}.
+He is also the founder of the FSF and the GNU project.
+
+@item
+@cindex Woods, John
+John Woods
+contributed parts of the code (mostly fixes) in
+the initial version of @command{gawk}.
+
+@item
+@cindex Trueman, David
+In 1988,
+David Trueman
+took over primary maintenance of @command{gawk},
+making it compatible with ``new'' @command{awk}, and
+greatly improving its performance.
+
+@item
+@cindex Rankin, Pat
+Pat Rankin
+provided the VMS port and its documentation.
+
+@item
+@cindex Kwok, Conrad
+@cindex Garfinkle, Scott
+@cindex Williams, Kent
+Conrad Kwok,
+Scott Garfinkle,
+and
+Kent Williams
+did the initial ports to MS-DOS with various versions of MSC.
+
+@item
+@cindex Peterson, Hal
+Hal Peterson
+provided help in porting @command{gawk} to Cray systems.
+
+@item
+@cindex Rommel, Kai Uwe
+Kai Uwe Rommel
+provided the initial port to OS/2 and its documentation.
+
+@item
+@cindex Jaegermann, Michal
+Michal Jaegermann
+provided the port to Atari systems and its documentation.
+He continues to provide portability checking with DEC Alpha
+systems, and has done a lot of work to make sure @command{gawk}
+works on non-32-bit systems.
+
+@item
+@cindex Fish, Fred
+Fred Fish
+provided the port to Amiga systems and its documentation.
+
+@item
+@cindex Deifik, Scott
+Scott Deifik
+currently maintains the MS-DOS port.
+
+@item
+@cindex Grigera, Juan
+Juan Grigera
+maintains the port to Windows32 systems.
+
+@item
+@cindex Hankerson, Darrel
+Dr.@: Darrel Hankerson
+acts as coordinator for the various ports to different PC platforms
+and creates binary distributions for various PC operating systems.
+He is also instrumental in keeping the documentation up to date for
+the various PC platforms.
+
+@item
+@cindex Zoulas, Christos
+Christos Zoulas
+provided the @code{extension}
+built-in function for dynamically adding new modules.
+
+@item
+@cindex Kahrs, J@"urgen
+J@"urgen Kahrs
+contributed the initial version of the TCP/IP networking
+code and documentation, and motivated the inclusion of the @samp{|&} operator.
+
+@item
+@cindex Davies, Stephen
+Stephen Davies
+provided the port to Tandem systems and its documentation.
+
+@item
+@cindex Brown, Martin
+Martin Brown
+provided the port to BeOS and its documentation.
+
+@item
+@cindex Peters, Arno
+Arno Peters
+did the initial work to convert @command{gawk} to use
+GNU Automake and @code{gettext}.
+
+@item
+@cindex Broder, Alan J.@:
+Alan J.@: Broder
+provided the initial version of the @code{asort} function
+as well as the code for the new optional third argument to the @code{match} function.
+
+@item
+@cindex Buening, Andreas
+Andreas Buening
+updated the @command{gawk} port for OS/2.
+
+@cindex Hasegawa, Isamu
+Isamu Hasegawa,
+of IBM in Japan, contributed support for multibyte characters.
+
+@cindex Benzinger, Michael
+Michael Benzinger contributed the initial code for @code{switch} statements.
+
+@cindex McPhee, Patrick
+Patrick T.J.@: McPhee contributed the code for dynamic loading in Windows32
+environments.
+
+@item
+@cindex Robbins, Arnold
+Arnold Robbins
+has been working on @command{gawk} since 1988, at first
+helping David Trueman, and as the primary maintainer since around 1994.
+@end itemize
+
+@node Installation
+@appendix Installing @command{gawk}
+
+@c last two commas are part of see also
+@cindex operating systems, See Also GNU/Linux, PC operating systems, Unix
+@c STARTOFRANGE gligawk
+@cindex @command{gawk}, installing
+@c STARTOFRANGE ingawk
+@cindex installing @command{gawk}
+This appendix provides instructions for installing @command{gawk} on the
+various platforms that are supported by the developers. The primary
+developer supports GNU/Linux (and Unix), whereas the other ports are
+contributed.
+@xref{Bugs},
+for the electronic mail addresses of the people who did
+the respective ports.
+
+@menu
+* Gawk Distribution:: What is in the @command{gawk} distribution.
+* Unix Installation:: Installing @command{gawk} under various
+ versions of Unix.
+* Non-Unix Installation:: Installation on Other Operating Systems.
+* Unsupported:: Systems whose ports are no longer supported.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available @command{awk}
+ implementations.
+@end menu
+
+@node Gawk Distribution
+@appendixsec The @command{gawk} Distribution
+@cindex source code, @command{gawk}
+
+This @value{SECTION} describes how to get the @command{gawk}
+distribution, how to extract it, and then what is in the various files and
+subdirectories.
+
+@menu
+* Getting:: How to get the distribution.
+* Extracting:: How to extract the distribution.
+* Distribution contents:: What is in the distribution.
+@end menu
+
+@node Getting
+@appendixsubsec Getting the @command{gawk} Distribution
+@cindex @command{gawk}, source code@comma{} obtaining
+There are three ways to get GNU software:
+
+@itemize @bullet
+@item
+Copy it from someone else who already has it.
+
+@cindex FSF (Free Software Foundation)
+@cindex Free Software Foundation (FSF)
+@item
+Order @command{gawk} directly from the Free Software Foundation.
+Software distributions are available for
+Gnu/Linux, Unix, and MS-Windows, in several CD packages.
+Their address is:
+
+@display
+Free Software Foundation
+51 Franklin Street, Fifth Floor
+Boston, MA 02110-1301 USA
+Phone: +1-617-542-5942
+Fax (including Japan): +1-617-542-2652
+Email: @email{gnu@@gnu.org}
+URL: @uref{http://www.gnu.org}
+@end display
+
+@noindent
+Ordering from the FSF directly contributes to the support of the foundation
+and to the production of more free software.
+
+@item
+Retrieve @command{gawk} by using anonymous @command{ftp} to the Internet host
+@code{ftp.gnu.org}, in the directory @file{/gnu/gawk}.
+@end itemize
+
+The GNU software archive is mirrored around the world.
+The up-to-date list of mirror sites is available from
+@uref{http://www.gnu.org/order/ftp.html, the main FSF web site}.
+Try to use one of the mirrors; they
+will be less busy, and you can usually find one closer to your site.
+
+@node Extracting
+@appendixsubsec Extracting the Distribution
+@command{gawk} is distributed as a @code{tar} file compressed with the
+GNU Zip program, @code{gzip}.
+
+Once you have the distribution (for example,
+@file{gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz}),
+use @code{gzip} to expand the
+file and then use @code{tar} to extract it. You can use the following
+pipeline to produce the @command{gawk} distribution:
+
+@example
+# Under System V, add 'o' to the tar options
+gzip -d -c gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz | tar -xvpf -
+@end example
+
+@noindent
+This creates a directory named @file{gawk-@value{VERSION}.@value{PATCHLEVEL}}
+in the current directory.
+
+The distribution @value{FN} is of the form
+@file{gawk-@var{V}.@var{R}.@var{P}.tar.gz}.
+The @var{V} represents the major version of @command{gawk},
+the @var{R} represents the current release of version @var{V}, and
+the @var{P} represents a @dfn{patch level}, meaning that minor bugs have
+been fixed in the release. The current patch level is @value{PATCHLEVEL},
+but when retrieving distributions, you should get the version with the highest
+version, release, and patch level. (Note, however, that patch levels greater than
+or equal to 80 denote ``beta'' or nonproduction software; you might not want
+to retrieve such a version unless you don't mind experimenting.)
+If you are not on a Unix system, you need to make other arrangements
+for getting and extracting the @command{gawk} distribution. You should consult
+a local expert.
+
+@node Distribution contents
+@appendixsubsec Contents of the @command{gawk} Distribution
+@c STARTOFRANGE gawdis
+@cindex @command{gawk}, distribution
+
+The @command{gawk} distribution has a number of C source files,
+documentation files,
+subdirectories, and files related to the configuration process
+(@pxref{Unix Installation}),
+as well as several subdirectories related to different non-Unix
+operating systems:
+
+@table @asis
+@item Various @samp{.c}, @samp{.y}, and @samp{.h} files
+The actual @command{gawk} source code.
+@end table
+
+@table @file
+@item README
+@itemx README_d/README.*
+Descriptive files: @file{README} for @command{gawk} under Unix and the
+rest for the various hardware and software combinations.
+
+@item INSTALL
+A file providing an overview of the configuration and installation process.
+
+@item ChangeLog
+A detailed list of source code changes as bugs are fixed or improvements made.
+
+@item NEWS
+A list of changes to @command{gawk} since the last release or patch.
+
+@item COPYING
+The GNU General Public License.
+
+@item FUTURES
+A brief list of features and changes being contemplated for future
+releases, with some indication of the time frame for the feature, based
+on its difficulty.
+
+@item LIMITATIONS
+A list of those factors that limit @command{gawk}'s performance.
+Most of these depend on the hardware or operating system software and
+are not limits in @command{gawk} itself.
+
+@item POSIX.STD
+A description of one area in which the POSIX standard for @command{awk} is
+incorrect as well as how @command{gawk} handles the problem.
+
+@cindex artificial intelligence@comma{} @command{gawk} and
+@item doc/awkforai.txt
+A short article describing why @command{gawk} is a good language for
+AI (Artificial Intelligence) programming.
+
+@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
+The @command{troff} source for a five-color @command{awk} reference card.
+A modern version of @command{troff} such as GNU @command{troff} (@command{groff}) is
+needed to produce the color version. See the file @file{README.card}
+for instructions if you have an older @command{troff}.
+
+@item doc/gawk.1
+The @command{troff} source for a manual page describing @command{gawk}.
+This is distributed for the convenience of Unix users.
+
+@cindex Texinfo
+@item doc/gawk.texi
+The Texinfo source file for this @value{DOCUMENT}.
+It should be processed with @TeX{} to produce a printed document, and
+with @command{makeinfo} to produce an Info or HTML file.
+
+@item doc/gawk.info
+The generated Info file for this @value{DOCUMENT}.
+
+@item doc/gawkinet.texi
+The Texinfo source file for
+@ifinfo
+@xref{Top}.
+@end ifinfo
+@ifnotinfo
+@cite{TCP/IP Internetworking with @command{gawk}}.
+@end ifnotinfo
+It should be processed with @TeX{} to produce a printed document and
+with @command{makeinfo} to produce an Info or HTML file.
+
+@item doc/gawkinet.info
+The generated Info file for
+@cite{TCP/IP Internetworking with @command{gawk}}.
+
+@item doc/igawk.1
+The @command{troff} source for a manual page describing the @command{igawk}
+program presented in
+@ref{Igawk Program}.
+
+@item doc/Makefile.in
+The input file used during the configuration process to generate the
+actual @file{Makefile} for creating the documentation.
+
+@item Makefile.am
+@itemx */Makefile.am
+Files used by the GNU @command{automake} software for generating
+the @file{Makefile.in} files used by @command{autoconf} and
+@command{configure}.
+
+@item Makefile.in
+@itemx acconfig.h
+@itemx acinclude.m4
+@itemx aclocal.m4
+@itemx configh.in
+@itemx configure.in
+@itemx configure
+@itemx custom.h
+@itemx missing_d/*
+@itemx m4/*
+These files and subdirectories are used when configuring @command{gawk}
+for various Unix systems. They are explained in
+@ref{Unix Installation}.
+
+@item po/*
+The @file{po} library contains message translations.
+
+@item awklib/extract.awk
+@itemx awklib/Makefile.am
+@itemx awklib/Makefile.in
+@itemx awklib/eg/*
+The @file{awklib} directory contains a copy of @file{extract.awk}
+(@pxref{Extract Program}),
+which can be used to extract the sample programs from the Texinfo
+source file for this @value{DOCUMENT}. It also contains a @file{Makefile.in} file, which
+@command{configure} uses to generate a @file{Makefile}.
+@file{Makefile.am} is used by GNU Automake to create @file{Makefile.in}.
+The library functions from
+@ref{Library Functions},
+and the @command{igawk} program from
+@ref{Igawk Program},
+are included as ready-to-use files in the @command{gawk} distribution.
+They are installed as part of the installation process.
+The rest of the programs in this @value{DOCUMENT} are available in appropriate
+subdirectories of @file{awklib/eg}.
+
+@item unsupported/atari/*
+Files needed for building @command{gawk} on an Atari ST
+(@pxref{Atari Installation}, for details).
+
+@item unsupported/tandem/*
+Files needed for building @command{gawk} on a Tandem
+(@pxref{Tandem Installation}, for details).
+
+@item posix/*
+Files needed for building @command{gawk} on POSIX-compliant systems.
+
+@item pc/*
+Files needed for building @command{gawk} under MS-DOS, MS Windows and OS/2
+(@pxref{PC Installation}, for details).
+
+@item vms/*
+Files needed for building @command{gawk} under VMS
+(@pxref{VMS Installation}, for details).
+
+@item test/*
+A test suite for
+@command{gawk}. You can use @samp{make check} from the top-level @command{gawk}
+directory to run your version of @command{gawk} against the test suite.
+If @command{gawk} successfully passes @samp{make check}, then you can
+be confident of a successful port.
+@end table
+@c ENDOFRANGE gawdis
+
+@node Unix Installation
+@appendixsec Compiling and Installing @command{gawk} on Unix
+
+Usually, you can compile and install @command{gawk} by typing only two
+commands. However, if you use an unusual system, you may need
+to configure @command{gawk} for your system yourself.
+
+@menu
+* Quick Installation:: Compiling @command{gawk} under Unix.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+@end menu
+
+@node Quick Installation
+@appendixsubsec Compiling @command{gawk} for Unix
+
+@c @cindex installation, unix
+After you have extracted the @command{gawk} distribution, @command{cd}
+to @file{gawk-@value{VERSION}.@value{PATCHLEVEL}}. Like most GNU software,
+@command{gawk} is configured
+automatically for your Unix system by running the @command{configure} program.
+This program is a Bourne shell script that is generated automatically using
+GNU @command{autoconf}.
+@ifnotinfo
+(The @command{autoconf} software is
+described fully in
+@cite{Autoconf---Generating Automatic Configuration Scripts},
+which is available from the Free Software Foundation.)
+@end ifnotinfo
+@ifinfo
+(The @command{autoconf} software is described fully starting with
+@ref{Top}.)
+@end ifinfo
+
+To configure @command{gawk}, simply run @command{configure}:
+
+@example
+sh ./configure
+@end example
+
+This produces a @file{Makefile} and @file{config.h} tailored to your system.
+The @file{config.h} file describes various facts about your system.
+You might want to edit the @file{Makefile} to
+change the @code{CFLAGS} variable, which controls
+the command-line options that are passed to the C compiler (such as
+optimization levels or compiling for debugging).
+
+Alternatively, you can add your own values for most @command{make}
+variables on the command line, such as @code{CC} and @code{CFLAGS}, when
+running @command{configure}:
+
+@example
+CC=cc CFLAGS=-g sh ./configure
+@end example
+
+@noindent
+See the file @file{INSTALL} in the @command{gawk} distribution for
+all the details.
+
+After you have run @command{configure} and possibly edited the @file{Makefile},
+type:
+
+@example
+make
+@end example
+
+@noindent
+Shortly thereafter, you should have an executable version of @command{gawk}.
+That's all there is to it!
+To verify that @command{gawk} is working properly,
+run @samp{make check}. All of the tests should succeed.
+If these steps do not work, or if any of the tests fail,
+check the files in the @file{README_d} directory to see if you've
+found a known problem. If the failure is not described there,
+please send in a bug report
+(@pxref{Bugs}.)
+
+@node Additional Configuration Options
+@appendixsubsec Additional Configuration Options
+@cindex @command{gawk}, configuring, options
+@cindex configuration options@comma{} @command{gawk}
+
+There are several additional options you may use on the @command{configure}
+command line when compiling @command{gawk} from scratch, including:
+
+@table @code
+@cindex @code{--enable-portals} configuration option
+@cindex configuration option, @code{--enable-portals}
+@item --enable-portals
+Treat pathnames that begin
+with @file{/p} as BSD portal files when doing two-way I/O with
+the @samp{|&} operator
+(@pxref{Portal Files}).
+
+@cindex @code{--enable-switch} configuration option
+@cindex configuration option, @code{--enable-switch}
+@item --enable-switch
+Enable the recognition and execution of C-style @code{switch} statements
+in @command{awk} programs
+(@pxref{Switch Statement}.)
+
+@cindex @code{--disable-lint} configuration option
+@cindex configuration option, @code{--disable-lint}
+@item --disable-lint
+This option disables all lint checking within @code{gawk}. The
+@option{--lint} and @option{--lint-old} options
+(@pxref{Options})
+are accepted, but silently do nothing.
+Similarly, setting the @code{LINT} variable
+(@pxref{User-modified})
+has no effect on the running @command{awk} program.
+
+When used with GCC's automatic dead-code-elimination, this option
+cuts almost 200K bytes off the size of the @command{gawk}
+executable on GNU/Linux x86 systems. Results on other systems and
+with other compilers are likely to vary.
+Using this option may bring you some slight performance improvement.
+
+Using this option will cause some of the tests in the test suite
+to fail. This option may be removed at a later date.
+
+@cindex @code{--disable-nls} configuration option
+@cindex configuration option, @code{--disable-nls}
+@item --disable-nls
+Disable all message-translation facilities.
+This is usually not desirable, but it may bring you some slight performance
+improvement.
+@end table
+
+As of version 3.1.5, the @option{--with-included-gettext} configuration
+option is no longer available, since @command{gawk} expects the
+GNU @code{gettext} library to be installed as an external library.
+
+@node Configuration Philosophy
+@appendixsubsec The Configuration Process
+
+@cindex @command{gawk}, configuring
+This @value{SECTION} is of interest only if you know something about using the
+C language and the Unix operating system.
+
+The source code for @command{gawk} generally attempts to adhere to formal
+standards wherever possible. This means that @command{gawk} uses library
+routines that are specified by the ISO C standard and by the POSIX
+operating system interface standard. When using an ISO C compiler,
+function prototypes are used to help improve the compile-time checking.
+
+Many Unix systems do not support all of either the ISO or the
+POSIX standards. The @file{missing_d} subdirectory in the @command{gawk}
+distribution contains replacement versions of those functions that are
+most likely to be missing.
+
+The @file{config.h} file that @command{configure} creates contains
+definitions that describe features of the particular operating system
+where you are attempting to compile @command{gawk}. The three things
+described by this file are: what header files are available, so that
+they can be correctly included, what (supposedly) standard functions
+are actually available in your C libraries, and various miscellaneous
+facts about your variant of Unix. For example, there may not be an
+@code{st_blksize} element in the @code{stat} structure. In this case,
+@samp{HAVE_ST_BLKSIZE} is undefined.
+
+@cindex @code{custom.h} file
+It is possible for your C compiler to lie to @command{configure}. It may
+do so by not exiting with an error when a library function is not
+available. To get around this, edit the file @file{custom.h}.
+Use an @samp{#ifdef} that is appropriate for your system, and either
+@code{#define} any constants that @command{configure} should have defined but
+didn't, or @code{#undef} any constants that @command{configure} defined and
+should not have. @file{custom.h} is automatically included by
+@file{config.h}.
+
+It is also possible that the @command{configure} program generated by
+@command{autoconf} will not work on your system in some other fashion.
+If you do have a problem, the file @file{configure.in} is the input for
+@command{autoconf}. You may be able to change this file and generate a
+new version of @command{configure} that works on your system
+(@pxref{Bugs},
+for information on how to report problems in configuring @command{gawk}).
+The same mechanism may be used to send in updates to @file{configure.in}
+and/or @file{custom.h}.
+
+@node Non-Unix Installation
+@appendixsec Installation on Other Operating Systems
+
+This @value{SECTION} describes how to install @command{gawk} on
+various non-Unix systems.
+
+@menu
+* Amiga Installation:: Installing @command{gawk} on an Amiga.
+* BeOS Installation:: Installing @command{gawk} on BeOS.
+* PC Installation:: Installing and Compiling @command{gawk} on
+ MS-DOS and OS/2.
+* VMS Installation:: Installing @command{gawk} on VMS.
+@end menu
+
+@node Amiga Installation
+@appendixsubsec Installing @command{gawk} on an Amiga
+
+@cindex amiga
+@cindex installation, amiga
+You can install @command{gawk} on an Amiga system using a Unix emulation
+environment, available via anonymous @command{ftp} from
+@code{ftp.ninemoons.com} in the directory @file{pub/ade/current}.
+This includes a shell based on @command{pdksh}. The primary component of
+this environment is a Unix emulation library, @file{ixemul.lib}.
+@c could really use more background here, who wrote this, etc.
+
+A more complete distribution for the Amiga is available on
+the Geek Gadgets CD-ROM, available from:
+
+@display
+CRONUS
+1840 E. Warner Road #105-265
+Tempe, AZ 85284 USA
+US Toll Free: (800) 804-0833
+Phone: +1-602-491-0442
+FAX: +1-602-491-0048
+Email: @email{info@@ninemoons.com}
+WWW: @uref{http://www.ninemoons.com}
+Anonymous @command{ftp} site: @code{ftp.ninemoons.com}
+@end display
+
+Once you have the distribution, you can configure @command{gawk} simply by
+running @command{configure}:
+
+@example
+configure -v m68k-amigaos
+@end example
+
+Then run @command{make} and you should be all set!
+If these steps do not work, please send in a bug report
+(@pxref{Bugs}).
+
+@node BeOS Installation
+@appendixsubsec Installing @command{gawk} on BeOS
+@cindex BeOS
+@cindex installation, beos
+
+@c From email contributed by Martin Brown, mc@whoever.com
+Since BeOS DR9, all the tools that you should need to build @code{gawk} are
+included with BeOS. The process is basically identical to the Unix process
+of running @command{configure} and then @command{make}. Full instructions are given below.
+
+You can compile @command{gawk} under BeOS by extracting the standard sources
+and running @command{configure}. You @emph{must} specify the location
+prefix for the installation directory. For BeOS DR9 and beyond, the best directory to
+use is @file{/boot/home/config}, so the @command{configure} command is:
+
+@example
+configure --prefix=/boot/home/config
+@end example
+
+This installs the compiled application into @file{/boot/home/config/bin},
+which is already specified in the standard @env{PATH}.
+
+Once the configuration process is completed, you can run @command{make},
+and then @samp{make install}:
+
+@example
+$ make
+@dots{}
+$ make install
+@end example
+
+BeOS uses @command{bash} as its shell; thus, you use @command{gawk} the same way you would
+under Unix.
+If these steps do not work, please send in a bug report
+(@pxref{Bugs}).
+
+@c Rewritten by Scott Deifik <scottd@amgen.com>
+@c and Darrel Hankerson <hankedr@mail.auburn.edu>
+
+@node PC Installation
+@appendixsubsec Installation on PC Operating Systems
+
+@cindex PC operating systems@comma{} @command{gawk} on, installing
+@cindex operating systems, PC@comma{} @command{gawk} on, installing
+This @value{SECTION} covers installation and usage of @command{gawk} on x86 machines
+running DOS, any version of Windows, or OS/2.
+In this @value{SECTION}, the term ``Windows32''
+refers to any of Windows-95/98/ME/NT/2000.
+
+The limitations of DOS (and DOS shells under Windows or OS/2) has meant
+that various ``DOS extenders'' are often used with programs such as
+@command{gawk}. The varying capabilities of Microsoft Windows 3.1
+and Windows32 can add to the confusion. For an overview of the
+considerations, please refer to @file{README_d/README.pc} in the
+distribution.
+
+@menu
+* PC Binary Installation:: Installing a prepared distribution.
+* PC Compiling:: Compiling @command{gawk} for MS-DOS, Windows32,
+ and OS/2.
+* PC Dynamic:: Compiling @command{gawk} for dynamic libraries.
+* PC Using:: Running @command{gawk} on MS-DOS, Windows32 and
+ OS/2.
+* Cygwin:: Building and running @command{gawk} for
+ Cygwin.
+@end menu
+
+@node PC Binary Installation
+@appendixsubsubsec Installing a Prepared Distribution for PC Systems
+
+If you have received a binary distribution prepared by the DOS
+maintainers, then @command{gawk} and the necessary support files appear
+under the @file{gnu} directory, with executables in @file{gnu/bin},
+libraries in @file{gnu/lib/awk}, and manual pages under @file{gnu/man}.
+This is designed for easy installation to a @file{/gnu} directory on your
+drive---however, the files can be installed anywhere provided @env{AWKPATH} is
+set properly. Regardless of the installation directory, the first line of
+@file{igawk.cmd} and @file{igawk.bat} (in @file{gnu/bin}) may need to be
+edited.
+
+The binary distribution contains a separate file describing the
+contents. In particular, it may include more than one version of the
+@command{gawk} executable.
+
+OS/2 (32 bit, EMX) binary distributions are prepared for the @file{/usr}
+directory of your preferred drive. Set @env{UNIXROOT} to your installation
+drive (e.g., @samp{e:}) if you want to install @command{gawk} onto another drive
+than the hardcoded default @samp{c:}. Executables appear in @file{/usr/bin},
+libraries under @file{/usr/share/awk}, manual pages under @file{/usr/man},
+Texinfo documentation under @file{/usr/info} and NLS files under @file{/usr/share/locale}.
+If you already have a file @file{/usr/info/dir} from another package
+@emph{do not overwrite it!} Instead enter the following commands at your prompt
+(replace @samp{x:} by your installation drive):
+
+@example
+install-info --info-dir=x:/usr/info x:/usr/info/gawk.info
+install-info --info-dir=x:/usr/info x:/usr/info/gawkinet.info
+@end example
+
+However, the files can be installed anywhere provided @env{AWKPATH} is
+set properly.
+
+The binary distribution may contain a separate file containing additional
+or more detailed installation instructions.
+
+@node PC Compiling
+@appendixsubsubsec Compiling @command{gawk} for PC Operating Systems
+
+@command{gawk} can be compiled for MS-DOS, Windows32, and OS/2 using the GNU
+development tools from DJ Delorie (DJGPP; MS-DOS only) or Eberhard
+Mattes (EMX; MS-DOS, Windows32 and OS/2). Microsoft Visual C/C++ can be used
+to build a Windows32 version, and Microsoft C/C++ can be
+used to build 16-bit versions for MS-DOS and OS/2.
+@c FIXME:
+(As of @command{gawk} 3.1.2, the MSC version doesn't work. However,
+the maintainer is working on fixing it.)
+The file
+@file{README_d/README.pc} in the @command{gawk} distribution contains
+additional notes, and @file{pc/Makefile} contains important information on
+compilation options.
+
+To build @command{gawk} for MS-DOS, Windows32, and OS/2 (16 bit only; for 32 bit
+(EMX) you can use the @command{configure} script and skip the following paragraphs;
+for details see below), copy the files in the @file{pc} directory (@emph{except}
+for @file{ChangeLog}) to the directory with the rest of the @command{gawk}
+sources. The @file{Makefile} contains a configuration section with comments and
+may need to be edited in order to work with your @command{make} utility.
+
+The @file{Makefile} contains a number of targets for building various MS-DOS,
+Windows32, and OS/2 versions. A list of targets is printed if the @command{make}
+command is given without a target. As an example, to build @command{gawk}
+using the DJGPP tools, enter @samp{make djgpp}.
+(The DJGPP tools may be found at
+@uref{ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/}.)
+
+Using @command{make} to run the standard tests and to install @command{gawk}
+requires additional Unix-like tools, including @command{sh}, @command{sed}, and
+@command{cp}. In order to run the tests, the @file{test/*.ok} files may need to
+be converted so that they have the usual DOS-style end-of-line markers. Most
+of the tests work properly with Stewartson's shell along with the
+companion utilities or appropriate GNU utilities. However, some editing of
+@file{test/Makefile} is required. It is recommended that you copy the file
+@file{pc/Makefile.tst} over the file @file{test/Makefile} as a
+replacement. Details can be found in @file{README_d/README.pc}
+and in the file @file{pc/Makefile.tst}.
+
+The 32 bit EMX version of @command{gawk} works ``out of the box'' under OS/2.
+In principle, it is possible to compile @command{gawk} the following way:
+
+@example
+$ ./configure
+$ make
+@end example
+
+This is not recommended, though. To get an OMF executable you should
+use the following commands at your @command{sh} prompt:
+
+@example
+$ CPPFLAGS="-D__ST_MT_ERRNO__"
+$ export CPPFLAGS
+$ CFLAGS="-O2 -Zomf -Zmt"
+$ export CFLAGS
+$ LDFLAGS="-s -Zcrtdll -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x6000"
+$ export LDFLAGS
+$ RANLIB="echo"
+$ export RANLIB
+$ ./configure --prefix=c:/usr --without-included-gettext
+$ make AR=emxomfar
+@end example
+
+These are just suggestions. You may use any other set of (self-consistent)
+environment variables and compiler flags.
+
+To get an FHS-compliant file hierarchy it is recommended to use the additional
+@command{configure} options @option{--infodir=c:/usr/share/info}, @option{--mandir=c:/usr/share/man}
+and @option{--libexecdir=c:/usr/lib}.
+
+@ignore
+The internal @code{gettext} library tends to be problematic. It is therefore recommended
+to use either an external one (@option{--without-included-gettext}) or to disable
+NLS entirely (@option{--disable-nls}).
+@end ignore
+
+If you use GCC 2.95 it is recommended to use also:
+
+@example
+$ LIBS="-lgcc"
+$ export LIBS
+@end example
+
+You can also get an @code{a.out} executable if you prefer:
+
+@example
+$ CPPFLAGS="-D__ST_MT_ERRNO__"
+$ export CPPFLAGS
+$ CFLAGS="-O2 -Zmt"
+$ export CFLAGS
+$ LDFLAGS="-s -Zstack 0x6000"
+$ LIBS="-lgcc"
+$ unset RANLIB
+@c $ ./configure --prefix=c:/usr --without-included-gettext
+$ ./configure --prefix=c:/usr
+$ make
+@end example
+
+@quotation NOTE
+Versions later than GCC 2.95, i.e., GCC 3.x using the Innotek libc were not tested.
+@end quotation
+
+@quotation NOTE
+Even if the compiled @command{gawk.exe} (@code{a.out}) executable
+contains a DOS header, it does @emph{not} work under DOS. To compile an executable
+that runs under DOS, @code{"-DPIPES_SIMULATED"} must be added to @env{CPPFLAGS}.
+But then some nonstandard extensions of @command{gawk} (e.g., @samp{|&}) do not work!
+@end quotation
+
+After compilation the internal tests can be performed. Enter
+@samp{make check CMP="diff -a"} at your command prompt. All tests
+except for the @code{pid} test are expected to work properly.
+The @code{pid} test fails because child processes are not started by
+@code{fork()}.
+
+@samp{make install} works as expected.
+
+@quotation NOTE
+Most OS/2 ports of GNU @command{make} are not able to handle
+the Makefiles of this package. If you encounter any problems with @command{make}
+try GNU Make 3.79.1 or later versions. You should find the latest
+version on @uref{http://www.unixos2.org/sw/pub/binary/make/} or on
+@uref{ftp://hobbes.nmsu.edu/pub/os2/}.
+@end quotation
+
+@node PC Dynamic
+@appendixsubsubsec Compiling @command{gawk} For Dynamic Libraries
+
+@c From README_d/README.pcdynamic
+@c 11 June 2003
+
+To compile @command{gawk} with dynamic extension support,
+uncomment the definitions of @code{DYN_FLAGS}, @code{DYN_EXP},
+@code{DYN_OBJ}, and @code{DYN_MAKEXP} in the configuration section of
+the @file{Makefile}. There are two definitions for @code{DYN_MAKEXP}:
+pick the one that matches your target.
+
+To build some of the example extension libraries, @command{cd} to the
+extension directory and copy @file{Makefile.pc} to @file{Makefile}. You
+can then build using the same two targets. To run the example
+@command{awk} scripts, you'll need to either change the call to
+the @code{extension} function to match the name of the library (for
+instance, change @code{"./ordchr.so"} to @code{"ordchr.dll"} or simply
+@code{"ordchr"}), or rename the library to match the call (for instance,
+rename @file{ordchr.dll} to @file{ordchr.so}).
+
+If you build @command{gawk.exe} with one compiler but want to build
+an extension library with the other, you need to copy the import
+library. Visual C uses a library called @file{gawk.lib}, while MinGW uses
+a library called @file{libgawk.a}. These files are equivalent and will
+interoperate if you give them the correct name. The resulting shared
+libraries are also interoperable.
+
+To create your own extension library, you can use the examples as models,
+but you're essentially on your own. Post to @code{comp.lang.awk} or
+send electronic mail to @email{ptjm@@interlog.com} if you have problems getting
+started. If you need to access functions or variables which are not
+exported by @command{gawk.exe}, add them to @file{gawkw32.def} and
+rebuild. You should also add @code{ATTRIBUTE_EXPORTED} to the declaration
+in @file{awk.h} of any variables you add to @file{gawkw32.def}.
+
+Note that extension libraries have the name of the @command{awk}
+executable embedded in them at link time, so they will work only
+with @command{gawk.exe}. In particular, they won't work if you
+rename @command{gawk.exe} to @command{awk.exe} or if you try to use
+@command{pgawk.exe}. You can perform profiling by temporarily renaming
+@command{pgawk.exe} to @command{gawk.exe}. You can resolve this problem
+by changing the program name in the definition of @code{DYN_MAKEXP}
+for your compiler.
+
+On Windows32, libraries are sought first in the current directory, then in
+the directory containing @command{gawk.exe}, and finally through the
+@env{PATH} environment variable.
+
+@node PC Using
+@appendixsubsubsec Using @command{gawk} on PC Operating Systems
+@c STARTOFRANGE opgawx
+@cindex operating systems, PC, @command{gawk} on
+@c STARTOFRANGE pcgawon
+@cindex PC operating systems, @command{gawk} on
+
+With the exception of the Cygwin environment,
+the @samp{|&} operator and TCP/IP networking
+(@pxref{TCP/IP Networking})
+are not supported for MS-DOS or MS-Windows. EMX (OS/2 only) does support
+at least the @samp{|&} operator.
+
+@cindex search paths
+@cindex @command{gawk}, OS/2 version of
+@cindex @command{gawk}, MS-DOS version of
+@cindex @code{;} (semicolon), @code{AWKPATH} variable and
+@cindex semicolon (@code{;}), @code{AWKPATH} variable and
+@cindex @code{AWKPATH} environment variable
+The OS/2 and MS-DOS versions of @command{gawk} search for program files as
+described in @ref{AWKPATH Variable}.
+However, semicolons (rather than colons) separate elements
+in the @env{AWKPATH} variable. If @env{AWKPATH} is not set or is empty,
+then the default search path for OS/2 (16 bit) and MS-DOS versions is
+@code{@w{".;c:/lib/awk;c:/gnu/lib/awk"}}.
+
+The search path for OS/2 (32 bit, EMX) is determined by the prefix directory
+(most likely @file{/usr} or @file{c:/usr}) that has been specified as an option of
+the @command{configure} script like it is the case for the Unix versions.
+If @file{c:/usr} is the prefix directory then the default search path contains @file{.}
+and @file{c:/usr/share/awk}.
+Additionally, to support binary distributions of @command{gawk} for OS/2
+systems whose drive @samp{c:} might not support long file names or might not exist
+at all, there is a special environment variable. If @env{UNIXROOT} specifies
+a drive then this specific drive is also searched for program files.
+E.g., if @env{UNIXROOT} is set to @file{e:} the complete default search path is
+@code{@w{".;c:/usr/share/awk;e:/usr/share/awk"}}.
+
+An @command{sh}-like shell (as opposed to @command{command.com} under MS-DOS
+or @command{cmd.exe} under OS/2) may be useful for @command{awk} programming.
+Ian Stewartson has written an excellent shell for MS-DOS and OS/2,
+Daisuke Aoyama has ported GNU @command{bash} to MS-DOS using the DJGPP tools,
+and several shells are available for OS/2, including @command{ksh}. The file
+@file{README_d/README.pc} in the @command{gawk} distribution contains
+information on these shells. Users of Stewartson's shell on DOS should
+examine its documentation for handling command lines; in particular,
+the setting for @command{gawk} in the shell configuration may need to be
+changed and the @code{ignoretype} option may also be of interest.
+
+@cindex differences in @command{awk} and @command{gawk}, @code{BINMODE} variable
+@cindex @code{BINMODE} variable
+Under OS/2 and DOS, @command{gawk} (and many other text programs) silently
+translate end-of-line @code{"\r\n"} to @code{"\n"} on input and @code{"\n"}
+to @code{"\r\n"} on output. A special @code{BINMODE} variable allows
+control over these translations and is interpreted as follows:
+
+@itemize @bullet
+@item
+If @code{BINMODE} is @samp{"r"}, or
+@code{(BINMODE & 1)} is nonzero, then
+binary mode is set on read (i.e., no translations on reads).
+
+@item
+If @code{BINMODE} is @code{"w"}, or
+@code{(BINMODE & 2)} is nonzero, then
+binary mode is set on write (i.e., no translations on writes).
+
+@item
+If @code{BINMODE} is @code{"rw"} or @code{"wr"},
+binary mode is set for both read and write
+(same as @code{(BINMODE & 3)}).
+
+@item
+@code{BINMODE=@var{non-null-string}} is
+the same as @samp{BINMODE=3} (i.e., no translations on
+reads or writes). However, @command{gawk} issues a warning
+message if the string is not one of @code{"rw"} or @code{"wr"}.
+@end itemize
+
+@noindent
+The modes for standard input and standard output are set one time
+only (after the
+command line is read, but before processing any of the @command{awk} program).
+Setting @code{BINMODE} for standard input or
+standard output is accomplished by using an
+appropriate @samp{-v BINMODE=@var{N}} option on the command line.
+@code{BINMODE} is set at the time a file or pipe is opened and cannot be
+changed mid-stream.
+
+The name @code{BINMODE} was chosen to match @command{mawk}
+(@pxref{Other Versions}).
+Both @command{mawk} and @command{gawk} handle @code{BINMODE} similarly; however,
+@command{mawk} adds a @samp{-W BINMODE=@var{N}} option and an environment
+variable that can set @code{BINMODE}, @code{RS}, and @code{ORS}. The
+files @file{binmode[1-3].awk} (under @file{gnu/lib/awk} in some of the
+prepared distributions) have been chosen to match @command{mawk}'s @samp{-W
+BINMODE=@var{N}} option. These can be changed or discarded; in particular,
+the setting of @code{RS} giving the fewest ``surprises'' is open to debate.
+@command{mawk} uses @samp{RS = "\r\n"} if binary mode is set on read, which is
+appropriate for files with the DOS-style end-of-line.
+
+To illustrate, the following examples set binary mode on writes for standard
+output and other files, and set @code{ORS} as the ``usual'' DOS-style
+end-of-line:
+
+@example
+gawk -v BINMODE=2 -v ORS="\r\n" @dots{}
+@end example
+
+@noindent
+or:
+
+@example
+gawk -v BINMODE=w -f binmode2.awk @dots{}
+@end example
+
+@noindent
+These give the same result as the @samp{-W BINMODE=2} option in
+@command{mawk}.
+The following changes the record separator to @code{"\r\n"} and sets binary
+mode on reads, but does not affect the mode on standard input:
+
+@example
+gawk -v RS="\r\n" --source "BEGIN @{ BINMODE = 1 @}" @dots{}
+@end example
+
+@noindent
+or:
+
+@example
+gawk -f binmode1.awk @dots{}
+@end example
+
+@noindent
+With proper quoting, in the first example the setting of @code{RS} can be
+moved into the @code{BEGIN} rule.
+
+@node Cygwin
+@appendixsubsubsec Using @command{gawk} In The Cygwin Environment
+
+@command{gawk} can be used ``out of the box'' under Windows if you are
+using the Cygwin environment.@footnote{@uref{http://www.cygwin.com}}
+This environment provides an excellent simulation of Unix, using the
+GNU tools, such as @command{bash}, the GNU Compiler Collection (GCC),
+GNU Make, and other GNU tools. Compilation and installation for Cygwin
+is the same as for a Unix system:
+
+@example
+tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+cd gawk-@value{VERSION}.@value{PATCHLEVEL}
+./configure
+make
+@end example
+
+When compared to GNU/Linux on the same system, the @samp{configure}
+step on Cygwin takes considerably longer. However, it does finish,
+and then the @samp{make} proceeds as usual.
+
+@quotation NOTE
+The @samp{|&} operator and TCP/IP networking
+(@pxref{TCP/IP Networking})
+are fully supported in the Cygwin environment. This is not true
+for any other environment for MS-DOS or MS-Windows.
+@end quotation
+
+@node VMS Installation
+@appendixsubsec How to Compile and Install @command{gawk} on VMS
+
+@c based on material from Pat Rankin <rankin@eql.caltech.edu>
+@c now rankin@pactechdata.com
+
+@cindex installation, vms
+This @value{SUBSECTION} describes how to compile and install @command{gawk} under VMS.
+
+@menu
+* VMS Compilation:: How to compile @command{gawk} under VMS.
+* VMS Installation Details:: How to install @command{gawk} under VMS.
+* VMS Running:: How to run @command{gawk} under VMS.
+* VMS POSIX:: Alternate instructions for VMS POSIX.
+@end menu
+
+@node VMS Compilation
+@appendixsubsubsec Compiling @command{gawk} on VMS
+
+To compile @command{gawk} under VMS, there is a @code{DCL} command procedure that
+issues all the necessary @code{CC} and @code{LINK} commands. There is
+also a @file{Makefile} for use with the @code{MMS} utility. From the source
+directory, use either:
+
+@example
+$ @@[.VMS]VMSBUILD.COM
+@end example
+
+@noindent
+or:
+
+@example
+$ MMS/DESCRIPTION=[.VMS]DESCRIP.MMS GAWK
+@end example
+
+Depending upon which C compiler you are using, follow one of the sets
+of instructions in this table:
+
+@table @asis
+@item VAX C V3.x
+Use either @file{vmsbuild.com} or @file{descrip.mms} as is. These use
+@code{CC/OPTIMIZE=NOLINE}, which is essential for Version 3.0.
+
+@item VAX C V2.x
+You must have Version 2.3 or 2.4; older ones won't work. Edit either
+@file{vmsbuild.com} or @file{descrip.mms} according to the comments in them.
+For @file{vmsbuild.com}, this just entails removing two @samp{!} delimiters.
+Also edit @file{config.h} (which is a copy of file @file{[.config]vms-conf.h})
+and comment out or delete the two lines @samp{#define __STDC__ 0} and
+@samp{#define VAXC_BUILTINS} near the end.
+
+@item GNU C
+Edit @file{vmsbuild.com} or @file{descrip.mms}; the changes are different
+from those for VAX C V2.x but equally straightforward. No changes to
+@file{config.h} are needed.
+
+@item DEC C
+Edit @file{vmsbuild.com} or @file{descrip.mms} according to their comments.
+No changes to @file{config.h} are needed.
+@end table
+
+@command{gawk} has been tested under VAX/VMS 5.5-1 using VAX C V3.2, and
+GNU C 1.40 and 2.3. It should work without modifications for VMS V4.6 and up.
+
+@node VMS Installation Details
+@appendixsubsubsec Installing @command{gawk} on VMS
+
+To install @command{gawk}, all you need is a ``foreign'' command, which is
+a @code{DCL} symbol whose value begins with a dollar sign. For example:
+
+@example
+$ GAWK :== $disk1:[gnubin]GAWK
+@end example
+
+@noindent
+Substitute the actual location of @command{gawk.exe} for
+@samp{$disk1:[gnubin]}. The symbol should be placed in the
+@file{login.com} of any user who wants to run @command{gawk},
+so that it is defined every time the user logs on.
+Alternatively, the symbol may be placed in the system-wide
+@file{sylogin.com} procedure, which allows all users
+to run @command{gawk}.
+
+Optionally, the help entry can be loaded into a VMS help library:
+
+@example
+$ LIBRARY/HELP SYS$HELP:HELPLIB [.VMS]GAWK.HLP
+@end example
+
+@noindent
+(You may want to substitute a site-specific help library rather than
+the standard VMS library @samp{HELPLIB}.) After loading the help text,
+the command:
+
+@example
+$ HELP GAWK
+@end example
+
+@noindent
+provides information about both the @command{gawk} implementation and the
+@command{awk} programming language.
+
+The logical name @samp{AWK_LIBRARY} can designate a default location
+for @command{awk} program files. For the @option{-f} option, if the specified
+@value{FN} has no device or directory path information in it, @command{gawk}
+looks in the current directory first, then in the directory specified
+by the translation of @samp{AWK_LIBRARY} if the file is not found.
+If, after searching in both directories, the file still is not found,
+@command{gawk} appends the suffix @samp{.awk} to the filename and retries
+the file search. If @samp{AWK_LIBRARY} is not defined, that
+portion of the file search fails benignly.
+
+@node VMS Running
+@appendixsubsubsec Running @command{gawk} on VMS
+
+Command-line parsing and quoting conventions are significantly different
+on VMS, so examples in this @value{DOCUMENT} or from other sources often need minor
+changes. They @emph{are} minor though, and all @command{awk} programs
+should run correctly.
+
+Here are a couple of trivial tests:
+
+@example
+$ gawk -- "BEGIN @{print ""Hello, World!""@}"
+$ gawk -"W" version
+! could also be -"W version" or "-W version"
+@end example
+
+@noindent
+Note that uppercase and mixed-case text must be quoted.
+
+The VMS port of @command{gawk} includes a @code{DCL}-style interface in addition
+to the original shell-style interface (see the help entry for details).
+One side effect of dual command-line parsing is that if there is only a
+single parameter (as in the quoted string program above), the command
+becomes ambiguous. To work around this, the normally optional @option{--}
+flag is required to force Unix style rather than @code{DCL} parsing. If any
+other dash-type options (or multiple parameters such as @value{DF}s to
+process) are present, there is no ambiguity and @option{--} can be omitted.
+
+@c @cindex directory search
+@c @cindex path, search
+@cindex search paths
+@cindex search paths, for source files
+The default search path, when looking for @command{awk} program files specified
+by the @option{-f} option, is @code{"SYS$DISK:[],AWK_LIBRARY:"}. The logical
+name @samp{AWKPATH} can be used to override this default. The format
+of @samp{AWKPATH} is a comma-separated list of directory specifications.
+When defining it, the value should be quoted so that it retains a single
+translation and not a multitranslation @code{RMS} searchlist.
+
+@node VMS POSIX
+@appendixsubsubsec Building and Using @command{gawk} on VMS POSIX
+
+Ignore the instructions above, although @file{vms/gawk.hlp} should still
+be made available in a help library. The source tree should be unpacked
+into a container file subsystem rather than into the ordinary VMS filesystem.
+Make sure that the two scripts, @file{configure} and
+@file{vms/posix-cc.sh}, are executable; use @samp{chmod +x} on them if
+necessary. Then execute the following two commands:
+
+@example
+psx> CC=vms/posix-cc.sh configure
+psx> make CC=c89 gawk
+@end example
+
+@noindent
+The first command constructs files @file{config.h} and @file{Makefile} out
+of templates, using a script to make the C compiler fit @command{configure}'s
+expectations. The second command compiles and links @command{gawk} using
+the C compiler directly; ignore any warnings from @command{make} about being
+unable to redefine @code{CC}. @command{configure} takes a very long
+time to execute, but at least it provides incremental feedback as it runs.
+
+This has been tested with VAX/VMS V6.2, VMS POSIX V2.0, and DEC C V5.2.
+
+Once built, @command{gawk} works like any other shell utility. Unlike
+the normal VMS port of @command{gawk}, no special command-line manipulation is
+needed in the VMS POSIX environment.
+
+@node Unsupported
+@appendixsec Unsupported Operating System Ports
+
+This sections describes systems for which
+the @command{gawk} port is no longer supported.
+
+@menu
+* Atari Installation:: Installing @command{gawk} on the Atari ST.
+* Tandem Installation:: Installing @command{gawk} on a Tandem.
+@end menu
+
+@node Atari Installation
+@appendixsubsec Installing @command{gawk} on the Atari ST
+
+The Atari port is no longer supported. It is
+included for those who might want to use it but it is no longer being
+actively maintained.
+
+@c based on material from Michal Jaegermann <michal@gortel.phys.ualberta.ca>
+@cindex atari
+@cindex installation, atari
+There are no substantial differences when installing @command{gawk} on
+various Atari models. Compiled @command{gawk} executables do not require
+a large amount of memory with most @command{awk} programs, and should run on all
+Motorola processor-based models (called further ST, even if that is not
+exactly right).
+
+In order to use @command{gawk}, you need to have a shell, either text or
+graphics, that does not map all the characters of a command line to
+uppercase. Maintaining case distinction in option flags is very
+important (@pxref{Options}).
+These days this is the default and it may only be a problem for some
+very old machines. If your system does not preserve the case of option
+flags, you need to upgrade your tools. Support for I/O
+redirection is necessary to make it easy to import @command{awk} programs
+from other environments. Pipes are nice to have but not vital.
+
+@menu
+* Atari Compiling:: Compiling @command{gawk} on Atari.
+* Atari Using:: Running @command{gawk} on Atari.
+@end menu
+
+@node Atari Compiling
+@appendixsubsubsec Compiling @command{gawk} on the Atari ST
+
+A proper compilation of @command{gawk} sources when @code{sizeof(int)}
+differs from @code{sizeof(void *)} requires an ISO C compiler. An initial
+port was done with @command{gcc}. You may actually prefer executables
+where @code{int}s are four bytes wide but the other variant works as well.
+
+You may need quite a bit of memory when trying to recompile the @command{gawk}
+sources, as some source files (@file{regex.c} in particular) are quite
+big. If you run out of memory compiling such a file, try reducing the
+optimization level for this particular file, which may help.
+
+@cindex Linux
+@cindex GNU/Linux
+With a reasonable shell (@command{bash} will do), you have a pretty good chance
+that the @command{configure} utility will succeed, and in particular if
+you run GNU/Linux, MiNT or a similar operating system. Otherwise
+sample versions of @file{config.h} and @file{Makefile.st} are given in the
+@file{atari} subdirectory and can be edited and copied to the
+corresponding files in the main source directory. Even if
+@command{configure} produces something, it might be advisable to compare
+its results with the sample versions and possibly make adjustments.
+
+Some @command{gawk} source code fragments depend on a preprocessor define
+@samp{atarist}. This basically assumes the TOS environment with @command{gcc}.
+Modify these sections as appropriate if they are not right for your
+environment. Also see the remarks about @env{AWKPATH} and @code{envsep} in
+@ref{Atari Using}.
+
+As shipped, the sample @file{config.h} claims that the @code{system}
+function is missing from the libraries, which is not true, and an
+alternative implementation of this function is provided in
+@file{unsupported/atari/system.c}.
+Depending upon your particular combination of
+shell and operating system, you might want to change the file to indicate
+that @code{system} is available.
+
+@node Atari Using
+@appendixsubsubsec Running @command{gawk} on the Atari ST
+
+An executable version of @command{gawk} should be placed, as usual,
+anywhere in your @env{PATH} where your shell can find it.
+
+While executing, the Atari version of @command{gawk} creates a number of temporary files. When
+using @command{gcc} libraries for TOS, @command{gawk} looks for either of
+the environment variables, @env{TEMP} or @env{TMPDIR}, in that order.
+If either one is found, its value is assumed to be a directory for
+temporary files. This directory must exist, and if you can spare the
+memory, it is a good idea to put it on a RAM drive. If neither
+@env{TEMP} nor @env{TMPDIR} are found, then @command{gawk} uses the
+current directory for its temporary files.
+
+The ST version of @command{gawk} searches for its program files, as described in
+@ref{AWKPATH Variable}.
+The default value for the @env{AWKPATH} variable is taken from
+@code{DEFPATH} defined in @file{Makefile}. The sample @command{gcc}/TOS
+@file{Makefile} for the ST in the distribution sets @code{DEFPATH} to
+@code{@w{".,c:\lib\awk,c:\gnu\lib\awk"}}. The search path can be
+modified by explicitly setting @env{AWKPATH} to whatever you want.
+Note that colons cannot be used on the ST to separate elements in the
+@env{AWKPATH} variable, since they have another reserved meaning.
+Instead, you must use a comma to separate elements in the path. When
+recompiling, the separating character can be modified by initializing
+the @code{envsep} variable in @file{unsupported/atari/gawkmisc.atr} to another
+value.
+
+Although @command{awk} allows great flexibility in doing I/O redirections
+from within a program, this facility should be used with care on the ST
+running under TOS. In some circumstances, the OS routines for file-handle
+pool processing lose track of certain events, causing the
+computer to crash and requiring a reboot. Often a warm reboot is
+sufficient. Fortunately, this happens infrequently and in rather
+esoteric situations. In particular, avoid having one part of an
+@command{awk} program using @code{print} statements explicitly redirected
+to @file{/dev/stdout}, while other @code{print} statements use the
+default standard output, and a calling shell has redirected standard
+output to a file.
+@c 10/2000: Is this still true, now that gawk does /dev/stdout internally?
+
+When @command{gawk} is compiled with the ST version of @command{gcc} and its
+usual libraries, it accepts both @samp{/} and @samp{\} as path separators.
+While this is convenient, it should be remembered that this removes one
+technically valid character (@samp{/}) from your @value{FN}.
+It may also create problems for external programs called via the @code{system}
+function, which may not support this convention. Whenever it is possible
+that a file created by @command{gawk} will be used by some other program,
+use only backslashes. Also remember that in @command{awk}, backslashes in
+strings have to be doubled in order to get literal backslashes
+(@pxref{Escape Sequences}).
+
+@node Tandem Installation
+@appendixsubsec Installing @command{gawk} on a Tandem
+@cindex tandem
+@cindex installation, tandem
+
+The Tandem port is only minimally supported.
+The port's contributor no longer has access to a Tandem system.
+
+@c This section based on README.Tandem by Stephen Davies (scldad@sdc.com.au)
+The Tandem port was done on a Cyclone machine running D20.
+The port is pretty clean and all facilities seem to work except for
+the I/O piping facilities
+(@pxref{Getline/Pipe},
+@ref{Getline/Variable/Pipe},
+and
+@ref{Redirection}),
+which is just too foreign a concept for Tandem.
+
+To build a Tandem executable from source, download all of the files so
+that the @value{FN}s on the Tandem box conform to the restrictions of D20.
+For example, @file{array.c} becomes @file{ARRAYC}, and @file{awk.h}
+becomes @file{AWKH}. The totally Tandem-specific files are in the
+@file{tandem} ``subvolume'' (@file{unsupported/tandem} in the @command{gawk}
+distribution) and should be copied to the main source directory before
+building @command{gawk}.
+
+The file @file{compit} can then be used to compile and bind an executable.
+Alas, there is no @command{configure} or @command{make}.
+
+Usage is the same as for Unix, except that D20 requires all @samp{@{} and
+@samp{@}} characters to be escaped with @samp{~} on the command line
+(but @emph{not} in script files). Also, the standard Tandem syntax for
+@samp{/in filename,out filename/} must be used instead of the usual
+Unix @samp{<} and @samp{>} for file redirection. (Redirection options
+on @code{getline}, @code{print} etc., are supported.)
+
+The @samp{-mr @var{val}} option
+(@pxref{Options})
+has been ``stolen'' to enable Tandem users to process fixed-length
+records with no ``end-of-line'' character. That is, @samp{-mr 74} tells
+@command{gawk} to read the input file as fixed 74-byte records.
+@c ENDOFRANGE opgawx
+@c ENDOFRANGE pcgawon
+
+@node Bugs
+@appendixsec Reporting Problems and Bugs
+@cindex archeologists
+@quotation
+@i{There is nothing more dangerous than a bored archeologist.}@*
+The Hitchhiker's Guide to the Galaxy
+@end quotation
+@c the radio show, not the book. :-)
+
+@c STARTOFRANGE dbugg
+@cindex debugging @command{gawk}, bug reports
+@c STARTOFRANGE tblgawb
+@cindex troubleshooting, @command{gawk}, bug reports
+If you have problems with @command{gawk} or think that you have found a bug,
+please report it to the developers; we cannot promise to do anything
+but we might well want to fix it.
+
+Before reporting a bug, make sure you have actually found a real bug.
+Carefully reread the documentation and see if it really says you can do
+what you're trying to do. If it's not clear whether you should be able
+to do something or not, report that too; it's a bug in the documentation!
+
+Before reporting a bug or trying to fix it yourself, try to isolate it
+to the smallest possible @command{awk} program and input @value{DF} that
+reproduces the problem. Then send us the program and @value{DF},
+some idea of what kind of Unix system you're using,
+the compiler you used to compile @command{gawk}, and the exact results
+@command{gawk} gave you. Also say what you expected to occur; this helps
+us decide whether the problem is really in the documentation.
+
+@cindex @code{bug-gawk@@gnu.org} bug reporting address
+@cindex email address for bug reports, @code{bug-gawk@@gnu.org}
+@cindex bug reports, email address, @code{bug-gawk@@gnu.org}
+Once you have a precise problem, send email to @email{bug-gawk@@gnu.org}.
+
+@cindex Robbins, Arnold
+Please include the version number of @command{gawk} you are using.
+You can get this information with the command @samp{gawk --version}.
+Using this address automatically sends a carbon copy of your
+mail to me. If necessary, I can be reached directly at
+@email{arnold@@gnu.org}. The bug reporting address is preferred since the
+email list is archived at the GNU Project.
+@emph{All email should be in English, since that is my native language.}
+
+@cindex @code{comp.lang.awk} newsgroup
+@strong{Caution:} Do @emph{not} try to report bugs in @command{gawk} by
+posting to the Usenet/Internet newsgroup @code{comp.lang.awk}.
+While the @command{gawk} developers do occasionally read this newsgroup,
+there is no guarantee that we will see your posting. The steps described
+above are the official recognized ways for reporting bugs.
+
+Non-bug suggestions are always welcome as well. If you have questions
+about things that are unclear in the documentation or are just obscure
+features, ask me; I will try to help you out, although I
+may not have the time to fix the problem. You can send me electronic
+mail at the Internet address noted previously.
+
+If you find bugs in one of the non-Unix ports of @command{gawk}, please send
+an electronic mail message to the person who maintains that port. They
+are named in the following list, as well as in the @file{README} file in the @command{gawk}
+distribution. Information in the @file{README} file should be considered
+authoritative if it conflicts with this @value{DOCUMENT}.
+
+The people maintaining the non-Unix ports of @command{gawk} are
+as follows:
+
+@ignore
+@table @asis
+@cindex Fish, Fred
+@item Amiga
+Fred Fish, @email{fnf@@ninemoons.com}.
+
+@cindex Brown, Martin
+@item BeOS
+Martin Brown, @email{mc@@whoever.com}.
+
+@cindex Deifik, Scott
+@cindex Hankerson, Darrel
+@item MS-DOS
+Scott Deifik, @email{scottd@@amgen.com} and
+Darrel Hankerson, @email{hankedr@@mail.auburn.edu}.
+
+@cindex Grigera, Juan
+@item MS-Windows
+Juan Grigera, @email{juan@@biophnet.unlp.edu.ar}.
+
+@item OS/2
+Andreas Buening, @email{andreas.buening@@nexgo.de}.
+
+@cindex Davies, Stephen
+@item Tandem
+Stephen Davies, @email{scldad@@sdc.com.au}.
+
+@cindex Rankin, Pat
+@item VMS
+Pat Rankin, @email{rankin@@pactechdata.com}.
+@end table
+@end ignore
+
+@multitable {MS-Windows} {123456789012345678901234567890123456789001234567890}
+@cindex Fish, Fred
+@item Amiga @tab Fred Fish, @email{fnf@@ninemoons.com}.
+
+@cindex Brown, Martin
+@item BeOS @tab Martin Brown, @email{mc@@whoever.com}.
+
+@cindex Deifik, Scott
+@cindex Hankerson, Darrel
+@item MS-DOS @tab Scott Deifik, @email{scottd@@amgen.com} and
+Darrel Hankerson, @email{hankedr@@mail.auburn.edu}.
+
+@cindex Grigera, Juan
+@item MS-Windows @tab Juan Grigera, @email{juan@@biophnet.unlp.edu.ar}.
+
+@item OS/2 @tab The Unix for OS/2 team, @email{gawk-maintainer@@unixos2.org}.
+
+@cindex Davies, Stephen
+@item Tandem @tab Stephen Davies, @email{scldad@@sdc.com.au}.
+
+@cindex Rankin, Pat
+@item VMS @tab Pat Rankin, @email{rankin@@pactechdata.com}.
+@end multitable
+
+If your bug is also reproducible under Unix, please send a copy of your
+report to the @email{bug-gawk@@gnu.org} email list as well.
+@c ENDOFRANGE dbugg
+@c ENDOFRANGE tblgawb
+
+@node Other Versions
+@appendixsec Other Freely Available @command{awk} Implementations
+@c STARTOFRANGE awkim
+@cindex @command{awk}, implementations
+@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
+@quotation
+@i{It's kind of fun to put comments like this in your awk code.}@*
+@ @ @ @ @ @ @code{// Do C++ comments work? answer: yes! of course}@*
+Michael Brennan
+@end quotation
+
+There are three other freely available @command{awk} implementations.
+This @value{SECTION} briefly describes where to get them:
+
+@table @asis
+@cindex Kernighan, Brian
+@cindex source code, Bell Laboratories @command{awk}
+@item Unix @command{awk}
+Brian Kernighan has made his implementation of
+@command{awk} freely available.
+You can retrieve this version via the World Wide Web from
+his home page.@footnote{@uref{http://cm.bell-labs.com/who/bwk}}
+It is available in several archive formats:
+
+@table @asis
+@item Shell archive
+@uref{http://cm.bell-labs.com/who/bwk/awk.shar}
+
+@item Compressed @command{tar} file
+@uref{http://cm.bell-labs.com/who/bwk/awk.tar.gz}
+
+@item Zip file
+@uref{http://cm.bell-labs.com/who/bwk/awk.zip}
+@end table
+
+This version requires an ISO C (1990 standard) compiler;
+the C compiler from
+GCC (the GNU Compiler Collection)
+works quite nicely.
+
+@xref{BTL},
+for a list of extensions in this @command{awk} that are not in POSIX @command{awk}.
+
+@cindex Brennan, Michael
+@cindex @command{mawk} program
+@cindex source code, @command{mawk}
+@item @command{mawk}
+Michael Brennan has written an independent implementation of @command{awk},
+called @command{mawk}. It is available under the GPL
+(@pxref{Copying}),
+just as @command{gawk} is.
+
+You can get it via anonymous @command{ftp} to the host
+@code{@w{ftp.whidbey.net}}. Change directory to @file{/pub/brennan}.
+Use ``binary'' or ``image'' mode, and retrieve @file{mawk1.3.3.tar.gz}
+(or the latest version that is there).
+
+@command{gunzip} may be used to decompress this file. Installation
+is similar to @command{gawk}'s
+(@pxref{Unix Installation}).
+
+@cindex extensions, @command{mawk}
+@command{mawk} has the following extensions that are not in POSIX @command{awk}:
+
+@itemize @bullet
+@item
+The @code{fflush} built-in function for flushing buffered output
+(@pxref{I/O Functions}).
+
+@item
+The @samp{**} and @samp{**=} operators
+(@pxref{Arithmetic Ops}
+and also see
+@ref{Assignment Ops}).
+
+@item
+The use of @code{func} as an abbreviation for @code{function}
+(@pxref{Definition Syntax}).
+
+@item
+The @samp{\x} escape sequence
+(@pxref{Escape Sequences}).
+
+@item
+The @file{/dev/stdout}, and @file{/dev/stderr}
+special files
+(@pxref{Special Files}).
+Use @code{"-"} instead of @code{"/dev/stdin"} with @command{mawk}.
+
+@item
+The ability for @code{FS} and for the third
+argument to @code{split} to be null strings
+(@pxref{Single Character Fields}).
+
+@item
+The ability to delete all of an array at once with @samp{delete @var{array}}
+(@pxref{Delete}).
+
+@item
+The ability for @code{RS} to be a regexp
+(@pxref{Records}).
+
+@item
+The @code{BINMODE} special variable for non-Unix operating systems
+(@pxref{PC Using}).
+@end itemize
+
+The next version of @command{mawk} will support @code{nextfile}.
+
+@cindex Sumner, Andrew
+@cindex @command{awka} compiler for @command{awk}
+@cindex source code, @command{awka}
+@item @command{awka}
+Written by Andrew Sumner,
+@command{awka} translates @command{awk} programs into C, compiles them,
+and links them with a library of functions that provides the core
+@command{awk} functionality.
+It also has a number of extensions.
+
+The @command{awk} translator is released under the GPL, and the library
+is under the LGPL.
+
+To get @command{awka}, go to @uref{http://awka.sourceforge.net}.
+You can reach Andrew Sumner at @email{andrew@@zbcom.net}.
+
+@cindex Beebe, Nelson H.F.@:
+@cindex @command{pawk} profiling Bell Labs @command{awk}
+@item @command{pawk}
+Nelson H.F.@: Beebe at the University of Utah has modified
+the Bell Labs @command{awk} to provide timing and profiling information.
+It is different from @command{pgawk}
+(@pxref{Profiling}),
+in that it uses CPU-based profiling, not line-count
+profiling. You may find it at either
+@uref{ftp://ftp.math.utah.edu/pub/pawk/pawk-20020210.tar.gz}
+or
+@uref{http://www.math.utah.edu/pub/pawk/pawk-20020210.tar.gz}.
+
+@end table
+@c ENDOFRANGE gligawk
+@c ENDOFRANGE ingawk
+@c ENDOFRANGE awkim
+
+@node Notes
+@appendix Implementation Notes
+@c STARTOFRANGE gawii
+@cindex @command{gawk}, implementation issues
+@c STARTOFRANGE impis
+@cindex implementation issues, @command{gawk}
+
+This appendix contains information mainly of interest to implementors and
+maintainers of @command{gawk}. Everything in it applies specifically to
+@command{gawk} and not to other implementations.
+
+@menu
+* Compatibility Mode:: How to disable certain @command{gawk}
+ extensions.
+* Additions:: Making Additions To @command{gawk}.
+* Dynamic Extensions:: Adding new built-in functions to
+ @command{gawk}.
+* Future Extensions:: New features that may be implemented one day.
+@end menu
+
+@node Compatibility Mode
+@appendixsec Downward Compatibility and Debugging
+@cindex @command{gawk}, implementation issues, downward compatibility
+@cindex @command{gawk}, implementation issues, debugging
+@cindex troubleshooting, @command{gawk}
+@cindex implementation issues@comma{} @command{gawk}, debugging
+
+@xref{POSIX/GNU},
+for a summary of the GNU extensions to the @command{awk} language and program.
+All of these features can be turned off by invoking @command{gawk} with the
+@option{--traditional} option or with the @option{--posix} option.
+
+If @command{gawk} is compiled for debugging with @samp{-DDEBUG}, then there
+is one more option available on the command line:
+
+@table @code
+@item -W parsedebug
+@itemx --parsedebug
+Prints out the parse stack information as the program is being parsed.
+@end table
+
+This option is intended only for serious @command{gawk} developers
+and not for the casual user. It probably has not even been compiled into
+your version of @command{gawk}, since it slows down execution.
+
+@node Additions
+@appendixsec Making Additions to @command{gawk}
+
+If you find that you want to enhance @command{gawk} in a significant
+fashion, you are perfectly free to do so. That is the point of having
+free software; the source code is available and you are free to change
+it as you want (@pxref{Copying}).
+
+This @value{SECTION} discusses the ways you might want to change @command{gawk}
+as well as any considerations you should bear in mind.
+
+@menu
+* Adding Code:: Adding code to the main body of
+ @command{gawk}.
+* New Ports:: Porting @command{gawk} to a new operating
+ system.
+@end menu
+
+@node Adding Code
+@appendixsubsec Adding New Features
+
+@c STARTOFRANGE adfgaw
+@cindex adding, features to @command{gawk}
+@c STARTOFRANGE fadgaw
+@cindex features, adding to @command{gawk}
+@c STARTOFRANGE gawadf
+@cindex @command{gawk}, features, adding
+You are free to add any new features you like to @command{gawk}.
+However, if you want your changes to be incorporated into the @command{gawk}
+distribution, there are several steps that you need to take in order to
+make it possible for me to include your changes:
+
+@enumerate 1
+@item
+Before building the new feature into @command{gawk} itself,
+consider writing it as an extension module
+(@pxref{Dynamic Extensions}).
+If that's not possible, continue with the rest of the steps in this list.
+
+@item
+Get the latest version.
+It is much easier for me to integrate changes if they are relative to
+the most recent distributed version of @command{gawk}. If your version of
+@command{gawk} is very old, I may not be able to integrate them at all.
+(@xref{Getting},
+for information on getting the latest version of @command{gawk}.)
+
+@item
+@ifnotinfo
+Follow the @cite{GNU Coding Standards}.
+@end ifnotinfo
+@ifinfo
+See @inforef{Top, , Version, standards, GNU Coding Standards}.
+@end ifinfo
+This document describes how GNU software should be written. If you haven't
+read it, please do so, preferably @emph{before} starting to modify @command{gawk}.
+(The @cite{GNU Coding Standards} are available from
+the GNU Project's
+@command{ftp}
+site, at
+@uref{ftp://ftp.gnu.org/gnu/GNUinfo/standards.text}.
+An HTML version, suitable for reading with a WWW browser, is
+available at
+@uref{http://www.gnu.org/prep/standards_toc.html}.
+Texinfo, Info, and DVI versions are also available.)
+
+@cindex @command{gawk}, coding style in
+@item
+Use the @command{gawk} coding style.
+The C code for @command{gawk} follows the instructions in the
+@cite{GNU Coding Standards}, with minor exceptions. The code is formatted
+using the traditional ``K&R'' style, particularly as regards to the placement
+of braces and the use of tabs. In brief, the coding rules for @command{gawk}
+are as follows:
+
+@itemize @bullet
+@item
+Use ANSI/ISO style (prototype) function headers when defining functions.
+
+@item
+Put the name of the function at the beginning of its own line.
+
+@item
+Put the return type of the function, even if it is @code{int}, on the
+line above the line with the name and arguments of the function.
+
+@item
+Put spaces around parentheses used in control structures
+(@code{if}, @code{while}, @code{for}, @code{do}, @code{switch},
+and @code{return}).
+
+@item
+Do not put spaces in front of parentheses used in function calls.
+
+@item
+Put spaces around all C operators and after commas in function calls.
+
+@item
+Do not use the comma operator to produce multiple side effects, except
+in @code{for} loop initialization and increment parts, and in macro bodies.
+
+@item
+Use real tabs for indenting, not spaces.
+
+@item
+Use the ``K&R'' brace layout style.
+
+@item
+Use comparisons against @code{NULL} and @code{'\0'} in the conditions of
+@code{if}, @code{while}, and @code{for} statements, as well as in the @code{case}s
+of @code{switch} statements, instead of just the
+plain pointer or character value.
+
+@item
+Use the @code{TRUE}, @code{FALSE} and @code{NULL} symbolic constants
+and the character constant @code{'\0'} where appropriate, instead of @code{1}
+and @code{0}.
+
+@item
+Use the @code{ISALPHA}, @code{ISDIGIT}, etc.@: macros, instead of the
+traditional lowercase versions; these macros are better behaved for
+non-ASCII character sets.
+
+@item
+Provide one-line descriptive comments for each function.
+
+@item
+Do not use @samp{#elif}. Many older Unix C compilers cannot handle it.
+
+@item
+Do not use the @code{alloca} function for allocating memory off the stack.
+Its use causes more portability trouble than is worth the minor benefit of not having
+to free the storage. Instead, use @code{malloc} and @code{free}.
+@end itemize
+
+@quotation NOTE
+If I have to reformat your code to follow the coding style used in
+@command{gawk}, I may not bother to integrate your changes at all.
+@end quotation
+
+@item
+Be prepared to sign the appropriate paperwork.
+In order for the FSF to distribute your changes, you must either place
+those changes in the public domain and submit a signed statement to that
+effect, or assign the copyright in your changes to the FSF.
+Both of these actions are easy to do and @emph{many} people have done so
+already. If you have questions, please contact me
+(@pxref{Bugs}),
+or @email{gnu@@gnu.org}.
+
+@cindex Texinfo
+@item
+Update the documentation.
+Along with your new code, please supply new sections and/or chapters
+for this @value{DOCUMENT}. If at all possible, please use real
+Texinfo, instead of just supplying unformatted ASCII text (although
+even that is better than no documentation at all).
+Conventions to be followed in @cite{@value{TITLE}} are provided
+after the @samp{@@bye} at the end of the Texinfo source file.
+If possible, please update the @command{man} page as well.
+
+You will also have to sign paperwork for your documentation changes.
+
+@item
+Submit changes as context diffs or unified diffs.
+Use @samp{diff -c -r -N} or @samp{diff -u -r -N} to compare
+the original @command{gawk} source tree with your version.
+(I find context diffs to be more readable but unified diffs are
+more compact.)
+I recommend using the GNU version of @command{diff}.
+Send the output produced by either run of @command{diff} to me when you
+submit your changes.
+(@xref{Bugs}, for the electronic mail
+information.)
+
+Using this format makes it easy for me to apply your changes to the
+master version of the @command{gawk} source code (using @code{patch}).
+If I have to apply the changes manually, using a text editor, I may
+not do so, particularly if there are lots of changes.
+
+@item
+Include an entry for the @file{ChangeLog} file with your submission.
+This helps further minimize the amount of work I have to do,
+making it easier for me to accept patches.
+@end enumerate
+
+Although this sounds like a lot of work, please remember that while you
+may write the new code, I have to maintain it and support it. If it
+isn't possible for me to do that with a minimum of extra work, then I
+probably will not.
+@c ENDOFRANGE adfgaw
+@c ENDOFRANGE gawadf
+@c ENDOFRANGE fadgaw
+
+@node New Ports
+@appendixsubsec Porting @command{gawk} to a New Operating System
+@cindex portability, @command{gawk}
+@cindex operating systems, porting @command{gawk} to
+
+@cindex porting @command{gawk}
+If you want to port @command{gawk} to a new operating system, there are
+several steps:
+
+@enumerate 1
+@item
+Follow the guidelines in
+@ifinfo
+@ref{Adding Code},
+@end ifinfo
+@ifnotinfo
+the previous @value{SECTION}
+@end ifnotinfo
+concerning coding style, submission of diffs, and so on.
+
+@item
+When doing a port, bear in mind that your code must coexist peacefully
+with the rest of @command{gawk} and the other ports. Avoid gratuitous
+changes to the system-independent parts of the code. If at all possible,
+avoid sprinkling @samp{#ifdef}s just for your port throughout the
+code.
+
+If the changes needed for a particular system affect too much of the
+code, I probably will not accept them. In such a case, you can, of course,
+distribute your changes on your own, as long as you comply
+with the GPL
+(@pxref{Copying}).
+
+@item
+A number of the files that come with @command{gawk} are maintained by other
+people at the Free Software Foundation. Thus, you should not change them
+unless it is for a very good reason; i.e., changes are not out of the
+question, but changes to these files are scrutinized extra carefully.
+The files are @file{getopt.h}, @file{getopt.c},
+@file{getopt1.c}, @file{regex.h}, @file{regex.c}, @file{dfa.h},
+@file{dfa.c}, @file{install-sh}, and @file{mkinstalldirs}.
+
+@item
+Be willing to continue to maintain the port.
+Non-Unix operating systems are supported by volunteers who maintain
+the code needed to compile and run @command{gawk} on their systems. If noone
+volunteers to maintain a port, it becomes unsupported and it may
+be necessary to remove it from the distribution.
+
+@item
+Supply an appropriate @file{gawkmisc.???} file.
+Each port has its own @file{gawkmisc.???} that implements certain
+operating system specific functions. This is cleaner than a plethora of
+@samp{#ifdef}s scattered throughout the code. The @file{gawkmisc.c} in
+the main source directory includes the appropriate
+@file{gawkmisc.???} file from each subdirectory.
+Be sure to update it as well.
+
+Each port's @file{gawkmisc.???} file has a suffix reminiscent of the machine
+or operating system for the port---for example, @file{pc/gawkmisc.pc} and
+@file{vms/gawkmisc.vms}. The use of separate suffixes, instead of plain
+@file{gawkmisc.c}, makes it possible to move files from a port's subdirectory
+into the main subdirectory, without accidentally destroying the real
+@file{gawkmisc.c} file. (Currently, this is only an issue for the
+PC operating system ports.)
+
+@item
+Supply a @file{Makefile} as well as any other C source and header files that are
+necessary for your operating system. All your code should be in a
+separate subdirectory, with a name that is the same as, or reminiscent
+of, either your operating system or the computer system. If possible,
+try to structure things so that it is not necessary to move files out
+of the subdirectory into the main source directory. If that is not
+possible, then be sure to avoid using names for your files that
+duplicate the names of files in the main source directory.
+
+@item
+Update the documentation.
+Please write a section (or sections) for this @value{DOCUMENT} describing the
+installation and compilation steps needed to compile and/or install
+@command{gawk} for your system.
+
+@item
+Be prepared to sign the appropriate paperwork.
+In order for the FSF to distribute your code, you must either place
+your code in the public domain and submit a signed statement to that
+effect, or assign the copyright in your code to the FSF.
+@ifinfo
+Both of these actions are easy to do and @emph{many} people have done so
+already. If you have questions, please contact me, or
+@email{gnu@@gnu.org}.
+@end ifinfo
+@end enumerate
+
+Following these steps makes it much easier to integrate your changes
+into @command{gawk} and have them coexist happily with other
+operating systems' code that is already there.
+
+In the code that you supply and maintain, feel free to use a
+coding style and brace layout that suits your taste.
+
+@node Dynamic Extensions
+@appendixsec Adding New Built-in Functions to @command{gawk}
+@cindex Robinson, Will
+@cindex robot, the
+@cindex Lost In Space
+@quotation
+@i{Danger Will Robinson! Danger!!@*
+Warning! Warning!}@*
+The Robot
+@end quotation
+
+@c STARTOFRANGE gladfgaw
+@cindex @command{gawk}, functions, adding
+@c STARTOFRANGE adfugaw
+@cindex adding, functions to @command{gawk}
+@c STARTOFRANGE fubadgaw
+@cindex functions, built-in, adding to @command{gawk}
+Beginning with @command{gawk} 3.1, it is possible to add new built-in
+functions to @command{gawk} using dynamically loaded libraries. This
+facility is available on systems (such as GNU/Linux) that support
+the @code{dlopen} and @code{dlsym} functions.
+This @value{SECTION} describes how to write and use dynamically
+loaded extensions for @command{gawk}.
+Experience with programming in
+C or C++ is necessary when reading this @value{SECTION}.
+
+@strong{Caution:} The facilities described in this @value{SECTION}
+are very much subject to change in a future @command{gawk} release.
+Be aware that you may have to re-do everything, perhaps from scratch,
+at some future time.
+
+@strong{Caution:} If you have written your own dynamic extensions,
+be sure to recompile them for each new @command{gawk} release.
+There is no guarantee of binary compatibility between different
+releases, no will there ever be such a guarantee.
+
+@menu
+* Internals:: A brief look at some @command{gawk} internals.
+* Sample Library:: A example of new functions.
+@end menu
+
+@node Internals
+@appendixsubsec A Minimal Introduction to @command{gawk} Internals
+@c STARTOFRANGE gawint
+@cindex @command{gawk}, internals
+
+The truth is that @command{gawk} was not designed for simple extensibility.
+The facilities for adding functions using shared libraries work, but
+are something of a ``bag on the side.'' Thus, this tour is
+brief and simplistic; would-be @command{gawk} hackers are encouraged to
+spend some time reading the source code before trying to write
+extensions based on the material presented here. Of particular note
+are the files @file{awk.h}, @file{builtin.c}, and @file{eval.c}.
+Reading @file{awkgram.y} in order to see how the parse tree is built
+would also be of use.
+
+@cindex @code{awk.h} file (internal)
+With the disclaimers out of the way, the following types, structure
+members, functions, and macros are declared in @file{awk.h} and are of
+use when writing extensions. The next @value{SECTION}
+shows how they are used:
+
+@table @code
+@cindex floating-point, numbers, @code{AWKNUM} internal type
+@cindex numbers, floating-point, @code{AWKNUM} internal type
+@cindex @code{AWKNUM} internal type
+@item AWKNUM
+An @code{AWKNUM} is the internal type of @command{awk}
+floating-point numbers. Typically, it is a C @code{double}.
+
+@cindex @code{NODE} internal type
+@cindex strings, @code{NODE} internal type
+@cindex numbers, @code{NODE} internal type
+@item NODE
+Just about everything is done using objects of type @code{NODE}.
+These contain both strings and numbers, as well as variables and arrays.
+
+@cindex @code{force_number} internal function
+@cindex numeric, values
+@item AWKNUM force_number(NODE *n)
+This macro forces a value to be numeric. It returns the actual
+numeric value contained in the node.
+It may end up calling an internal @command{gawk} function.
+
+@cindex @code{force_string} internal function
+@item void force_string(NODE *n)
+This macro guarantees that a @code{NODE}'s string value is current.
+It may end up calling an internal @command{gawk} function.
+It also guarantees that the string is zero-terminated.
+
+@cindex @code{get_curfunc_arg_count} internal function
+@item size_t get_curfunc_arg_count(void)
+This function returns the actual number of parameters passed
+to the current function. Inside the code of an extension
+this can be used to determine the maximum index which is
+safe to use with @code{stack_ptr}. If this value is
+greater than @code{tree->param_cnt}, the function was
+called incorrectly from the @command{awk} program.
+
+@strong{Caution:} This function is new as of @command{gawk} 3.1.4.
+
+@cindex parameters@comma{} number of
+@cindex @code{param_cnt} internal variable
+@item n->param_cnt
+Inside an extension function, this is the maximum number of
+expected parameters, as set by the @code{make_builtin} function.
+
+@cindex @code{stptr} internal variable
+@cindex @code{stlen} internal variable
+@item n->stptr
+@itemx n->stlen
+The data and length of a @code{NODE}'s string value, respectively.
+The string is @emph{not} guaranteed to be zero-terminated.
+If you need to pass the string value to a C library function, save
+the value in @code{n->stptr[n->stlen]}, assign @code{'\0'} to it,
+call the routine, and then restore the value.
+
+@cindex @code{type} internal variable
+@item n->type
+The type of the @code{NODE}. This is a C @code{enum}. Values should
+be either @code{Node_var} or @code{Node_var_array} for function
+parameters.
+
+@cindex @code{vname} internal variable
+@item n->vname
+The ``variable name'' of a node. This is not of much use inside
+externally written extensions.
+
+@cindex arrays, associative, clearing
+@cindex @code{assoc_clear} internal function
+@item void assoc_clear(NODE *n)
+Clears the associative array pointed to by @code{n}.
+Make sure that @samp{n->type == Node_var_array} first.
+
+@cindex arrays, elements, installing
+@cindex @code{assoc_lookup} internal function
+@item NODE **assoc_lookup(NODE *symbol, NODE *subs, int reference)
+Finds, and installs if necessary, array elements.
+@code{symbol} is the array, @code{subs} is the subscript.
+This is usually a value created with @code{tmp_string} (see below).
+@code{reference} should be @code{TRUE} if it is an error to use the
+value before it is created. Typically, @code{FALSE} is the
+correct value to use from extension functions.
+
+@cindex strings
+@cindex @code{make_string} internal function
+@item NODE *make_string(char *s, size_t len)
+Take a C string and turn it into a pointer to a @code{NODE} that
+can be stored appropriately. This is permanent storage; understanding
+of @command{gawk} memory management is helpful.
+
+@cindex numbers
+@cindex @code{make_number} internal function
+@item NODE *make_number(AWKNUM val)
+Take an @code{AWKNUM} and turn it into a pointer to a @code{NODE} that
+can be stored appropriately. This is permanent storage; understanding
+of @command{gawk} memory management is helpful.
+
+@cindex @code{tmp_string} internal function
+@item NODE *tmp_string(char *s, size_t len);
+Take a C string and turn it into a pointer to a @code{NODE} that
+can be stored appropriately. This is temporary storage; understanding
+of @command{gawk} memory management is helpful.
+
+@cindex @code{tmp_number} internal function
+@item NODE *tmp_number(AWKNUM val)
+Take an @code{AWKNUM} and turn it into a pointer to a @code{NODE} that
+can be stored appropriately. This is temporary storage;
+understanding of @command{gawk} memory management is helpful.
+
+@cindex nodes@comma{} duplicating
+@cindex @code{dupnode} internal function
+@item NODE *dupnode(NODE *n)
+Duplicate a node. In most cases, this increments an internal
+reference count instead of actually duplicating the entire @code{NODE};
+understanding of @command{gawk} memory management is helpful.
+
+@cindex memory, releasing
+@cindex @code{free_temp} internal macro
+@item void free_temp(NODE *n)
+This macro releases the memory associated with a @code{NODE}
+allocated with @code{tmp_string} or @code{tmp_number}.
+Understanding of @command{gawk} memory management is helpful.
+
+@cindex @code{make_builtin} internal function
+@item void make_builtin(char *name, NODE *(*func)(NODE *), int count)
+Register a C function pointed to by @code{func} as new built-in
+function @code{name}. @code{name} is a regular C string. @code{count}
+is the maximum number of arguments that the function takes.
+The function should be written in the following manner:
+
+@example
+/* do_xxx --- do xxx function for gawk */
+
+NODE *
+do_xxx(NODE *tree)
+@{
+ @dots{}
+@}
+@end example
+
+@cindex arguments, retrieving
+@cindex @code{get_argument} internal function
+@item NODE *get_argument(NODE *tree, int i)
+This function is called from within a C extension function to get
+the @code{i}-th argument from the function call.
+The first argument is argument zero.
+
+@cindex @code{get_actual_argument} internal function
+@item NODE *get_actual_argument(NODE *tree, unsigned int i,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int@ optional,@ int@ wantarray);
+This function retrieves a particular argument @code{i}. @code{wantarray} is @code{TRUE}
+if the argument should be an array, @code{FALSE} otherwise. If @code{optional} is
+@code{TRUE}, the argument need not have been supplied. If it wasn't, the return
+value is @code{NULL}. It is a fatal error if @code{optional} is @code{TRUE} but
+the argument was not provided.
+
+@strong{Caution:} This function is new as of @command{gawk} 3.1.4.
+
+@cindex @code{get_scalar_argument} internal macro
+@item get_scalar_argument(t, i, opt)
+This is a convenience macro that calls @code{get_actual_argument}.
+
+@strong{Caution:} This macro is new as of @command{gawk} 3.1.4.
+
+@cindex @code{get_array_argument} internal macro
+@item get_array_argument(t, i, opt)
+This is a convenience macro that calls @code{get_actual_argument}.
+
+@strong{Caution:} This macro is new as of @command{gawk} 3.1.4.
+
+@cindex functions, return values@comma{} setting
+@cindex @code{set_value} internal function
+@item void set_value(NODE *tree)
+This function is called from within a C extension function to set
+the return value from the extension function. This value is
+what the @command{awk} program sees as the return value from the
+new @command{awk} function.
+
+@cindex @code{ERRNO} variable
+@cindex @code{update_ERRNO} internal function
+@item void update_ERRNO(void)
+This function is called from within a C extension function to set
+the value of @command{gawk}'s @code{ERRNO} variable, based on the current
+value of the C @code{errno} variable.
+It is provided as a convenience.
+
+@cindex @code{ERRNO} variable
+@cindex @code{update_ERRNO_saved} internal function
+@item void update_ERRNO_saved(int errno_saved)
+This function is called from within a C extension function to set
+the value of @command{gawk}'s @code{ERRNO} variable, based on the saved
+value of the C @code{errno} variable provided as the argument.
+It is provided as a convenience.
+
+@strong{Caution:} This function is new as of @command{gawk} 3.1.5.
+
+@cindex @code{ENVIRON} variable
+@cindex @code{PROCINFO} variable
+@cindex @code{register_deferred_variable} internal function
+@item void register_deferred_variable(const char *name, NODE *(*load_func)(void))
+This function is called to register a function to be called when a
+reference to an undefined variable with the given name is encountered.
+The callback function will never be called if the variable exists already,
+so, unless the calling code is running at program startup, it should first
+check whether a variable of the given name already exists.
+The argument function must return a pointer to a NODE containing the
+newly created variable. This function is used to implement the builtin
+@code{ENVIRON} and @code{PROCINFO} variables, so you can refer to them
+for examples.
+
+@strong{Caution:} This function is new as of @command{gawk} 3.1.5.
+
+@cindex @code{IOBUF} internal structure
+@cindex @code{iop_alloc} internal function
+@cindex @code{get_record} input method
+@cindex @code{close_func} input method
+@cindex XML
+@cindex @code{register_open_hook} internal function
+@item void register_open_hook(void *(*open_func)(IOBUF *))
+This function is called to register a function to be called whenever
+a new data file is opened, leading to the creation of an @code{IOBUF}
+structure in @code{iop_alloc}. After creating the new @code{IOBUF},
+@code{iop_alloc} will call (in reverse order of registration, so the last
+function registered is called first) each open hook until one returns
+non-NULL. If any hook returns a non-NULL value, that value is assigned
+to the @code{IOBUF}'s @code{opaque} field (which will presumably point
+to a structure containing additional state associated with the input
+processing), and no further open hooks are called.
+
+The function called will most likely want to set the @code{IOBUF}
+@code{get_record} method to indicate that future input records should
+be retrieved by calling that method instead of using the standard
+@command{gawk} input processing.
+
+And the function will also probably want to set the @code{IOBUF}
+@code{close_func} method to be called when the file is closed to clean
+up any state associated with the input.
+
+Finally, hook functions should be prepared to receive an @code{IOBUF}
+structure where the @code{fd} field is set to @code{INVALID_HANDLE},
+meaning that @command{gawk} was not able to open the file itself. In
+this case, the hook function must be able to successfully open the file
+and place a valid file descriptor there.
+
+Currently, for example, the hook function facility is used to implement
+the XML parser shared library extension. For more info, please look in
+@file{awk.h} and in @file{io.c}.
+
+@strong{Caution:} This function is new as of @command{gawk} 3.1.5.
+@end table
+
+An argument that is supposed to be an array needs to be handled with
+some extra code, in case the array being passed in is actually
+from a function parameter.
+
+In versions of @command{gawk} up to and including 3.1.2, the
+following boilerplate code shows how to do this:
+
+@smallexample
+NODE *the_arg;
+
+the_arg = get_argument(tree, 2); /* assume need 3rd arg, 0-based */
+
+/* if a parameter, get it off the stack */
+if (the_arg->type == Node_param_list)
+ the_arg = stack_ptr[the_arg->param_cnt];
+
+/* parameter referenced an array, get it */
+if (the_arg->type == Node_array_ref)
+ the_arg = the_arg->orig_array;
+
+/* check type */
+if (the_arg->type != Node_var && the_arg->type != Node_var_array)
+ fatal("newfunc: third argument is not an array");
+
+/* force it to be an array, if necessary, clear it */
+the_arg->type = Node_var_array;
+assoc_clear(the_arg);
+@end smallexample
+
+For versions 3.1.3 and later, the internals changed. In particular,
+the interface was actually @emph{simplified} drastically. The
+following boilerplate code now suffices:
+
+@smallexample
+NODE *the_arg;
+
+the_arg = get_argument(tree, 2); /* assume need 3rd arg, 0-based */
+
+/* force it to be an array: */
+the_arg = get_array(the_arg);
+
+/* if necessary, clear it: */
+assoc_clear(the_arg);
+@end smallexample
+
+As of version 3.1.4, the internals improved again, and became
+even simpler:
+
+@smallexample
+NODE *the_arg;
+
+the_arg = get_array_argument(tree, 2, FALSE); /* assume need 3rd arg, 0-based */
+@end smallexample
+
+Again, you should spend time studying the @command{gawk} internals;
+don't just blindly copy this code.
+@c ENDOFRANGE gawint
+
+@node Sample Library
+@appendixsubsec Directory and File Operation Built-ins
+@c STARTOFRANGE chdirg
+@cindex @code{chdir} function@comma{} implementing in @command{gawk}
+@c STARTOFRANGE statg
+@cindex @code{stat} function@comma{} implementing in @command{gawk}
+@c STARTOFRANGE filre
+@cindex files, information about@comma{} retrieving
+@c STARTOFRANGE dirch
+@cindex directories, changing
+
+Two useful functions that are not in @command{awk} are @code{chdir}
+(so that an @command{awk} program can change its directory) and
+@code{stat} (so that an @command{awk} program can gather information about
+a file).
+This @value{SECTION} implements these functions for @command{gawk} in an
+external extension library.
+
+@menu
+* Internal File Description:: What the new functions will do.
+* Internal File Ops:: The code for internal file operations.
+* Using Internal File Ops:: How to use an external extension.
+@end menu
+
+@node Internal File Description
+@appendixsubsubsec Using @code{chdir} and @code{stat}
+
+This @value{SECTION} shows how to use the new functions at the @command{awk}
+level once they've been integrated into the running @command{gawk}
+interpreter.
+Using @code{chdir} is very straightforward. It takes one argument,
+the new directory to change to:
+
+@example
+@dots{}
+newdir = "/home/arnold/funstuff"
+ret = chdir(newdir)
+if (ret < 0) @{
+ printf("could not change to %s: %s\n",
+ newdir, ERRNO) > "/dev/stderr"
+ exit 1
+@}
+@dots{}
+@end example
+
+The return value is negative if the @code{chdir} failed,
+and @code{ERRNO}
+(@pxref{Built-in Variables})
+is set to a string indicating the error.
+
+Using @code{stat} is a bit more complicated.
+The C @code{stat} function fills in a structure that has a fair
+amount of information.
+The right way to model this in @command{awk} is to fill in an associative
+array with the appropriate information:
+
+@c broke printf for page breaking
+@example
+file = "/home/arnold/.profile"
+fdata[1] = "x" # force `fdata' to be an array
+ret = stat(file, fdata)
+if (ret < 0) @{
+ printf("could not stat %s: %s\n",
+ file, ERRNO) > "/dev/stderr"
+ exit 1
+@}
+printf("size of %s is %d bytes\n", file, fdata["size"])
+@end example
+
+The @code{stat} function always clears the data array, even if
+the @code{stat} fails. It fills in the following elements:
+
+@table @code
+@item "name"
+The name of the file that was @code{stat}'ed.
+
+@item "dev"
+@itemx "ino"
+The file's device and inode numbers, respectively.
+
+@item "mode"
+The file's mode, as a numeric value. This includes both the file's
+type and its permissions.
+
+@item "nlink"
+The number of hard links (directory entries) the file has.
+
+@item "uid"
+@itemx "gid"
+The numeric user and group ID numbers of the file's owner.
+
+@item "size"
+The size in bytes of the file.
+
+@item "blocks"
+The number of disk blocks the file actually occupies. This may not
+be a function of the file's size if the file has holes.
+
+@item "atime"
+@itemx "mtime"
+@itemx "ctime"
+The file's last access, modification, and inode update times,
+respectively. These are numeric timestamps, suitable for formatting
+with @code{strftime}
+(@pxref{Built-in}).
+
+@item "pmode"
+The file's ``printable mode.'' This is a string representation of
+the file's type and permissions, such as what is produced by
+@samp{ls -l}---for example, @code{"drwxr-xr-x"}.
+
+@item "type"
+A printable string representation of the file's type. The value
+is one of the following:
+
+@table @code
+@item "blockdev"
+@itemx "chardev"
+The file is a block or character device (``special file'').
+
+@ignore
+@item "door"
+The file is a Solaris ``door'' (special file used for
+interprocess communications).
+@end ignore
+
+@item "directory"
+The file is a directory.
+
+@item "fifo"
+The file is a named-pipe (also known as a FIFO).
+
+@item "file"
+The file is just a regular file.
+
+@item "socket"
+The file is an @code{AF_UNIX} (``Unix domain'') socket in the
+filesystem.
+
+@item "symlink"
+The file is a symbolic link.
+@end table
+@end table
+
+Several additional elements may be present depending upon the operating
+system and the type of the file. You can test for them in your @command{awk}
+program by using the @code{in} operator
+(@pxref{Reference to Elements}):
+
+@table @code
+@item "blksize"
+The preferred block size for I/O to the file. This field is not
+present on all POSIX-like systems in the C @code{stat} structure.
+
+@item "linkval"
+If the file is a symbolic link, this element is the name of the
+file the link points to (i.e., the value of the link).
+
+@item "rdev"
+@itemx "major"
+@itemx "minor"
+If the file is a block or character device file, then these values
+represent the numeric device number and the major and minor components
+of that number, respectively.
+@end table
+
+@node Internal File Ops
+@appendixsubsubsec C Code for @code{chdir} and @code{stat}
+
+Here is the C code for these extensions. They were written for
+GNU/Linux. The code needs some more work for complete portability
+to other POSIX-compliant systems:@footnote{This version is edited
+slightly for presentation. The complete version can be found in
+@file{extension/filefuncs.c} in the @command{gawk} distribution.}
+
+@c break line for page breaking
+@example
+#include "awk.h"
+
+#include <sys/sysmacros.h>
+
+/* do_chdir --- provide dynamically loaded
+ chdir() builtin for gawk */
+
+static NODE *
+do_chdir(tree)
+NODE *tree;
+@{
+ NODE *newdir;
+ int ret = -1;
+
+ if (do_lint && get_curfunc_arg_count() != 1)
+ lintwarn("chdir: called with incorrect number of arguments");
+
+ newdir = get_scalar_argument(tree, 0);
+@end example
+
+The file includes the @code{"awk.h"} header file for definitions
+for the @command{gawk} internals. It includes @code{<sys/sysmacros.h>}
+for access to the @code{major} and @code{minor} macros.
+
+@cindex programming conventions, @command{gawk} internals
+By convention, for an @command{awk} function @code{foo}, the function that
+implements it is called @samp{do_foo}. The function should take
+a @samp{NODE *} argument, usually called @code{tree}, that
+represents the argument list to the function. The @code{newdir}
+variable represents the new directory to change to, retrieved
+with @code{get_argument}. Note that the first argument is
+numbered zero.
+
+This code actually accomplishes the @code{chdir}. It first forces
+the argument to be a string and passes the string value to the
+@code{chdir} system call. If the @code{chdir} fails, @code{ERRNO}
+is updated.
+The result of @code{force_string} has to be freed with @code{free_temp}:
+
+@example
+ (void) force_string(newdir);
+ ret = chdir(newdir->stptr);
+ if (ret < 0)
+ update_ERRNO();
+ free_temp(newdir);
+@end example
+
+Finally, the function returns the return value to the @command{awk} level,
+using @code{set_value}. Then it must return a value from the call to
+the new built-in (this value ignored by the interpreter):
+
+@example
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+@}
+@end example
+
+The @code{stat} built-in is more involved. First comes a function
+that turns a numeric mode into a printable representation
+(e.g., 644 becomes @samp{-rw-r--r--}). This is omitted here for brevity:
+
+@c break line for page breaking
+@example
+/* format_mode --- turn a stat mode field
+ into something readable */
+
+static char *
+format_mode(fmode)
+unsigned long fmode;
+@{
+ @dots{}
+@}
+@end example
+
+Next comes the actual @code{do_stat} function itself. First come the
+variable declarations and argument checking:
+
+@ignore
+Changed message for page breaking. Used to be:
+ "stat: called with incorrect number of arguments (%d), should be 2",
+@end ignore
+@example
+/* do_stat --- provide a stat() function for gawk */
+
+static NODE *
+do_stat(tree)
+NODE *tree;
+@{
+ NODE *file, *array;
+ struct stat sbuf;
+ int ret;
+ NODE **aptr;
+ char *pmode; /* printable mode */
+ char *type = "unknown";
+
+
+ if (do_lint && get_curfunc_arg_count() > 2)
+ lintwarn("stat: called with too many arguments");
+@end example
+
+Then comes the actual work. First, we get the arguments.
+Then, we always clear the array. To get the file information,
+we use @code{lstat}, in case the file is a symbolic link.
+If there's an error, we set @code{ERRNO} and return:
+
+@c comment made multiline for page breaking
+@example
+ /* directory is first arg, array to hold results is second */
+ file = get_scalar_argument(tree, 0, FALSE);
+ array = get_array_argument(tree, 1, FALSE);
+
+ /* empty out the array */
+ assoc_clear(array);
+
+ /* lstat the file, if error, set ERRNO and return */
+ (void) force_string(file);
+ ret = lstat(file->stptr, & sbuf);
+ if (ret < 0) @{
+ update_ERRNO();
+
+ set_value(tmp_number((AWKNUM) ret));
+
+ free_temp(file);
+ return tmp_number((AWKNUM) 0);
+ @}
+@end example
+
+Now comes the tedious part: filling in the array. Only a few of the
+calls are shown here, since they all follow the same pattern:
+
+@example
+ /* fill in the array */
+ aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
+ *aptr = dupnode(file);
+
+ aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mode);
+
+ aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
+ pmode = format_mode(sbuf.st_mode);
+ *aptr = make_string(pmode, strlen(pmode));
+@end example
+
+When done, we free the temporary value containing the @value{FN},
+set the return value, and return:
+
+@example
+ free_temp(file);
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+@}
+@end example
+
+@cindex programming conventions, @command{gawk} internals
+Finally, it's necessary to provide the ``glue'' that loads the
+new function(s) into @command{gawk}. By convention, each library has
+a routine named @code{dlload} that does the job:
+
+@example
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+@{
+ make_builtin("chdir", do_chdir, 1);
+ make_builtin("stat", do_stat, 2);
+ return tmp_number((AWKNUM) 0);
+@}
+@end example
+
+And that's it! As an exercise, consider adding functions to
+implement system calls such as @code{chown}, @code{chmod}, and @code{umask}.
+
+@node Using Internal File Ops
+@appendixsubsubsec Integrating the Extensions
+
+@cindex @command{gawk}, interpreter@comma{} adding code to
+Now that the code is written, it must be possible to add it at
+runtime to the running @command{gawk} interpreter. First, the
+code must be compiled. Assuming that the functions are in
+a file named @file{filefuncs.c}, and @var{idir} is the location
+of the @command{gawk} include files,
+the following steps create
+a GNU/Linux shared library:
+
+@example
+$ gcc -shared -DHAVE_CONFIG_H -c -O -g -I@var{idir} filefuncs.c
+$ ld -o filefuncs.so -shared filefuncs.o
+@end example
+
+@cindex @code{extension} function (@command{gawk})
+Once the library exists, it is loaded by calling the @code{extension}
+built-in function.
+This function takes two arguments: the name of the
+library to load and the name of a function to call when the library
+is first loaded. This function adds the new functions to @command{gawk}.
+It returns the value returned by the initialization function
+within the shared library:
+
+@example
+# file testff.awk
+BEGIN @{
+ extension("./filefuncs.so", "dlload")
+
+ chdir(".") # no-op
+
+ data[1] = 1 # force `data' to be an array
+ print "Info for 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"])
+@}
+@end example
+
+Here are the results of running the program:
+
+@example
+$ gawk -f testff.awk
+@print{} Info for testff.awk
+@print{} ret = 0
+@print{} data["blksize"] = 4096
+@print{} data["mtime"] = 932361936
+@print{} data["mode"] = 33188
+@print{} data["type"] = file
+@print{} data["dev"] = 2065
+@print{} data["gid"] = 10
+@print{} data["ino"] = 878597
+@print{} data["ctime"] = 971431797
+@print{} data["blocks"] = 2
+@print{} data["nlink"] = 1
+@print{} data["name"] = testff.awk
+@print{} data["atime"] = 971608519
+@print{} data["pmode"] = -rw-r--r--
+@print{} data["size"] = 607
+@print{} data["uid"] = 2076
+@print{} testff.awk modified: 07 19 99 08:25:36
+@end example
+@c ENDOFRANGE filre
+@c ENDOFRANGE dirch
+@c ENDOFRANGE statg
+@c ENDOFRANGE chdirg
+@c ENDOFRANGE gladfgaw
+@c ENDOFRANGE adfugaw
+@c ENDOFRANGE fubadgaw
+
+@node Future Extensions
+@appendixsec Probable Future Extensions
+@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 is a language similar to PERL, only considerably more elegant.}@*
+Arnold Robbins
+
+@i{Hey!}@*
+Larry Wall
+@end quotation
+
+This @value{SECTION} briefly lists extensions and possible improvements
+that indicate the directions we are
+currently considering for @command{gawk}. The file @file{FUTURES} in the
+@command{gawk} distribution lists these extensions as well.
+
+Following is a list of probable future changes visible at the
+@command{awk} language level:
+
+@c these are ordered by likelihood
+@table @asis
+@item Loadable module interface
+It is not clear that the @command{awk}-level interface to the
+modules facility is as good as it should be. The interface needs to be
+redesigned, particularly taking namespace issues into account, as
+well as possibly including issues such as library search path order
+and versioning.
+
+@item @code{RECLEN} variable for fixed-length records
+Along with @code{FIELDWIDTHS}, this would speed up the processing of
+fixed-length records.
+@code{PROCINFO["RS"]} would be @code{"RS"} or @code{"RECLEN"},
+depending upon which kind of record processing is in effect.
+
+@item Additional @code{printf} specifiers
+The 1999 ISO C standard added a number of additional @code{printf}
+format specifiers. These should be evaluated for possible inclusion
+in @command{gawk}.
+
+@item Databases
+It may be possible to map a GDBM/NDBM/SDBM file into an @command{awk} array.
+
+@item More @code{lint} warnings
+There are more things that could be checked for portability.
+@end table
+
+Following is a list of probable improvements that will make @command{gawk}'s
+source code easier to work with:
+
+@table @asis
+@item Loadable module mechanics
+The current extension mechanism works
+(@pxref{Dynamic Extensions}),
+but is rather primitive. It requires a fair amount of manual work
+to create and integrate a loadable module.
+Nor is the current mechanism as portable as might be desired.
+The GNU @command{libtool} package provides a number of features that
+would make using loadable modules much easier.
+@command{gawk} should be changed to use @command{libtool}.
+
+@item Loadable module internals
+The API to its internals that @command{gawk} ``exports'' should be revised.
+Too many things are needlessly exposed. A new API should be designed
+and implemented to make module writing easier.
+
+@item Better array subscript management
+@command{gawk}'s management of array subscript storage could use revamping,
+so that using the same value to index multiple arrays only
+stores one copy of the index value.
+
+@item Integrating the DBUG library
+Integrating Fred Fish's DBUG library would be helpful during development,
+but it's a lot of work to do.
+@end table
+
+Following is a list of probable improvements that will make @command{gawk}
+perform better:
+
+@table @asis
+@c NEXT ED: remove this item. awka and mawk do these respectively
+@item Compilation of @command{awk} programs
+@command{gawk} uses a Bison (YACC-like)
+parser to convert the script given it into a syntax tree; the syntax
+tree is then executed by a simple recursive evaluator. This method incurs
+a lot of overhead, since the recursive evaluator performs many procedure
+calls to do even the simplest things.
+
+It should be possible for @command{gawk} to convert the script's parse tree
+into a C program which the user would then compile, using the normal
+C compiler and a special @command{gawk} library to provide all the needed
+functions (regexps, fields, associative arrays, type coercion, and so on).
+
+@cindex @command{gawk}, interpreter@comma{} adding code to
+An easier possibility might be for an intermediate phase of @command{gawk} to
+convert the parse tree into a linear byte code form like the one used
+in GNU Emacs Lisp. The recursive evaluator would then be replaced by
+a straight line byte code interpreter that would be intermediate in speed
+between running a compiled program and doing what @command{gawk} does
+now.
+@end table
+
+Finally,
+the programs in the test suite could use documenting in this @value{DOCUMENT}.
+
+@xref{Additions},
+if you are interested in tackling any of these projects.
+@c ENDOFRANGE impis
+@c ENDOFRANGE gawii
+
+@node Basic Concepts
+@appendix Basic Programming Concepts
+@cindex programming, concepts
+@c STARTOFRANGE procon
+@cindex programming, concepts
+
+This @value{APPENDIX} attempts to define some of the basic concepts
+and terms that are used throughout the rest of this @value{DOCUMENT}.
+As this @value{DOCUMENT} is specifically about @command{awk},
+and not about computer programming in general, the coverage here
+is by necessity fairly cursory and simplistic.
+(If you need more background, there are many
+other introductory texts that you should refer to instead.)
+
+@menu
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+* Floating Point Issues:: Stuff to know about floating-point numbers.
+@end menu
+
+@node Basic High Level
+@appendixsec What a Program Does
+
+@cindex processing data
+At the most basic level, the job of a program is to process
+some input data and produce results.
+
+@c NEXT ED: Use real images here
+@iftex
+@tex
+\expandafter\ifx\csname graph\endcsname\relax \csname newbox\endcsname\graph\fi
+\expandafter\ifx\csname graphtemp\endcsname\relax \csname newdimen\endcsname\graphtemp\fi
+\setbox\graph=\vtop{\vskip 0pt\hbox{%
+ \special{pn 20}%
+ \special{pa 2425 200}%
+ \special{pa 2850 200}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 20}%
+ \special{pa 2750 175}%
+ \special{pa 2850 200}%
+ \special{pa 2750 225}%
+ \special{pa 2750 175}%
+ \special{fp}%
+ \special{pn 20}%
+ \special{pa 850 200}%
+ \special{pa 1250 200}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 20}%
+ \special{pa 1150 175}%
+ \special{pa 1250 200}%
+ \special{pa 1150 225}%
+ \special{pa 1150 175}%
+ \special{fp}%
+ \special{pn 20}%
+ \special{pa 2950 400}%
+ \special{pa 3650 400}%
+ \special{pa 3650 0}%
+ \special{pa 2950 0}%
+ \special{pa 2950 400}%
+ \special{fp}%
+ \special{pn 10}%
+ \special{ar 1800 200 450 200 0 6.28319}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 3.300in\lower\graphtemp\hbox to 0pt{\hss Results\hss}}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 1.800in\lower\graphtemp\hbox to 0pt{\hss Program\hss}}%
+ \special{pn 10}%
+ \special{pa 0 400}%
+ \special{pa 700 400}%
+ \special{pa 700 0}%
+ \special{pa 0 0}%
+ \special{pa 0 400}%
+ \special{fp}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 0.350in\lower\graphtemp\hbox to 0pt{\hss Data\hss}}%
+ \hbox{\vrule depth0.400in width0pt height 0pt}%
+ \kern 3.650in
+ }%
+}%
+\centerline{\box\graph}
+@end tex
+@end iftex
+@ifnottex
+@example
+ _______
++------+ / \ +---------+
+| Data | -----> < Program > -----> | Results |
++------+ \_______/ +---------+
+@end example
+@end ifnottex
+
+@cindex compiled programs
+@cindex interpreted programs
+The ``program'' in the figure can be either a compiled
+program@footnote{Compiled programs are typically written
+in lower-level languages such as C, C++, Fortran, or Ada,
+and then translated, or @dfn{compiled}, into a form that
+the computer can execute directly.}
+(such as @command{ls}),
+or it may be @dfn{interpreted}. In the latter case, a machine-executable
+program such as @command{awk} reads your program, and then uses the
+instructions in your program to process the data.
+
+@cindex programming, basic steps
+When you write a program, it usually consists
+of the following, very basic set of steps:
+
+@c NEXT ED: Use real images here
+@iftex
+@tex
+\expandafter\ifx\csname graph\endcsname\relax \csname newbox\endcsname\graph\fi
+\expandafter\ifx\csname graphtemp\endcsname\relax \csname newdimen\endcsname\graphtemp\fi
+\setbox\graph=\vtop{\vskip 0pt\hbox{%
+ \graphtemp=.5ex\advance\graphtemp by 0.600in
+ \rlap{\kern 2.800in\lower\graphtemp\hbox to 0pt{\hss Yes\hss}}%
+ \graphtemp=.5ex\advance\graphtemp by 0.100in
+ \rlap{\kern 3.300in\lower\graphtemp\hbox to 0pt{\hss No\hss}}%
+ \special{pn 8}%
+ \special{pa 2100 1000}%
+ \special{pa 1600 1000}%
+ \special{pa 1600 1000}%
+ \special{pa 1600 300}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 8}%
+ \special{pa 1575 400}%
+ \special{pa 1600 300}%
+ \special{pa 1625 400}%
+ \special{pa 1575 400}%
+ \special{fp}%
+ \special{pn 8}%
+ \special{pa 2600 500}%
+ \special{pa 2600 900}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 8}%
+ \special{pa 2625 800}%
+ \special{pa 2600 900}%
+ \special{pa 2575 800}%
+ \special{pa 2625 800}%
+ \special{fp}%
+ \special{pn 8}%
+ \special{pa 3200 200}%
+ \special{pa 4000 200}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 8}%
+ \special{pa 3900 175}%
+ \special{pa 4000 200}%
+ \special{pa 3900 225}%
+ \special{pa 3900 175}%
+ \special{fp}%
+ \special{pn 8}%
+ \special{pa 1400 200}%
+ \special{pa 2100 200}%
+ \special{fp}%
+ \special{sh 1.000}%
+ \special{pn 8}%
+ \special{pa 2000 175}%
+ \special{pa 2100 200}%
+ \special{pa 2000 225}%
+ \special{pa 2000 175}%
+ \special{fp}%
+ \special{pn 8}%
+ \special{ar 2600 1000 400 100 0 6.28319}%
+ \graphtemp=.5ex\advance\graphtemp by 1.000in
+ \rlap{\kern 2.600in\lower\graphtemp\hbox to 0pt{\hss Process\hss}}%
+ \special{pn 8}%
+ \special{pa 2200 400}%
+ \special{pa 3100 400}%
+ \special{pa 3100 0}%
+ \special{pa 2200 0}%
+ \special{pa 2200 400}%
+ \special{fp}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 2.688in\lower\graphtemp\hbox to 0pt{\hss More Data?\hss}}%
+ \special{pn 8}%
+ \special{ar 650 200 650 200 0 6.28319}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 0.613in\lower\graphtemp\hbox to 0pt{\hss Initialization\hss}}%
+ \special{pn 8}%
+ \special{ar 0 200 0 0 0 6.28319}%
+ \special{pn 8}%
+ \special{ar 4550 200 450 100 0 6.28319}%
+ \graphtemp=.5ex\advance\graphtemp by 0.200in
+ \rlap{\kern 4.600in\lower\graphtemp\hbox to 0pt{\hss Clean Up\hss}}%
+ \hbox{\vrule depth1.100in width0pt height 0pt}%
+ \kern 5.000in
+ }%
+}%
+\centerline{\box\graph}
+@end tex
+@end iftex
+@ifnottex
+@example
+ ______
++----------------+ / More \ No +----------+
+| Initialization | -------> < Data > -------> | Clean Up |
++----------------+ ^ \ ? / +----------+
+ | +--+-+
+ | | Yes
+ | |
+ | V
+ | +---------+
+ +-----+ Process |
+ +---------+
+@end example
+@end ifnottex
+
+@table @asis
+@item Initialization
+These are the things you do before actually starting to process
+data, such as checking arguments, initializing any data you need
+to work with, and so on.
+This step corresponds to @command{awk}'s @code{BEGIN} rule
+(@pxref{BEGIN/END}).
+
+If you were baking a cake, this might consist of laying out all the
+mixing bowls and the baking pan, and making sure you have all the
+ingredients that you need.
+
+@item Processing
+This is where the actual work is done. Your program reads data,
+one logical chunk at a time, and processes it as appropriate.
+
+In most programming languages, you have to manually manage the reading
+of data, checking to see if there is more each time you read a chunk.
+@command{awk}'s pattern-action paradigm
+(@pxref{Getting Started})
+handles the mechanics of this for you.
+
+In baking a cake, the processing corresponds to the actual labor:
+breaking eggs, mixing the flour, water, and other ingredients, and then putting the cake
+into the oven.
+
+@item Clean Up
+Once you've processed all the data, you may have things you need to
+do before exiting.
+This step corresponds to @command{awk}'s @code{END} rule
+(@pxref{BEGIN/END}).
+
+After the cake comes out of the oven, you still have to wrap it in
+plastic wrap to keep anyone from tasting it, as well as wash
+the mixing bowls and utensils.
+@end table
+
+@cindex algorithms
+An @dfn{algorithm} is a detailed set of instructions necessary to accomplish
+a task, or process data. It is much the same as a recipe for baking
+a cake. Programs implement algorithms. Often, it is up to you to design
+the algorithm and implement it, simultaneously.
+
+@cindex records
+@cindex fields
+The ``logical chunks'' we talked about previously are called @dfn{records},
+similar to the records a company keeps on employees, a school keeps for
+students, or a doctor keeps for patients.
+Each record has many component parts, such as first and last names,
+date of birth, address, and so on. The component parts are referred
+to as the @dfn{fields} of the record.
+
+The act of reading data is termed @dfn{input}, and that of
+generating results, not too surprisingly, is termed @dfn{output}.
+They are often referred to together as ``input/output,''
+and even more often, as ``I/O'' for short.
+(You will also see ``input'' and ``output'' used as verbs.)
+
+@cindex data-driven languages
+@cindex languages@comma{} data-driven
+@command{awk} manages the reading of data for you, as well as the
+breaking it up into records and fields. Your program's job is to
+tell @command{awk} what to with the data. You do this by describing
+@dfn{patterns} in the data to look for, and @dfn{actions} to execute
+when those patterns are seen. This @dfn{data-driven} nature of
+@command{awk} programs usually makes them both easier to write
+and easier to read.
+
+@node Basic Data Typing
+@appendixsec Data Values in a Computer
+
+@cindex variables
+In a program,
+you keep track of information and values in things called @dfn{variables}.
+A variable is just a name for a given value, such as @code{first_name},
+@code{last_name}, @code{address}, and so on.
+@command{awk} has several predefined variables, and it has
+special names to refer to the current input record
+and the fields of the record.
+You may also group multiple
+associated values under one name, as an array.
+
+@cindex values, numeric
+@cindex values, string
+@cindex scalar values
+Data, particularly in @command{awk}, consists of either numeric
+values, such as 42 or 3.1415927, or string values.
+String values are essentially anything that's not a number, such as a name.
+Strings are sometimes referred to as @dfn{character data}, since they
+store the individual characters that comprise them.
+Individual variables, as well as numeric and string variables, are
+referred to as @dfn{scalar} values.
+Groups of values, such as arrays, are not scalars.
+
+@cindex integers
+@cindex floating-point, numbers
+@cindex numbers, floating-point
+Within computers, there are two kinds of numeric values: @dfn{integers}
+and @dfn{floating-point}.
+In school, integer values were referred to as ``whole'' numbers---that is,
+numbers without any fractional part, such as 1, 42, or @minus{}17.
+The advantage to integer numbers is that they represent values exactly.
+The disadvantage is that their range is limited. On most modern systems,
+this range is @minus{}2,147,483,648 to 2,147,483,647.
+
+@cindex unsigned integers
+@cindex integers, unsigned
+Integer values come in two flavors: @dfn{signed} and @dfn{unsigned}.
+Signed values may be negative or positive, with the range of values just
+described.
+Unsigned values are always positive. On most modern systems,
+the range is from 0 to 4,294,967,295.
+
+@cindex double-precision floating-point
+@cindex single-precision floating-point
+Floating-point numbers represent what are called ``real'' numbers; i.e.,
+those that do have a fractional part, such as 3.1415927.
+The advantage to floating-point numbers is that they
+can represent a much larger range of values.
+The disadvantage is that there are numbers that they cannot represent
+exactly.
+@command{awk} uses @dfn{double-precision} floating-point numbers, which
+can hold more digits than @dfn{single-precision}
+floating-point numbers.
+Floating-point issues are discussed more fully in
+@ref{Floating Point Issues}.
+
+At the very lowest level, computers store values as groups of binary digits,
+or @dfn{bits}. Modern computers group bits into groups of eight, called @dfn{bytes}.
+Advanced applications sometimes have to manipulate bits directly,
+and @command{gawk} provides functions for doing so.
+
+@cindex null strings
+While you are probably used to the idea of a number without a value (i.e., zero),
+it takes a bit more getting used to the idea of zero-length character data.
+Nevertheless, such a thing exists.
+It is called the @dfn{null string}.
+The null string is character data that has no value.
+In other words, it is empty. It is written in @command{awk} programs
+like this: @code{""}.
+
+Humans are used to working in decimal; i.e., base 10. In base 10,
+numbers go from 0 to 9, and then ``roll over'' into the next
+column. (Remember grade school? 42 is 4 times 10 plus 2.)
+
+There are other number bases though. Computers commonly use base 2
+or @dfn{binary}, base 8 or @dfn{octal}, and base 16 or @dfn{hexadecimal}.
+In binary, each column represents two times the value in the column to
+its right. Each column may contain either a 0 or a 1.
+Thus, binary 1010 represents 1 times 8, plus 0 times 4, plus 1 times 2,
+plus 0 times 1, or decimal 10.
+Octal and hexadecimal are discussed more in
+@ref{Nondecimal-numbers}.
+
+Programs are written in programming languages.
+Hundreds, if not thousands, of programming languages exist.
+One of the most popular is the C programming language.
+The C language had a very strong influence on the design of
+the @command{awk} language.
+
+@cindex Kernighan, Brian
+@cindex Ritchie, Dennis
+There have been several versions of C. The first is often referred to
+as ``K&R'' C, after the initials of Brian Kernighan and Dennis Ritchie,
+the authors of the first book on C. (Dennis Ritchie created the language,
+and Brian Kernighan was one of the creators of @command{awk}.)
+
+In the mid-1980s, an effort began to produce an international standard
+for C. This work culminated in 1989, with the production of the ANSI
+standard for C. This standard became an ISO standard in 1990.
+Where it makes sense, POSIX @command{awk} is compatible with 1990 ISO C.
+
+In 1999, a revised ISO C standard was approved and released.
+Future versions of @command{gawk} will be as compatible as possible
+with this standard.
+
+@node Floating Point Issues
+@appendixsec Floating-Point Number Caveats
+
+As mentioned earlier, floating-point numbers represent what are called
+``real'' numbers, i.e., those that have a fractional part. @command{awk}
+uses double-precision floating-point numbers to represent all
+numeric values. This @value{SECTION} describes some of the issues
+involved in using floating-point numbers.
+
+There is a very nice paper on floating-point arithmetic by
+David Goldberg, ``What Every
+Computer Scientist Should Know About Floating-point Arithmetic,''
+@cite{ACM Computing Surveys} @strong{23}, 1 (1991-03),
+5-48.@footnote{@uref{http://www.validlab.com/goldberg/paper.ps}.}
+This is worth reading if you are interested in the details,
+but it does require a background in computer science.
+
+Internally, @command{awk} keeps both the numeric value
+(double-precision floating-point) and the string value for a variable.
+Separately, @command{awk} keeps
+track of what type the variable has
+(@pxref{Typing and Comparison}),
+which plays a role in how variables are used in comparisons.
+
+It is important to note that the string value for a number may not
+reflect the full value (all the digits) that the numeric value
+actually contains.
+The following program (@file{values.awk}) illustrates this:
+
+@example
+@{
+ $1 = $2 + $3
+ # see it for what it is
+ printf("$1 = %.12g\n", $1)
+ # use CONVFMT
+ a = "<" $1 ">"
+ print "a =", a
+@group
+ # use OFMT
+ print "$1 =", $1
+@end group
+@}
+@end example
+
+@noindent
+This program shows the full value of the sum of @code{$2} and @code{$3}
+using @code{printf}, and then prints the string values obtained
+from both automatic conversion (via @code{CONVFMT}) and
+from printing (via @code{OFMT}).
+
+Here is what happens when the program is run:
+
+@example
+$ echo 2 3.654321 1.2345678 | awk -f values.awk
+@print{} $1 = 4.8888888
+@print{} a = <4.88889>
+@print{} $1 = 4.88889
+@end example
+
+This makes it clear that the full numeric value is different from
+what the default string representations show.
+
+@code{CONVFMT}'s default value is @code{"%.6g"}, which yields a value with
+at least six significant digits. For some applications, you might want to
+change it to specify more precision.
+On most modern machines, most of the time,
+17 digits is enough to capture a floating-point number's
+value exactly.@footnote{Pathological cases can require up to
+752 digits (!), but we doubt that you need to worry about this.}
+
+@cindex floating-point
+Unlike numbers in the abstract sense (such as what you studied in high school
+or college math), numbers stored in computers are limited in certain ways.
+They cannot represent an infinite number of digits, nor can they always
+represent things exactly.
+In particular,
+floating-point numbers cannot
+always represent values exactly. Here is an example:
+
+@example
+$ awk '@{ printf("%010d\n", $1 * 100) @}'
+515.79
+@print{} 0000051579
+515.80
+@print{} 0000051579
+515.81
+@print{} 0000051580
+515.82
+@print{} 0000051582
+@kbd{@value{CTL}-d}
+@end example
+
+@noindent
+This shows that some values can be represented exactly,
+whereas others are only approximated. This is not a ``bug''
+in @command{awk}, but simply an artifact of how computers
+represent numbers.
+
+@cindex negative zero
+@cindex positive zero
+@cindex zero@comma{} negative vs.@: positive
+Another peculiarity of floating-point numbers on modern systems
+is that they often have more than one representation for the number zero!
+In particular, it is possible to represent ``minus zero'' as well as
+regular, or ``positive'' zero.
+
+This example shows that negative and positive zero are distinct values
+when stored internally, but that they are in fact equal to each other,
+as well as to ``regular'' zero:
+
+@smallexample
+$ gawk 'BEGIN @{ mz = -0 ; pz = 0
+> printf "-0 = %g, +0 = %g, (-0 == +0) -> %d\n", mz, pz, mz == pz
+> printf "mz == 0 -> %d, pz == 0 -> %d\n", mz == 0, pz == 0
+> @}'
+@print{} -0 = -0, +0 = 0, (-0 == +0) -> 1
+@print{} mz == 0 -> 1, pz == 0 -> 1
+@end smallexample
+
+It helps to keep this in mind should you process numeric data
+that contains negative zero values; the fact that the zero is negative
+is noted and can affect comparisons.
+@c ENDOFRANGE procon
+
+@node Glossary
+@unnumbered Glossary
+
+@table @asis
+@item Action
+A series of @command{awk} statements attached to a rule. If the rule's
+pattern matches an input record, @command{awk} executes the
+rule's action. Actions are always enclosed in curly braces.
+(@xref{Action Overview}.)
+
+@cindex Spencer, Henry
+@cindex @command{sed} utility
+@cindex amazing @command{awk} assembler (@command{aaa})
+@item Amazing @command{awk} Assembler
+Henry Spencer at the University of Toronto wrote a retargetable assembler
+completely as @command{sed} and @command{awk} scripts. It is thousands
+of lines long, including machine descriptions for several eight-bit
+microcomputers. It is a good example of a program that would have been
+better written in another language.
+You can get it from @uref{ftp://ftp.freefriends.org/arnold/Awkstuff/aaa.tgz}.
+
+@cindex amazingly workable formatter (@command{awf})
+@cindex @command{awf} (amazingly workable formatter) program
+@item Amazingly Workable Formatter (@command{awf})
+Henry Spencer at the University of Toronto wrote a formatter that accepts
+a large subset of the @samp{nroff -ms} and @samp{nroff -man} formatting
+commands, using @command{awk} and @command{sh}.
+It is available over the Internet
+from @uref{ftp://ftp.freefriends.org/arnold/Awkstuff/awf.tgz}.
+
+@item Anchor
+The regexp metacharacters @samp{^} and @samp{$}, which force the match
+to the beginning or end of the string, respectively.
+
+@cindex ANSI
+@item ANSI
+The American National Standards Institute. This organization produces
+many standards, among them the standards for the C and C++ programming
+languages.
+These standards often become international standards as well. See also
+``ISO.''
+
+@item Array
+A grouping of multiple values under the same name.
+Most languages just provide sequential arrays.
+@command{awk} provides associative arrays.
+
+@item Assertion
+A statement in a program that a condition is true at this point in the program.
+Useful for reasoning about how a program is supposed to behave.
+
+@item Assignment
+An @command{awk} expression that changes the value of some @command{awk}
+variable or data object. An object that you can assign to is called an
+@dfn{lvalue}. The assigned values are called @dfn{rvalues}.
+@xref{Assignment Ops}.
+
+@item Associative Array
+Arrays in which the indices may be numbers or strings, not just
+sequential integers in a fixed range.
+
+@item @command{awk} Language
+The language in which @command{awk} programs are written.
+
+@item @command{awk} Program
+An @command{awk} program consists of a series of @dfn{patterns} and
+@dfn{actions}, collectively known as @dfn{rules}. For each input record
+given to the program, the program's rules are all processed in turn.
+@command{awk} programs may also contain function definitions.
+
+@item @command{awk} Script
+Another name for an @command{awk} program.
+
+@item Bash
+The GNU version of the standard shell
+@ifnotinfo
+(the @b{B}ourne-@b{A}gain @b{SH}ell).
+@end ifnotinfo
+@ifinfo
+(the Bourne-Again SHell).
+@end ifinfo
+See also ``Bourne Shell.''
+
+@item BBS
+See ``Bulletin Board System.''
+
+@item Bit
+Short for ``Binary Digit.''
+All values in computer memory ultimately reduce to binary digits: values
+that are either zero or one.
+Groups of bits may be interpreted differently---as integers,
+floating-point numbers, character data, addresses of other
+memory objects, or other data.
+@command{awk} lets you work with floating-point numbers and strings.
+@command{gawk} lets you manipulate bit values with the built-in
+functions described in
+@ref{Bitwise Functions}.
+
+Computers are often defined by how many bits they use to represent integer
+values. Typical systems are 32-bit systems, but 64-bit systems are
+becoming increasingly popular, and 16-bit systems are waning in
+popularity.
+
+@item Boolean Expression
+Named after the English mathematician Boole. See also ``Logical Expression.''
+
+@item Bourne Shell
+The standard shell (@file{/bin/sh}) on Unix and Unix-like systems,
+originally written by Steven R.@: Bourne.
+Many shells (@command{bash}, @command{ksh}, @command{pdksh}, @command{zsh}) are
+generally upwardly compatible with the Bourne shell.
+
+@item Built-in Function
+The @command{awk} language provides built-in functions that perform various
+numerical, I/O-related, and string computations. Examples are
+@code{sqrt} (for the square root of a number) and @code{substr} (for a
+substring of a string).
+@command{gawk} provides functions for timestamp management, bit manipulation,
+and runtime string translation.
+(@xref{Built-in}.)
+
+@item Built-in Variable
+@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},
+and
+@code{SUBSEP}
+are the variables that have special meaning to @command{awk}.
+In addition,
+@code{ARGIND},
+@code{BINMODE},
+@code{ERRNO},
+@code{FIELDWIDTHS},
+@code{IGNORECASE},
+@code{LINT},
+@code{PROCINFO},
+@code{RT},
+and
+@code{TEXTDOMAIN}
+are the variables that have special meaning to @command{gawk}.
+Changing some of them affects @command{awk}'s running environment.
+(@xref{Built-in Variables}.)
+
+@item Braces
+See ``Curly Braces.''
+
+@item Bulletin Board System
+A computer system allowing users to log in and read and/or leave messages
+for other users of the system, much like leaving paper notes on a bulletin
+board.
+
+@item C
+The system programming language that most GNU software is written in. The
+@command{awk} programming language has C-like syntax, and this @value{DOCUMENT}
+points out similarities between @command{awk} and C when appropriate.
+
+In general, @command{gawk} attempts to be as similar to the 1990 version
+of ISO C as makes sense. Future versions of @command{gawk} may adopt features
+from the newer 1999 standard, as appropriate.
+
+@item C++
+A popular object-oriented programming language derived from C.
+
+@cindex ISO 8859-1
+@cindex ISO Latin-1
+@cindex character sets (machine character encodings)
+@item Character Set
+The set of numeric codes used by a computer system to represent the
+characters (letters, numbers, punctuation, etc.) of a particular country
+or place. The most common character set in use today is ASCII (American
+Standard Code for Information Interchange). Many European
+countries use an extension of ASCII known as ISO-8859-1 (ISO Latin-1).
+
+@cindex @command{chem} utility
+@item CHEM
+A preprocessor for @command{pic} that reads descriptions of molecules
+and produces @command{pic} input for drawing them.
+It was written in @command{awk}
+by Brian Kernighan and Jon Bentley, and is available from
+@uref{http://cm.bell-labs.com/netlib/typesetting/chem.gz}.
+
+@item Coprocess
+A subordinate program with which two-way communications is possible.
+
+@cindex compiled programs
+@item Compiler
+A program that translates human-readable source code into
+machine-executable object code. The object code is then executed
+directly by the computer.
+See also ``Interpreter.''
+
+@item Compound Statement
+A series of @command{awk} statements, enclosed in curly braces. Compound
+statements may be nested.
+(@xref{Statements}.)
+
+@item Concatenation
+Concatenating two strings means sticking them together, one after another,
+producing a new string. For example, the string @samp{foo} concatenated with
+the string @samp{bar} gives the string @samp{foobar}.
+(@xref{Concatenation}.)
+
+@item Conditional Expression
+An expression using the @samp{?:} ternary operator, such as
+@samp{@var{expr1} ? @var{expr2} : @var{expr3}}. The expression
+@var{expr1} is evaluated; if the result is true, the value of the whole
+expression is the value of @var{expr2}; otherwise the value is
+@var{expr3}. In either case, only one of @var{expr2} and @var{expr3}
+is evaluated. (@xref{Conditional Exp}.)
+
+@item Comparison Expression
+A relation that is either true or false, such as @samp{(a < b)}.
+Comparison expressions are used in @code{if}, @code{while}, @code{do},
+and @code{for}
+statements, and in patterns to select which input records to process.
+(@xref{Typing and Comparison}.)
+
+@item Curly Braces
+The characters @samp{@{} and @samp{@}}. Curly braces are used in
+@command{awk} for delimiting actions, compound statements, and function
+bodies.
+
+@cindex dark corner
+@item Dark Corner
+An area in the language where specifications often were (or still
+are) not clear, leading to unexpected or undesirable behavior.
+Such areas are marked in this @value{DOCUMENT} with
+@iftex
+the picture of a flashlight in the margin
+@end iftex
+@ifnottex
+``(d.c.)'' in the text
+@end ifnottex
+and are indexed under the heading ``dark corner.''
+
+@item Data Driven
+A description of @command{awk} programs, where you specify the data you
+are interested in processing, and what to do when that data is seen.
+
+@item Data Objects
+These are numbers and strings of characters. Numbers are converted into
+strings and vice versa, as needed.
+(@xref{Conversion}.)
+
+@item Deadlock
+The situation in which two communicating processes are each waiting
+for the other to perform an action.
+
+@item Double-Precision
+An internal representation of numbers that can have fractional parts.
+Double-precision numbers keep track of more digits than do single-precision
+numbers, but operations on them are sometimes more expensive. This is the way
+@command{awk} stores numeric values. It is the C type @code{double}.
+
+@item Dynamic Regular Expression
+A dynamic regular expression is a regular expression written as an
+ordinary expression. It could be a string constant, such as
+@code{"foo"}, but it may also be an expression whose value can vary.
+(@xref{Computed Regexps}.)
+
+@item Environment
+A collection of strings, of the form @var{name@code{=}val}, that each
+program has available to it. Users generally place values into the
+environment in order to provide information to various programs. Typical
+examples are the environment variables @env{HOME} and @env{PATH}.
+
+@item Empty String
+See ``Null String.''
+
+@cindex epoch, definition of
+@item Epoch
+The date used as the ``beginning of time'' for timestamps.
+Time values in Unix systems are represented as seconds since the epoch,
+with library functions available for converting these values into
+standard date and time formats.
+
+The epoch on Unix and POSIX systems is 1970-01-01 00:00:00 UTC.
+See also ``GMT'' and ``UTC.''
+
+@item Escape Sequences
+A special sequence of characters used for describing nonprinting
+characters, such as @samp{\n} for newline or @samp{\033} for the ASCII
+ESC (Escape) character. (@xref{Escape Sequences}.)
+
+@item FDL
+See ``Free Documentation License.''
+
+@item Field
+When @command{awk} reads an input record, it splits the record into pieces
+separated by whitespace (or by a separator regexp that you can
+change by setting the built-in variable @code{FS}). Such pieces are
+called fields. If the pieces are of fixed length, you can use the built-in
+variable @code{FIELDWIDTHS} to describe their lengths.
+(@xref{Field Separators},
+and
+@ref{Constant Size}.)
+
+@item Flag
+A variable whose truth value indicates the existence or nonexistence
+of some condition.
+
+@item Floating-Point Number
+Often referred to in mathematical terms as a ``rational'' or real number,
+this is just a number that can have a fractional part.
+See also ``Double-Precision'' and ``Single-Precision.''
+
+@item Format
+Format strings are used to control the appearance of output in the
+@code{strftime} and @code{sprintf} functions, and are used in the
+@code{printf} statement as well. Also, data conversions from numbers to strings
+are controlled by the format string contained in the built-in variable
+@code{CONVFMT}. (@xref{Control Letters}.)
+
+@item Free Documentation License
+This document describes the terms under which this @value{DOCUMENT}
+is published and may be copied. (@xref{GNU Free Documentation License}.)
+
+@item Function
+A specialized group of statements used to encapsulate general
+or program-specific tasks. @command{awk} has a number of built-in
+functions, and also allows you to define your own.
+(@xref{Functions}.)
+
+@item FSF
+See ``Free Software Foundation.''
+
+@cindex FSF (Free Software Foundation)
+@cindex Free Software Foundation (FSF)
+@cindex Stallman, Richard
+@item Free Software Foundation
+A nonprofit organization dedicated
+to the production and distribution of freely distributable software.
+It was founded by Richard M.@: Stallman, the author of the original
+Emacs editor. GNU Emacs is the most widely used version of Emacs today.
+
+@item @command{gawk}
+The GNU implementation of @command{awk}.
+
+@cindex GPL (General Public License)
+@cindex General Public License (GPL)
+@cindex GNU General Public License
+@item General Public License
+This document describes the terms under which @command{gawk} and its source
+code may be distributed. (@xref{Copying}.)
+
+@item GMT
+``Greenwich Mean Time.''
+This is the old term for UTC.
+It is the time of day used as the epoch for Unix and POSIX systems.
+See also ``Epoch'' and ``UTC.''
+
+@cindex FSF (Free Software Foundation)
+@cindex Free Software Foundation (FSF)
+@cindex GNU Project
+@item GNU
+``GNU's not Unix''. An on-going project of the Free Software Foundation
+to create a complete, freely distributable, POSIX-compliant computing
+environment.
+
+@item GNU/Linux
+A variant of the GNU system using the Linux kernel, instead of the
+Free Software Foundation's Hurd kernel.
+Linux is a stable, efficient, full-featured clone of Unix that has
+been ported to a variety of architectures.
+It is most popular on PC-class systems, but runs well on a variety of
+other systems too.
+The Linux kernel source code is available under the terms of the GNU General
+Public License, which is perhaps its most important aspect.
+
+@item GPL
+See ``General Public License.''
+
+@item Hexadecimal
+Base 16 notation, where the digits are @code{0}--@code{9} and
+@code{A}--@code{F}, with @samp{A}
+representing 10, @samp{B} representing 11, and so on, up to @samp{F} for 15.
+Hexadecimal numbers are written in C using a leading @samp{0x},
+to indicate their base. Thus, @code{0x12} is 18 (1 times 16 plus 2).
+
+@item I/O
+Abbreviation for ``Input/Output,'' the act of moving data into and/or
+out of a running program.
+
+@item Input Record
+A single chunk of data that is read in by @command{awk}. Usually, an @command{awk} input
+record consists of one line of text.
+(@xref{Records}.)
+
+@item Integer
+A whole number, i.e., a number that does not have a fractional part.
+
+@item Internationalization
+The process of writing or modifying a program so
+that it can use multiple languages without requiring
+further source code changes.
+
+@cindex interpreted programs
+@item Interpreter
+A program that reads human-readable source code directly, and uses
+the instructions in it to process data and produce results.
+@command{awk} is typically (but not always) implemented as an interpreter.
+See also ``Compiler.''
+
+@item Interval Expression
+A component of a regular expression that lets you specify repeated matches of
+some part of the regexp. Interval expressions were not traditionally available
+in @command{awk} programs.
+
+@cindex ISO
+@item ISO
+The International Standards Organization.
+This organization produces international standards for many things, including
+programming languages, such as C and C++.
+In the computer arena, important standards like those for C, C++, and POSIX
+become both American national and ISO international standards simultaneously.
+This @value{DOCUMENT} refers to Standard C as ``ISO C'' throughout.
+
+@item Keyword
+In the @command{awk} language, a keyword is a word that has special
+meaning. Keywords are reserved and may not be used as variable names.
+
+@command{gawk}'s keywords are:
+@code{BEGIN},
+@code{END},
+@code{if},
+@code{else},
+@code{while},
+@code{do@dots{}while},
+@code{for},
+@code{for@dots{}in},
+@code{break},
+@code{continue},
+@code{delete},
+@code{next},
+@code{nextfile},
+@code{function},
+@code{func},
+and
+@code{exit}.
+
+@cindex LGPL (Lesser General Public License)
+@cindex Lesser General Public License (LGPL)
+@cindex GNU Lesser General Public License
+@item Lesser General Public License
+This document describes the terms under which binary library archives
+or shared objects,
+and their source code may be distributed.
+
+@item Linux
+See ``GNU/Linux.''
+
+@item LGPL
+See ``Lesser General Public License.''
+
+@item Localization
+The process of providing the data necessary for an
+internationalized program to work in a particular language.
+
+@item Logical Expression
+An expression using the operators for logic, AND, OR, and NOT, written
+@samp{&&}, @samp{||}, and @samp{!} in @command{awk}. Often called Boolean
+expressions, after the mathematician who pioneered this kind of
+mathematical logic.
+
+@item Lvalue
+An expression that can appear on the left side of an assignment
+operator. In most languages, lvalues can be variables or array
+elements. In @command{awk}, a field designator can also be used as an
+lvalue.
+
+@item Matching
+The act of testing a string against a regular expression. If the
+regexp describes the contents of the string, it is said to @dfn{match} it.
+
+@item Metacharacters
+Characters used within a regexp that do not stand for themselves.
+Instead, they denote regular expression operations, such as repetition,
+grouping, or alternation.
+
+@item Null String
+A string with no characters in it. It is represented explicitly in
+@command{awk} programs by placing two double quote characters next to
+each other (@code{""}). It can appear in input data by having two successive
+occurrences of the field separator appear next to each other.
+
+@item Number
+A numeric-valued data object. Modern @command{awk} implementations use
+double-precision floating-point to represent numbers.
+Very old @command{awk} implementations use single-precision floating-point.
+
+@item Octal
+Base-eight notation, where the digits are @code{0}--@code{7}.
+Octal numbers are written in C using a leading @samp{0},
+to indicate their base. Thus, @code{013} is 11 (one times 8 plus 3).
+
+@cindex P1003.2 POSIX standard
+@item P1003.2
+See ``POSIX.''
+
+@item Pattern
+Patterns tell @command{awk} which input records are interesting to which
+rules.
+
+A pattern is an arbitrary conditional expression against which input is
+tested. If the condition is satisfied, the pattern is said to @dfn{match}
+the input record. A typical pattern might compare the input record against
+a regular expression. (@xref{Pattern Overview}.)
+
+@item POSIX
+The name for a series of standards
+@c being developed by the IEEE
+that specify a Portable Operating System interface. The ``IX'' denotes
+the Unix heritage of these standards. The main standard of interest for
+@command{awk} users is
+@cite{IEEE Standard for Information Technology, Standard 1003.2-1992,
+Portable Operating System Interface (POSIX) Part 2: Shell and Utilities}.
+Informally, this standard is often referred to as simply ``P1003.2.''
+
+@item Precedence
+The order in which operations are performed when operators are used
+without explicit parentheses.
+
+@item Private
+Variables and/or functions that are meant for use exclusively by library
+functions and not for the main @command{awk} program. Special care must be
+taken when naming such variables and functions.
+(@xref{Library Names}.)
+
+@item Range (of input lines)
+A sequence of consecutive lines from the input file(s). A pattern
+can specify ranges of input lines for @command{awk} to process or it can
+specify single lines. (@xref{Pattern Overview}.)
+
+@item Recursion
+When a function calls itself, either directly or indirectly.
+If this isn't clear, refer to the entry for ``recursion.''
+
+@item Redirection
+Redirection means performing input from something other than the standard input
+stream, or performing output to something other than the standard output stream.
+
+You can redirect the output of the @code{print} and @code{printf} statements
+to a file or a system command, using the @samp{>}, @samp{>>}, @samp{|}, and @samp{|&}
+operators. You can redirect input to the @code{getline} statement using
+the @samp{<}, @samp{|}, and @samp{|&} operators.
+(@xref{Redirection},
+and @ref{Getline}.)
+
+@item Regexp
+Short for @dfn{regular expression}. A regexp is a pattern that denotes a
+set of strings, possibly an infinite set. For example, the regexp
+@samp{R.*xp} matches any string starting with the letter @samp{R}
+and ending with the letters @samp{xp}. In @command{awk}, regexps are
+used in patterns and in conditional expressions. Regexps may contain
+escape sequences. (@xref{Regexp}.)
+
+@item Regular Expression
+See ``regexp.''
+
+@item Regular Expression Constant
+A regular expression constant is a regular expression written within
+slashes, such as @code{/foo/}. This regular expression is chosen
+when you write the @command{awk} program and cannot be changed during
+its execution. (@xref{Regexp Usage}.)
+
+@item Rule
+A segment of an @command{awk} program that specifies how to process single
+input records. A rule consists of a @dfn{pattern} and an @dfn{action}.
+@command{awk} reads an input record; then, for each rule, if the input record
+satisfies the rule's pattern, @command{awk} executes the rule's action.
+Otherwise, the rule does nothing for that input record.
+
+@item Rvalue
+A value that can appear on the right side of an assignment operator.
+In @command{awk}, essentially every expression has a value. These values
+are rvalues.
+
+@item Scalar
+A single value, be it a number or a string.
+Regular variables are scalars; arrays and functions are not.
+
+@item Search Path
+In @command{gawk}, a list of directories to search for @command{awk} program source files.
+In the shell, a list of directories to search for executable programs.
+
+@item Seed
+The initial value, or starting point, for a sequence of random numbers.
+
+@item @command{sed}
+See ``Stream Editor.''
+
+@item Shell
+The command interpreter for Unix and POSIX-compliant systems.
+The shell works both interactively, and as a programming language
+for batch files, or shell scripts.
+
+@item Short-Circuit
+The nature of the @command{awk} logical operators @samp{&&} and @samp{||}.
+If the value of the entire expression is determinable from evaluating just
+the lefthand side of these operators, the righthand side is not
+evaluated.
+(@xref{Boolean Ops}.)
+
+@item Side Effect
+A side effect occurs when an expression has an effect aside from merely
+producing a value. Assignment expressions, increment and decrement
+expressions, and function calls have side effects.
+(@xref{Assignment Ops}.)
+
+@item Single-Precision
+An internal representation of numbers that can have fractional parts.
+Single-precision numbers keep track of fewer digits than do double-precision
+numbers, but operations on them are sometimes less expensive in terms of CPU time.
+This is the type used by some very old versions of @command{awk} to store
+numeric values. It is the C type @code{float}.
+
+@item Space
+The character generated by hitting the space bar on the keyboard.
+
+@item Special File
+A @value{FN} interpreted internally by @command{gawk}, instead of being handed
+directly to the underlying operating system---for example, @file{/dev/stderr}.
+(@xref{Special Files}.)
+
+@item Stream Editor
+A program that reads records from an input stream and processes them one
+or more at a time. This is in contrast with batch programs, which may
+expect to read their input files in entirety before starting to do
+anything, as well as with interactive programs which require input from the
+user.
+
+@item String
+A datum consisting of a sequence of characters, such as @samp{I am a
+string}. Constant strings are written with double quotes in the
+@command{awk} language and may contain escape sequences.
+(@xref{Escape Sequences}.)
+
+@item Tab
+The character generated by hitting the @kbd{TAB} key on the keyboard.
+It usually expands to up to eight spaces upon output.
+
+@item Text Domain
+A unique name that identifies an application.
+Used for grouping messages that are translated at runtime
+into the local language.
+
+@item Timestamp
+A value in the ``seconds since the epoch'' format used by Unix
+and POSIX systems. Used for the @command{gawk} functions
+@code{mktime}, @code{strftime}, and @code{systime}.
+See also ``Epoch'' and ``UTC.''
+
+@cindex Linux
+@cindex GNU/Linux
+@cindex Unix
+@cindex BSD-based operating systems
+@cindex NetBSD
+@cindex FreeBSD
+@cindex OpenBSD
+@item Unix
+A computer operating system originally developed in the early 1970's at
+AT&T Bell Laboratories. It initially became popular in universities around
+the world and later moved into commercial environments as a software
+development system and network server system. There are many commercial
+versions of Unix, as well as several work-alike systems whose source code
+is freely available (such as GNU/Linux, NetBSD, FreeBSD, and OpenBSD).
+
+@item UTC
+The accepted abbreviation for ``Universal Coordinated Time.''
+This is standard time in Greenwich, England, which is used as a
+reference time for day and date calculations.
+See also ``Epoch'' and ``GMT.''
+
+@item Whitespace
+A sequence of space, TAB, or newline characters occurring inside an input
+record or a string.
+@end table
+
+@node Copying
+@unnumbered GNU General Public License
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@c fakenode --- for prepinfo
+@unnumberedsec Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@ifnotinfo
+@c fakenode --- for prepinfo
+@unnumberedsec Terms and Conditions for Copying, Distribution and Modification
+@end ifnotinfo
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate 0
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@ifnotinfo
+@c fakenode --- for prepinfo
+@heading NO WARRANTY
+@end ifnotinfo
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW@. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE@. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU@. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@ifnotinfo
+@c fakenode --- for prepinfo
+@heading END OF TERMS AND CONDITIONS
+@end ifnotinfo
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@c fakenode --- for prepinfo
+@unnumberedsec How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and an idea of what it does.}
+Copyright (C) @var{year} @var{name of author}
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) @var{year} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'. This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+@group
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end group
+@end smallexample
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+@node GNU Free Documentation License
+@unnumbered GNU Free Documentation License
+
+@cindex FDL (Free Documentation License)
+@cindex Free Documentation License (FDL)
+@cindex GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warrany Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@c fakenode --- for prepinfo
+@unnumberedsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
+
+@node Index
+@unnumbered Index
+@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.
+
+2. The default AWKPATH search path should be configurable via `configure'
+ The default and how this changes needs to be documented.
+
+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{...}). This is
+ a change from earlier versions.
+ " " should have an @w{} around it
+ Use "non-" only with language names or acronyms, or the words bug and option
+ 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 "zeros" instead of "zeroes".
+ Use "nonzero" not "non-zero".
+ Use "runtime" not "run time" or "run-time".
+ Use "command-line" not "command line".
+ 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 @code{do}, and not @code{do}-@code{while}, except where
+ actually discussing the do-while.
+ Use "versus" in text and "vs." in index entries
+ 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.
+ In tables, put command-line options in @code, while in the text,
+ put them in @option.
+ When using @strong, use "Note:" or "Caution:" with colons and
+ not exclamation points. Do not surround the paragraphs
+ with @quotation ... @end quotation.
+ 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.
+
+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:
+------------
+Enhance FIELDWIDTHS with some way to indicate "the rest of the record".
+E.g., a length of 0 or -1 or something. May be "n"?
+
+Make FIELDWIDTHS be an array?
+
+% Next edition:
+% 1. Talk about common extensions, those in nawk, gawk, mawk
+% 2. Use @code{foo} for variables and @code{foo()} for functions
+% 3. Standardize the error messages from the functions and programs
+% in Chapters 12 and 13.
+% 4. Nuke the BBS stuff and use something that won't be obsolete
+% 5. Reorg chapters 5 & 7 like so:
+%Chapter 5:
+% - Constants, Variables, and Conversions
+% + Constant Expressions
+% + Using Regular Expression Constants
+% + Variables
+% + Conversion of Strings and Numbers
+% - Operators
+% + Arithmetic Operators
+% + String Concatenation
+% + Assignment Expressions
+% + Increment and Decrement Operators
+% - Truth Values and Conditions
+% + True and False in Awk
+% + Boolean Expressions
+% + Conditional Expressions
+% - Function Calls
+% - Operator Precedence
+%
+%Chapter 7:
+% - Array Basics
+% + Introduction to Arrays
+% + Referring to an Array Element
+% + Assigning Array Elements
+% + Basic Array Example
+% + Scanning All Elements of an Array
+% - The delete Statement
+% - Using Numbers to Subscript Arrays
+% - Using Uninitialized Variables as Subscripts
+% - Multidimensional Arrays
+% + Scanning Multidimensional Arrays
+% - Sorting Array Values and Indices with gawk
--- /dev/null
+This is gawkinet.info, produced by makeinfo version 4.6 from
+gawkinet.texi.
+
+INFO-DIR-SECTION Network applications
+START-INFO-DIR-ENTRY
+* Gawkinet: (gawkinet). TCP/IP Internetworking With `gawk'.
+END-INFO-DIR-ENTRY
+
+This is Edition 1.1 of `TCP/IP Internetworking With `gawk'', for the
+3.1.4 (or later) version of the GNU implementation of AWK.
+
+
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License", the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+ a. "A GNU Manual"
+
+ b. "You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development."
+
+ This file documents the networking features in GNU `awk'.
+
+This is Edition 1.1 of `TCP/IP Internetworking With `gawk'', for the
+3.1.4 (or later) version of the GNU implementation of AWK.
+
+
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License", the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+ a. "A GNU Manual"
+
+ b. "You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development."
+
+\1f
+File: gawkinet.info, Node: Top, Next: Preface, Prev: (dir), Up: (dir)
+
+General Introduction
+********************
+
+This file documents the networking features in GNU Awk (`gawk') version
+3.1 and later.
+
+This is Edition 1.1 of `TCP/IP Internetworking With `gawk'', for the
+3.1.4 (or later) version of the GNU implementation of AWK.
+
+
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License", the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+ a. "A GNU Manual"
+
+ b. "You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development."
+
+* Menu:
+
+* Preface:: About this document.
+* Introduction:: About networkiing.
+* Using Networking:: Some examples.
+* Some Applications and Techniques:: More extended examples.
+* Links:: Where to find the stuff mentioned in this
+ document.
+* GNU Free Documentation License:: The license for this document.
+* Index:: The index.
+
+* Stream Communications:: Sending data streams.
+* Datagram Communications:: Sending self-contained messages.
+* The TCP/IP Protocols:: How these models work in the Internet.
+* Basic Protocols:: The basic protocols.
+* Ports:: The idea behind ports.
+* Making Connections:: Making TCP/IP connections.
+* Gawk Special Files:: How to do `gawk' networking.
+* Special File Fields:: The fields in the special file name.
+* Comparing Protocols:: Differences between the protocols.
+* File /inet/tcp:: The TCP special file.
+* File /inet/udp:: The UDP special file.
+* File /inet/raw:: The RAW special file.
+* TCP Connecting:: Making a TCP connection.
+* Troubleshooting:: Troubleshooting TCP/IP connections.
+* Interacting:: Interacting with a service.
+* Setting Up:: Setting up a service.
+* Email:: Reading email.
+* Web page:: Reading a Web page.
+* Primitive Service:: A primitive Web service.
+* Interacting Service:: A Web service with interaction.
+* CGI Lib:: A simple CGI library.
+* Simple Server:: A simple Web server.
+* Caveats:: Network programming caveats.
+* Challenges:: Where to go from here.
+* PANIC:: An Emergency Web Server.
+* GETURL:: Retrieving Web Pages.
+* REMCONF:: Remote Configuration Of Embedded Systems.
+* URLCHK:: Look For Changed Web Pages.
+* WEBGRAB:: Extract Links From A Page.
+* STATIST:: Graphing A Statistical Distribution.
+* MAZE:: Walking Through A Maze In Virtual Reality.
+* MOBAGWHO:: A Simple Mobile Agent.
+* STOXPRED:: Stock Market Prediction As A Service.
+* PROTBASE:: Searching Through A Protein Database.
+
+\1f
+File: gawkinet.info, Node: Preface, Next: Introduction, Prev: Top, Up: Top
+
+Preface
+*******
+
+In May of 1997, Ju"rgen Kahrs felt the need for network access from
+`awk', and, with a little help from me, set about adding features to do
+this for `gawk'. At that time, he wrote the bulk of this Info file.
+
+ The code and documentation were added to the `gawk' 3.1 development
+tree, and languished somewhat until I could finally get down to some
+serious work on that version of `gawk'. This finally happened in the
+middle of 2000.
+
+ Meantime, Ju"rgen wrote an article about the Internet special files
+and `|&' operator for `Linux Journal', and made a networking patch for
+the production versions of `gawk' available from his home page. In
+August of 2000 (for `gawk' 3.0.6), this patch also made it to the main
+GNU `ftp' distribution site.
+
+ For release with `gawk', I edited Ju"rgen's prose for English
+grammar and style, as he is not a native English speaker. I also
+rearranged the material somewhat for what I felt was a better order of
+presentation, and (re)wrote some of the introductory material.
+
+ The majority of this document and the code are his work, and the
+high quality and interesting ideas speak for themselves. It is my hope
+that these features will be of significant value to the `awk' community.
+
+
+Arnold Robbins
+Nof Ayalon, ISRAEL
+March, 2001
+
+\1f
+File: gawkinet.info, Node: Introduction, Next: Using Networking, Prev: Preface, Up: Top
+
+1 Networking Concepts
+*********************
+
+This major node provides a (necessarily) brief intoduction to computer
+networking concepts. For many applications of `gawk' to TCP/IP
+networking, we hope that this is enough. For more advanced tasks, you
+will need deeper background, and it may be necessary to switch to
+lower-level programming in C or C++.
+
+ There are two real-life models for the way computers send messages
+to each other over a network. While the analogies are not perfect,
+they are close enough to convey the major concepts. These two models
+are the phone system (reliable byte-stream communications), and the
+postal system (best-effort datagrams).
+
+* Menu:
+
+* Stream Communications:: Sending data streams.
+* Datagram Communications:: Sending self-contained messages.
+* The TCP/IP Protocols:: How these models work in the Internet.
+* Making Connections:: Making TCP/IP connections.
+
+\1f
+File: gawkinet.info, Node: Stream Communications, Next: Datagram Communications, Prev: Introduction, Up: Introduction
+
+1.1 Reliable Byte-streams (Phone Calls)
+=======================================
+
+When you make a phone call, the following steps occur:
+
+ 1. You dial a number.
+
+ 2. The phone system connects to the called party, telling them there
+ is an incoming call. (Their phone rings.)
+
+ 3. The other party answers the call, or, in the case of a computer
+ network, refuses to answer the call.
+
+ 4. Assuming the other party answers, the connection between you is
+ now a "duplex" (two-way), "reliable" (no data lost), sequenced
+ (data comes out in the order sent) data stream.
+
+ 5. You and your friend may now talk freely, with the phone system
+ moving the data (your voices) from one end to the other. From
+ your point of view, you have a direct end-to-end connection with
+ the person on the other end.
+
+ The same steps occur in a duplex reliable computer networking
+connection. There is considerably more overhead in setting up the
+communications, but once it's done, data moves in both directions,
+reliably, in sequence.
+
+\1f
+File: gawkinet.info, Node: Datagram Communications, Next: The TCP/IP Protocols, Prev: Stream Communications, Up: Introduction
+
+1.2 Best-effort Datagrams (Mailed Letters)
+==========================================
+
+Suppose you mail three different documents to your office on the other
+side of the country on two different days. Doing so entails the
+following.
+
+ 1. Each document travels in its own envelope.
+
+ 2. Each envelope contains both the sender and the recipient address.
+
+ 3. Each envelope may travel a different route to its destination.
+
+ 4. The envelopes may arrive in a different order from the one in
+ which they were sent.
+
+ 5. One or more may get lost in the mail. (Although, fortunately,
+ this does not occur very often.)
+
+ 6. In a computer network, one or more "packets" may also arrive
+ multiple times. (This doesn't happen with the postal system!)
+
+
+ The important characteristics of datagram communications, like those
+of the postal system are thus:
+
+ * Delivery is "best effort;" the data may never get there.
+
+ * Each message is self-contained, including the source and
+ destination addresses.
+
+ * Delivery is _not_ sequenced; packets may arrive out of order,
+ and/or multiple times.
+
+ * Unlike the phone system, overhead is considerably lower. It is
+ not necessary to set up the call first.
+
+ The price the user pays for the lower overhead of datagram
+communications is exactly the lower reliability; it is often necessary
+for user-level protocols that use datagram communications to add their
+own reliability features on top of the basic communications.
+
+\1f
+File: gawkinet.info, Node: The TCP/IP Protocols, Next: Making Connections, Prev: Datagram Communications, Up: Introduction
+
+1.3 The Internet Protocols
+==========================
+
+The Internet Protocol Suite (usually referred to as just TCP/IP)(1)
+consists of a number of different protocols at different levels or
+"layers." For our purposes, three protocols provide the fundamental
+communications mechanisms. All other defined protocols are referred to
+as user-level protocols (e.g., HTTP, used later in this Info file).
+
+* Menu:
+
+* Basic Protocols:: The basic protocols.
+* Ports:: The idea behind ports.
+
+ ---------- Footnotes ----------
+
+ (1) It should be noted that although the Internet seems to have
+conquered the world, there are other networking protocol suites in
+existence and in use.
+
+\1f
+File: gawkinet.info, Node: Basic Protocols, Next: Ports, Prev: The TCP/IP Protocols, Up: The TCP/IP Protocols
+
+1.3.1 The Basic Internet Protocols
+----------------------------------
+
+IP
+ The Internet Protocol. This protocol is almost never used
+ directly by applications. It provides the basic packet delivery
+ and routing infrastructure of the Internet. Much like the phone
+ company's switching centers or the Post Office's trucks, it is not
+ of much day-to-day interest to the regular user (or programmer).
+ It happens to be a best effort datagram protocol.
+
+UDP
+ The User Datagram Protocol. This is a best effort datagram
+ protocol. It provides a small amount of extra reliability over
+ IP, and adds the notion of "ports", described in *Note TCP and UDP
+ Ports: Ports.
+
+TCP
+ The Transmission Control Protocol. This is a duplex, reliable,
+ sequenced byte-stream protocol, again layered on top of IP, and
+ also providing the notion of ports. This is the protocol that you
+ will most likely use when using `gawk' for network programming.
+
+ All other user-level protocols use either TCP or UDP to do their
+basic communications. Examples are SMTP (Simple Mail Transfer
+Protocol), FTP (File Transfer Protocol), and HTTP (HyperText Transfer
+Protocol).
+
+\1f
+File: gawkinet.info, Node: Ports, Prev: Basic Protocols, Up: The TCP/IP Protocols
+
+1.3.2 TCP and UDP Ports
+-----------------------
+
+In the postal system, the address on an envelope indicates a physical
+location, such as a residence or office building. But there may be
+more than one person at a location; thus you have to further quantify
+the recipient by putting a person or company name on the envelope.
+
+ In the phone system, one phone number may represent an entire
+company, in which case you need a person's extension number in order to
+reach that individual directly. Or, when you call a home, you have to
+say, "May I please speak to ..." before talking to the person directly.
+
+ IP networking provides the concept of addressing. An IP address
+represents a particular computer, but no more. In order to reach the
+mail service on a system, or the FTP or WWW service on a system, you
+must have some way to further specify which service you want. In the
+Internet Protocol suite, this is done with "port numbers", which
+represent the services, much like an extension number used with a phone
+number.
+
+ Port numbers are 16-bit integers. Unix and Unix-like systems
+reserve ports below 1024 for "well known" services, such as SMTP, FTP,
+and HTTP. Numbers 1024 and above may be used by any application,
+although there is no promise made that a particular port number is
+always available.
+
+\1f
+File: gawkinet.info, Node: Making Connections, Prev: The TCP/IP Protocols, Up: Introduction
+
+1.4 Making TCP/IP Connections (And Some Terminology)
+====================================================
+
+Two terms come up repeatedly when discussing networking: "client" and
+"server". For now, we'll discuss these terms at the "connection
+level", when first establishing connections between two processes on
+different systems over a network. (Once the connection is established,
+the higher level, or "application level" protocols, such as HTTP or
+FTP, determine who is the client and who is the server. Often, it
+turns out that the client and server are the same in both roles.)
+
+ The "server" is the system providing the service, such as the web
+server or email server. It is the "host" (system) which is _connected
+to_ in a transaction. For this to work though, the server must be
+expecting connections. Much as there has to be someone at the office
+building to answer the phone(1), the server process (usually) has to be
+started first and be waiting for a connection.
+
+ The "client" is the system requesting the service. It is the system
+_initiating the connection_ in a transaction. (Just as when you pick
+up the phone to call an office or store.)
+
+ In the TCP/IP framework, each end of a connection is represented by
+a pair of (ADDRESS, PORT) pairs. For the duration of the connection,
+the ports in use at each end are unique, and cannot be used
+simultaneously by other processes on the same system. (Only after
+closing a connection can a new one be built up on the same port. This
+is contrary to the usual behavior of fully developed web servers which
+have to avoid situations in which they are not reachable. We have to
+pay this price in order to enjoy the benefits of a simple communication
+paradigm in `gawk'.)
+
+ Furthermore, once the connection is established, communications are
+"synchronous".(2) I.e., each end waits on the other to finish
+transmitting, before replying. This is much like two people in a phone
+conversation. While both could talk simultaneously, doing so usually
+doesn't work too well.
+
+ In the case of TCP, the synchronicity is enforced by the protocol
+when sending data. Data writes "block" until the data have been
+received on the other end. For both TCP and UDP, data reads block
+until there is incoming data waiting to be read. This is summarized in
+the following table, where an "X" indicates that the given action
+blocks.
+
+TCP X X
+UDP X
+RAW X
+
+ ---------- Footnotes ----------
+
+ (1) In the days before voice mail systems!
+
+ (2) For the technically savvy, data reads block--if there's no
+incoming data, the program is made to wait until there is, instead of
+receiving a "there's no data" error return.
+
+\1f
+File: gawkinet.info, Node: Using Networking, Next: Some Applications and Techniques, Prev: Introduction, Up: Top
+
+2 Networking With `gawk'
+************************
+
+The `awk' programming language was originally developed as a
+pattern-matching language for writing short programs to perform data
+manipulation tasks. `awk''s strength is the manipulation of textual
+data that is stored in files. It was never meant to be used for
+networking purposes. To exploit its features in a networking context,
+it's necessary to use an access mode for network connections that
+resembles the access of files as closely as possible.
+
+ `awk' is also meant to be a prototyping language. It is used to
+demonstrate feasibility and to play with features and user interfaces.
+This can be done with file-like handling of network connections.
+`gawk' trades the lack of many of the advanced features of the TCP/IP
+family of protocols for the convenience of simple connection handling.
+The advanced features are available when programming in C or Perl. In
+fact, the network programming in this major node is very similar to
+what is described in books such as `Internet Programming with Python',
+`Advanced Perl Programming', or `Web Client Programming with Perl'.
+
+ However, you can do the programming here without first having to
+learn object-oriented ideology; underlying languages such as Tcl/Tk,
+Perl, Python; or all of the libraries necessary to extend these
+languages before they are ready for the Internet.
+
+ This major node demonstrates how to use the TCP protocol. The other
+protocols are much less important for most users (UDP) or even
+untractable (RAW).
+
+* Menu:
+
+* Gawk Special Files:: How to do `gawk' networking.
+* TCP Connecting:: Making a TCP connection.
+* Troubleshooting:: Troubleshooting TCP/IP connections.
+* Interacting:: Interacting with a service.
+* Setting Up:: Setting up a service.
+* Email:: Reading email.
+* Web page:: Reading a Web page.
+* Primitive Service:: A primitive Web service.
+* Interacting Service:: A Web service with interaction.
+* Simple Server:: A simple Web server.
+* Caveats:: Network programming caveats.
+* Challenges:: Where to go from here.
+
+\1f
+File: gawkinet.info, Node: Gawk Special Files, Next: TCP Connecting, Prev: Using Networking, Up: Using Networking
+
+2.1 `gawk''s Networking Mechanisms
+==================================
+
+The `|&' operator introduced in `gawk' 3.1 for use in communicating
+with a "coprocess" is described in *Note Two-way Communications With
+Another Process: (gawk)Two-way I/O. It shows how to do two-way I/O to a
+separate process, sending it data with `print' or `printf' and reading
+data with `getline'. If you haven't read it already, you should detour
+there to do so.
+
+ `gawk' transparently extends the two-way I/O mechanism to simple
+networking through the use of special file names. When a "coprocess"
+that matches the special files we are about to describe is started,
+`gawk' creates the appropriate network connection, and then two-way I/O
+proceeds as usual.
+
+ At the C, C++, and Perl level, networking is accomplished via
+"sockets", an Application Programming Interface (API) originally
+developed at the University of California at Berkeley that is now used
+almost universally for TCP/IP networking. Socket level programming,
+while fairly straightforward, requires paying attention to a number of
+details, as well as using binary data. It is not well-suited for use
+from a high-level language like `awk'. The special files provided in
+`gawk' hide the details from the programmer, making things much simpler
+and easier to use.
+
+ The special file name for network access is made up of several
+fields, all of which are mandatory:
+
+ /inet/PROTOCOL/LOCALPORT/HOSTNAME/REMOTEPORT
+
+The `/inet/' field is, of course, constant when accessing the network.
+The LOCALPORT and REMOTEPORT fields do not have a meaning when used
+with `/inet/raw' because "ports" only apply to TCP and UDP. So, when
+using `/inet/raw', the port fields always have to be `0'.
+
+* Menu:
+
+* Special File Fields:: The fields in the special file name.
+* Comparing Protocols:: Differences between the protocols.
+
+\1f
+File: gawkinet.info, Node: Special File Fields, Next: Comparing Protocols, Prev: Gawk Special Files, Up: Gawk Special Files
+
+2.1.1 The Fields of the Special File Name
+-----------------------------------------
+
+This node explains the meaning of all the other fields, as well as the
+range of values and the defaults. All of the fields are mandatory. To
+let the system pick a value, or if the field doesn't apply to the
+protocol, specify it as `0':
+
+PROTOCOL
+ Determines which member of the TCP/IP family of protocols is
+ selected to transport the data across the network. There are three
+ possible values (always written in lowercase): `tcp', `udp', and
+ `raw'. The exact meaning of each is explained later in this node.
+
+LOCALPORT
+ Determines which port on the local machine is used to communicate
+ across the network. It has no meaning with `/inet/raw' and must
+ therefore be `0'. Application-level clients usually use `0' to
+ indicate they do not care which local port is used--instead they
+ specify a remote port to connect to. It is vital for
+ application-level servers to use a number different from `0' here
+ because their service has to be available at a specific publicly
+ known port number. It is possible to use a name from
+ `/etc/services' here.
+
+HOSTNAME
+ Determines which remote host is to be at the other end of the
+ connection. Application-level servers must fill this field with a
+ `0' to indicate their being open for all other hosts to connect to
+ them and enforce connection level server behavior this way. It is
+ not possible for an application-level server to restrict its
+ availability to one remote host by entering a host name here.
+ Application-level clients must enter a name different from `0'.
+ The name can be either symbolic (e.g., `jpl-devvax.jpl.nasa.gov')
+ or numeric (e.g., `128.149.1.143').
+
+REMOTEPORT
+ Determines which port on the remote machine is used to communicate
+ across the network. It has no meaning with `/inet/raw' and must
+ therefore be 0. For `/inet/tcp' and `/inet/udp',
+ application-level clients _must_ use a number other than `0' to
+ indicate to which port on the remote machine they want to connect.
+ Application-level servers must not fill this field with a `0'.
+ Instead they specify a local port to which clients connect. It is
+ possible to use a name from `/etc/services' here.
+
+Experts in network programming will notice that the usual client/server
+asymmetry found at the level of the socket API is not visible here.
+This is for the sake of simplicity of the high-level concept. If this
+asymmetry is necessary for your application, use another language. For
+`gawk', it is more important to enable users to write a client program
+with a minimum of code. What happens when first accessing a network
+connection is seen in the following pseudocode:
+
+ if ((name of remote host given) && (other side accepts connection)) {
+ rendez-vous successful; transmit with getline or print
+ } else {
+ if ((other side did not accept) && (localport == 0))
+ exit unsuccessful
+ if (TCP) {
+ set up a server accepting connections
+ this means waiting for the client on the other side to connect
+ } else
+ ready
+ }
+
+The exact behavior of this algorithm depends on the values of the
+fields of the special file name. When in doubt, *Note
+table-inet-components:: gives you the combinations of values and their
+meaning. If this table is too complicated, focus on the three lines
+printed in *bold*. All the examples in *Note Networking With `gawk':
+Using Networking, use only the patterns printed in bold letters.
+
+PROTOCOL LOCAL PORT HOST NAME REMOTE RESULTING CONNECTION-LEVEL
+ PORT BEHAVIOR
+------------------------------------------------------------------------------
+*tcp* *0* *x* *x* *Dedicated client, fails if
+ immediately connecting to a
+ server on the
+ other side fails*
+------------------------------------------------------------------------------
+udp 0 x x Dedicated client
+------------------------------------------------------------------------------
+raw 0 x 0 Dedicated client, works only
+ as `root'
+------------------------------------------------------------------------------
+*tcp, udp* *x* *x* *x* *Client, switches to
+ dedicated server if
+ necessary*
+------------------------------------------------------------------------------
+*tcp, udp* *x* *0* *0* *Dedicated server*
+------------------------------------------------------------------------------
+raw 0 0 0 Dedicated server, works only
+ as `root'
+------------------------------------------------------------------------------
+tcp, udp, x x 0 Invalid
+raw
+------------------------------------------------------------------------------
+tcp, udp, 0 0 x Invalid
+raw
+------------------------------------------------------------------------------
+tcp, udp, x 0 x Invalid
+raw
+------------------------------------------------------------------------------
+tcp, udp 0 0 0 Invalid
+------------------------------------------------------------------------------
+tcp, udp 0 x 0 Invalid
+------------------------------------------------------------------------------
+raw x 0 0 Invalid
+------------------------------------------------------------------------------
+raw 0 x x Invalid
+------------------------------------------------------------------------------
+raw x x x Invalid
+------------------------------------------------------------------------------
+
+Table 2.1: /inet Special File Components
+
+ In general, TCP is the preferred mechanism to use. It is the
+simplest protocol to understand and to use. Use the others only if
+circumstances demand low-overhead.
+
+\1f
+File: gawkinet.info, Node: Comparing Protocols, Prev: Special File Fields, Up: Gawk Special Files
+
+2.1.2 Comparing Protocols
+-------------------------
+
+This node develops a pair of programs (sender and receiver) that do
+nothing but send a timestamp from one machine to another. The sender
+and the receiver are implemented with each of the three protocols
+available and demonstrate the differences between them.
+
+* Menu:
+
+* File /inet/tcp:: The TCP special file.
+* File /inet/udp:: The UDP special file.
+* File /inet/raw:: The RAW special file.
+
+\1f
+File: gawkinet.info, Node: File /inet/tcp, Next: File /inet/udp, Prev: Comparing Protocols, Up: Comparing Protocols
+
+2.1.2.1 `/inet/tcp'
+...................
+
+Once again, always use TCP. (Use UDP when low overhead is a necessity,
+and use RAW for network experimentation.) The first example is the
+sender program:
+
+ # Server
+ BEGIN {
+ print strftime() |& "/inet/tcp/8888/0/0"
+ close("/inet/tcp/8888/0/0")
+ }
+
+The receiver is very simple:
+
+ # Client
+ BEGIN {
+ "/inet/tcp/0/localhost/8888" |& getline
+ print $0
+ close("/inet/tcp/0/localhost/8888")
+ }
+
+TCP guarantees that the bytes arrive at the receiving end in exactly
+the same order that they were sent. No byte is lost (except for broken
+connections), doubled, or out of order. Some overhead is necessary to
+accomplish this, but this is the price to pay for a reliable service.
+It does matter which side starts first. The sender/server has to be
+started first, and it waits for the receiver to read a line.
+
+\1f
+File: gawkinet.info, Node: File /inet/udp, Next: File /inet/raw, Prev: File /inet/tcp, Up: Comparing Protocols
+
+2.1.2.2 `/inet/udp'
+...................
+
+The server and client programs that use UDP are almost identical to
+their TCP counterparts; only the PROTOCOL has changed. As before, it
+does matter which side starts first. The receiving side blocks and
+waits for the sender. In this case, the receiver/client has to be
+started first:
+
+ # Server
+ BEGIN {
+ print strftime() |& "/inet/udp/8888/0/0"
+ close("/inet/udp/8888/0/0")
+ }
+
+The receiver is almost identical to the TCP receiver:
+
+ # Client
+ BEGIN {
+ "/inet/udp/0/localhost/8888" |& getline
+ print $0
+ close("/inet/udp/0/localhost/8888")
+ }
+
+UDP cannot guarantee that the datagrams at the receiving end will
+arrive in exactly the same order they were sent. Some datagrams could be
+lost, some doubled, and some out of order. But no overhead is necessary
+to accomplish this. This unreliable behavior is good enough for tasks
+such as data acquisition, logging, and even stateless services like NFS.
+
+\1f
+File: gawkinet.info, Node: File /inet/raw, Prev: File /inet/udp, Up: Comparing Protocols
+
+2.1.2.3 `/inet/raw'
+...................
+
+This is an IP-level protocol. Only `root' is allowed to access this
+special file. It is meant to be the basis for implementing and
+experimenting with transport-level protocols.(1) In the most general
+case, the sender has to supply the encapsulating header bytes in front
+of the packet and the receiver has to strip the additional bytes from
+the message.
+
+RAW receivers cannot receive packets sent with TCP or UDP because the
+operating system does not deliver the packets to a RAW receiver. The
+operating system knows about some of the protocols on top of IP and
+decides on its own which packet to deliver to which process. (d.c.)
+Therefore, the UDP receiver must be used for receiving UDP datagrams
+sent with the RAW sender. This is a dark corner, not only of `gawk',
+but also of TCP/IP.
+
+For extended experimentation with protocols, look into the approach
+implemented in a tool called SPAK. This tool reflects the hierarchical
+layering of protocols (encapsulation) in the way data streams are piped
+out of one program into the next one. It shows which protocol is based
+on which other (lower-level) protocol by looking at the command-line
+ordering of the program calls. Cleverly thought out, SPAK is much
+better than `gawk''s `/inet' for learning the meaning of each and every
+bit in the protocol headers.
+
+The next example uses the RAW protocol to emulate the behavior of UDP.
+The sender program is the same as above, but with some additional bytes
+that fill the places of the UDP fields:
+
+ BEGIN {
+ Message = "Hello world\n"
+ SourcePort = 0
+ DestinationPort = 8888
+ MessageLength = length(Message)+8
+ RawService = "/inet/raw/0/localhost/0"
+ printf("%c%c%c%c%c%c%c%c%s",
+ SourcePort/256, SourcePort%256,
+ DestinationPort/256, DestinationPort%256,
+ MessageLength/256, MessageLength%256,
+ 0, 0, Message) |& RawService
+ fflush(RawService)
+ close(RawService)
+ }
+
+Since this program tries to emulate the behavior of UDP, it checks if
+the RAW sender is understood by the UDP receiver but not if the RAW
+receiver can understand the UDP sender. In a real network, the RAW
+receiver is hardly of any use because it gets every IP packet that
+comes across the network. There are usually so many packets that `gawk'
+would be too slow for processing them. Only on a network with little
+traffic can the IP-level receiver program be tested. Programs for
+analyzing IP traffic on modem or ISDN channels should be possible.
+
+Port numbers do not have a meaning when using `/inet/raw'. Their fields
+have to be `0'. Only TCP and UDP use ports. Receiving data from
+`/inet/raw' is difficult, not only because of processing speed but also
+because data is usually binary and not restricted to ASCII. This
+implies that line separation with `RS' does not work as usual.
+
+---------- Footnotes ----------
+
+(1) This special file is reserved, but not otherwise currently
+implemented.
+
+\1f
+File: gawkinet.info, Node: TCP Connecting, Next: Troubleshooting, Prev: Gawk Special Files, Up: Using Networking
+
+2.2 Establishing a TCP Connection
+=================================
+
+Let's observe a network connection at work. Type in the following
+program and watch the output. Within a second, it connects via TCP
+(`/inet/tcp') to the machine it is running on (`localhost') and asks
+the service `daytime' on the machine what time it is:
+
+ BEGIN {
+ "/inet/tcp/0/localhost/daytime" |& getline
+ print $0
+ close("/inet/tcp/0/localhost/daytime")
+ }
+
+Even experienced `awk' users will find the second line strange in two
+respects:
+
+ * A special file is used as a shell command that pipes its output
+ into `getline'. One would rather expect to see the special file
+ being read like any other file (`getline <
+ "/inet/tcp/0/localhost/daytime")'.
+
+ * The operator `|&' has not been part of any `awk' implementation
+ (until now). It is actually the only extension of the `awk'
+ language needed (apart from the special files) to introduce
+ network access.
+
+The `|&' operator was introduced in `gawk' 3.1 in order to overcome the
+crucial restriction that access to files and pipes in `awk' is always
+unidirectional. It was formerly impossible to use both access modes on
+the same file or pipe. Instead of changing the whole concept of file
+access, the `|&' operator behaves exactly like the usual pipe operator
+except for two additions:
+
+ * Normal shell commands connected to their `gawk' program with a `|&'
+ pipe can be accessed bidirectionally. The `|&' turns out to be a
+ quite general, useful, and natural extension of `awk'.
+
+ * Pipes that consist of a special file name for network connections
+ are not executed as shell commands. Instead, they can be read and
+ written to, just like a full-duplex network connection.
+
+In the earlier example, the `|&' operator tells `getline' to read a
+line from the special file `/inet/tcp/0/localhost/daytime'. We could
+also have printed a line into the special file. But instead we just
+read a line with the time, printed it, and closed the connection.
+(While we could just let `gawk' close the connection by finishing the
+program, in this Info file we are pedantic and always explicitly close
+the connections.)
+
+\1f
+File: gawkinet.info, Node: Troubleshooting, Next: Interacting, Prev: TCP Connecting, Up: Using Networking
+
+2.3 Troubleshooting Connection Problems
+=======================================
+
+It may well be that for some reason the program shown in the previous
+example does not run on your machine. When looking at possible reasons
+for this, you will learn much about typical problems that arise in
+network programming. First of all, your implementation of `gawk' may
+not support network access because it is a pre-3.1 version or you do
+not have a network interface in your machine. Perhaps your machine
+uses some other protocol, such as DECnet or Novell's IPX. For the rest
+of this major node, we will assume you work on a Unix machine that
+supports TCP/IP. If the previous example program does not run on your
+machine, it may help to replace the name `localhost' with the name of
+your machine or its IP address. If it does, you could replace
+`localhost' with the name of another machine in your vicinity--this
+way, the program connects to another machine. Now you should see the
+date and time being printed by the program, otherwise your machine may
+not support the `daytime' service. Try changing the service to
+`chargen' or `ftp'. This way, the program connects to other services
+that should give you some response. If you are curious, you should have
+a look at your `/etc/services' file. It could look like this:
+
+ # /etc/services:
+ #
+ # Network services, Internet style
+ #
+ # Name Number/Protcol Alternate name # Comments
+
+ echo 7/tcp
+ echo 7/udp
+ discard 9/tcp sink null
+ discard 9/udp sink null
+ daytime 13/tcp
+ daytime 13/udp
+ chargen 19/tcp ttytst source
+ chargen 19/udp ttytst source
+ ftp 21/tcp
+ telnet 23/tcp
+ smtp 25/tcp mail
+ finger 79/tcp
+ www 80/tcp http # WorldWideWeb HTTP
+ www 80/udp # HyperText Transfer Protocol
+ pop-2 109/tcp postoffice # POP version 2
+ pop-2 109/udp
+ pop-3 110/tcp # POP version 3
+ pop-3 110/udp
+ nntp 119/tcp readnews untp # USENET News
+ irc 194/tcp # Internet Relay Chat
+ irc 194/udp
+ ...
+
+Here, you find a list of services that traditional Unix machines usually
+support. If your GNU/Linux machine does not do so, it may be that these
+services are switched off in some startup script. Systems running some
+flavor of Microsoft Windows usually do _not_ support these services.
+Nevertheless, it _is_ possible to do networking with `gawk' on Microsoft
+Windows.(1) The first column of the file gives the name of the service,
+and the second column gives a unique number and the protocol that one
+can use to connect to this service. The rest of the line is treated as
+a comment. You see that some services (`echo') support TCP as well as
+UDP.
+
+---------- Footnotes ----------
+
+(1) Microsoft prefered to ignore the TCP/IP family of protocols until
+1995. Then came the rise of the Netscape browser as a landmark "killer
+application." Microsoft added TCP/IP support and their own browser to
+Microsoft Windows 95 at the last minute. They even back-ported their
+TCP/IP implementation to Microsoft Windows for Workgroups 3.11, but it
+was a rather rudimentary and half-hearted implementation. Nevertheless,
+the equivalent of `/etc/services' resides under
+`C:\WINNT\system32\drivers\etc\services' on Microsoft Windows 2000.
+
+\1f
+File: gawkinet.info, Node: Interacting, Next: Setting Up, Prev: Troubleshooting, Up: Using Networking
+
+2.4 Interacting with a Network Service
+======================================
+
+The next program makes use of the possibility to really interact with a
+network service by printing something into the special file. It asks the
+so-called `finger' service if a user of the machine is logged in. When
+testing this program, try to change `localhost' to some other machine
+name in your local network:
+
+ BEGIN {
+ NetService = "/inet/tcp/0/localhost/finger"
+ print "NAME" |& NetService
+ while ((NetService |& getline) > 0)
+ print $0
+ close(NetService)
+ }
+
+After telling the service on the machine which user to look for, the
+program repeatedly reads lines that come as a reply. When no more lines
+are coming (because the service has closed the connection), the program
+also closes the connection. Try replacing `"NAME"' with your login name
+(or the name of someone else logged in). For a list of all users
+currently logged in, replace NAME with an empty string (`""').
+
+The final `close' command could be safely deleted from the above
+script, because the operating system closes any open connection by
+default when a script reaches the end of execution. In order to avoid
+portability problems, it is best to always close connections explicitly.
+With the Linux kernel, for example, proper closing results in flushing
+of buffers. Letting the close happen by default may result in
+discarding buffers.
+
+When looking at `/etc/services' you may have noticed that the `daytime'
+service is also available with `udp'. In the earlier example, change
+`tcp' to `udp', and change `finger' to `daytime'. After starting the
+modified program, you see the expected day and time message. The
+program then hangs, because it waits for more lines coming from the
+service. However, they never come. This behavior is a consequence of the
+differences between TCP and UDP. When using UDP, neither party is
+automatically informed about the other closing the connection.
+Continuing to experiment this way reveals many other subtle differences
+between TCP and UDP. To avoid such trouble, one should always remember
+the advice Douglas E. Comer and David Stevens give in Volume III of
+their series `Internetworking With TCP' (page 14):
+
+ When designing client-server applications, beginners are strongly
+ advised to use TCP because it provides reliable,
+ connection-oriented communication. Programs only use UDP if the
+ application protocol handles reliability, the application requires
+ hardware broadcast or multicast, or the application cannot
+ tolerate virtual circuit overhead.
+
+\1f
+File: gawkinet.info, Node: Setting Up, Next: Email, Prev: Interacting, Up: Using Networking
+
+2.5 Setting Up a Service
+========================
+
+The preceding programs behaved as clients that connect to a server
+somewhere on the Internet and request a particular service. Now we set
+up such a service to mimic the behavior of the `daytime' service. Such
+a server does not know in advance who is going to connect to it over
+the network. Therefore, we cannot insert a name for the host to connect
+to in our special file name.
+
+Start the following program in one window. Notice that the service does
+not have the name `daytime', but the number `8888'. From looking at
+`/etc/services', you know that names like `daytime' are just mnemonics
+for predetermined 16-bit integers. Only the system administrator
+(`root') could enter our new service into `/etc/services' with an
+appropriate name. Also notice that the service name has to be entered
+into a different field of the special file name because we are setting
+up a server, not a client:
+
+ BEGIN {
+ print strftime() |& "/inet/tcp/8888/0/0"
+ close("/inet/tcp/8888/0/0")
+ }
+
+Now open another window on the same machine. Copy the client program
+given as the first example (*note Establishing a TCP Connection: TCP
+Connecting.) to a new file and edit it, changing the name `daytime' to
+`8888'. Then start the modified client. You should get a reply like
+this:
+
+ Sat Sep 27 19:08:16 CEST 1997
+
+Both programs explicitly close the connection.
+
+Now we will intentionally make a mistake to see what happens when the
+name `8888' (the so-called port) is already used by another service.
+Start the server program in both windows. The first one works, but the
+second one complains that it could not open the connection. Each port
+on a single machine can only be used by one server program at a time.
+Now terminate the server program and change the name `8888' to `echo'.
+After restarting it, the server program does not run any more, and you
+know why: there is already an `echo' service running on your machine.
+But even if this isn't true, you would not get your own `echo' server
+running on a Unix machine, because the ports with numbers smaller than
+1024 (`echo' is at port 7) are reserved for `root'. On machines
+running some flavor of Microsoft Windows, there is no restriction that
+reserves ports 1 to 1024 for a privileged user; hence, you can start an
+`echo' server there.
+
+Turning this short server program into something really useful is
+simple. Imagine a server that first reads a file name from the client
+through the network connection, then does something with the file and
+sends a result back to the client. The server-side processing could be:
+
+ BEGIN {
+ NetService = "/inet/tcp/8888/0/0"
+ NetService |& getline
+ CatPipe = ("cat " $1) # sets $0 and the fields
+ while ((CatPipe | getline) > 0)
+ print $0 |& NetService
+ close(NetService)
+ }
+
+and we would have a remote copying facility. Such a server reads the
+name of a file from any client that connects to it and transmits the
+contents of the named file across the net. The server-side processing
+could also be the execution of a command that is transmitted across the
+network. From this example, you can see how simple it is to open up a
+security hole on your machine. If you allow clients to connect to your
+machine and execute arbitrary commands, anyone would be free to do `rm
+-rf *'.
+
+\1f
+File: gawkinet.info, Node: Email, Next: Web page, Prev: Setting Up, Up: Using Networking
+
+2.6 Reading Email
+=================
+
+The distribution of email is usually done by dedicated email servers
+that communicate with your machine using special protocols. To receive
+email, we will use the Post Office Protocol (POP). Sending can be done
+with the much older Simple Mail Transfer Protocol (SMTP).
+
+When you type in the following program, replace the EMAILHOST by the
+name of your local email server. Ask your administrator if the server
+has a POP service, and then use its name or number in the program below.
+Now the program is ready to connect to your email server, but it will
+not succeed in retrieving your mail because it does not yet know your
+login name or password. Replace them in the program and it shows you
+the first email the server has in store:
+
+ BEGIN {
+ POPService = "/inet/tcp/0/EMAILHOST/pop3"
+ RS = ORS = "\r\n"
+ print "user NAME" |& POPService
+ POPService |& getline
+ print "pass PASSWORD" |& POPService
+ POPService |& getline
+ print "retr 1" |& POPService
+ POPService |& getline
+ if ($1 != "+OK") exit
+ print "quit" |& POPService
+ RS = "\r\n\\.\r\n"
+ POPService |& getline
+ print $0
+ close(POPService)
+ }
+
+The record separators `RS' and `ORS' are redefined because the protocol
+(POP) requires CR-LF to separate lines. After identifying yourself to
+the email service, the command `retr 1' instructs the service to send
+the first of all your email messages in line. If the service replies
+with something other than `+OK', the program exits; maybe there is no
+email. Otherwise, the program first announces that it intends to finish
+reading email, and then redefines `RS' in order to read the entire
+email as multiline input in one record. From the POP RFC, we know that
+the body of the email always ends with a single line containing a
+single dot. The program looks for this using `RS = "\r\n\\.\r\n"'.
+When it finds this sequence in the mail message, it quits. You can
+invoke this program as often as you like; it does not delete the
+message it reads, but instead leaves it on the server.
+
+\1f
+File: gawkinet.info, Node: Web page, Next: Primitive Service, Prev: Email, Up: Using Networking
+
+2.7 Reading a Web Page
+======================
+
+Retrieving a web page from a web server is as simple as retrieving
+email from an email server. We only have to use a similar, but not
+identical, protocol and a different port. The name of the protocol is
+HyperText Transfer Protocol (HTTP) and the port number is usually 80.
+As in the preceding node, ask your administrator about the name of your
+local web server or proxy web server and its port number for HTTP
+requests.
+
+The following program employs a rather crude approach toward retrieving
+a web page. It uses the prehistoric syntax of HTTP 0.9, which almost all
+web servers still support. The most noticeable thing about it is that
+the program directs the request to the local proxy server whose name
+you insert in the special file name (which in turn calls
+`www.yahoo.com'):
+
+ BEGIN {
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/0/PROXY/80"
+ print "GET http://www.yahoo.com" |& HttpService
+ while ((HttpService |& getline) > 0)
+ print $0
+ close(HttpService)
+ }
+
+Again, lines are separated by a redefined `RS' and `ORS'. The `GET'
+request that we send to the server is the only kind of HTTP request
+that existed when the web was created in the early 1990s. HTTP calls
+this `GET' request a "method," which tells the service to transmit a
+web page (here the home page of the Yahoo! search engine). Version 1.0
+added the request methods `HEAD' and `POST'. The current version of
+HTTP is 1.1,(1) and knows the additional request methods `OPTIONS',
+`PUT', `DELETE', and `TRACE'. You can fill in any valid web address,
+and the program prints the HTML code of that page to your screen.
+
+Notice the similarity between the responses of the POP and HTTP
+services. First, you get a header that is terminated by an empty line,
+and then you get the body of the page in HTML. The lines of the
+headers also have the same form as in POP. There is the name of a
+parameter, then a colon, and finally the value of that parameter.
+
+Images (`.png' or `.gif' files) can also be retrieved this way, but
+then you get binary data that should be redirected into a file. Another
+application is calling a CGI (Common Gateway Interface) script on some
+server. CGI scripts are used when the contents of a web page are not
+constant, but generated instantly at the moment you send a request for
+the page. For example, to get a detailed report about the current
+quotes of Motorola stock shares, call a CGI script at Yahoo! with the
+following:
+
+ get = "GET http://quote.yahoo.com/q?s=MOT&d=t"
+ print get |& HttpService
+
+You can also request weather reports this way.
+
+---------- Footnotes ----------
+
+(1) Version 1.0 of HTTP was defined in RFC 1945. HTTP 1.1 was
+initially specified in RFC 2068. In June 1999, RFC 2068 was made
+obsolete by RFC 2616, an update without any substantial changes.
+
+\1f
+File: gawkinet.info, Node: Primitive Service, Next: Interacting Service, Prev: Web page, Up: Using Networking
+
+2.8 A Primitive Web Service
+===========================
+
+Now we know enough about HTTP to set up a primitive web service that
+just says `"Hello, world"' when someone connects to it with a browser.
+Compared to the situation in the preceding node, our program changes
+the role. It tries to behave just like the server we have observed.
+Since we are setting up a server here, we have to insert the port
+number in the `localport' field of the special file name. The other two
+fields (HOSTNAME and REMOTEPORT) have to contain a `0' because we do
+not know in advance which host will connect to our service.
+
+In the early 1990s, all a server had to do was send an HTML document and
+close the connection. Here, we adhere to the modern syntax of HTTP.
+The steps are as follows:
+
+ 1. Send a status line telling the web browser that everything is okay.
+
+ 2. Send a line to tell the browser how many bytes follow in the body
+ of the message. This was not necessary earlier because both
+ parties knew that the document ended when the connection closed.
+ Nowadays it is possible to stay connected after the transmission
+ of one web page. This is to avoid the network traffic necessary
+ for repeatedly establishing TCP connections for requesting several
+ images. Thus, there is the need to tell the receiving party how
+ many bytes will be sent. The header is terminated as usual with an
+ empty line.
+
+ 3. Send the `"Hello, world"' body in HTML. The useless `while' loop
+ swallows the request of the browser. We could actually omit the
+ loop, and on most machines the program would still work. First,
+ start the following program:
+
+ BEGIN {
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/8080/0/0"
+ Hello = "<HTML><HEAD>" \
+ "<TITLE>A Famous Greeting</TITLE></HEAD>" \
+ "<BODY><H1>Hello, world</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+ }
+
+Now, on the same machine, start your favorite browser and let it point
+to `http://localhost:8080' (the browser needs to know on which port our
+server is listening for requests). If this does not work, the browser
+probably tries to connect to a proxy server that does not know your
+machine. If so, change the browser's configuration so that the browser
+does not try to use a proxy to connect to your machine.
+
+\1f
+File: gawkinet.info, Node: Interacting Service, Next: Simple Server, Prev: Primitive Service, Up: Using Networking
+
+2.9 A Web Service with Interaction
+==================================
+
+This node shows how to set up a simple web server. The subnode is a
+library file that we will use with all the examples in *Note Some
+Applications and Techniques::.
+
+* Menu:
+
+* CGI Lib:: A simple CGI library.
+
+Setting up a web service that allows user interaction is more difficult
+and shows us the limits of network access in `gawk'. In this node, we
+develop a main program (a `BEGIN' pattern and its action) that will
+become the core of event-driven execution controlled by a graphical
+user interface (GUI). Each HTTP event that the user triggers by some
+action within the browser is received in this central procedure.
+Parameters and menu choices are extracted from this request, and an
+appropriate measure is taken according to the user's choice. For
+example:
+
+ BEGIN {
+ if (MyHost == "") {
+ "uname -n" | getline MyHost
+ close("uname -n")
+ }
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ MyPrefix = "http://" MyHost ":" MyPort
+ SetUpServer()
+ while ("awk" != "complex") {
+ # header lines are terminated this way
+ RS = ORS = "\r\n"
+ Status = 200 # this means OK
+ Reason = "OK"
+ Header = TopHeader
+ Document = TopDoc
+ Footer = TopFooter
+ if (GETARG["Method"] == "GET") {
+ HandleGET()
+ } else if (GETARG["Method"] == "HEAD") {
+ # not yet implemented
+ } else if (GETARG["Method"] != "") {
+ print "bad method", GETARG["Method"]
+ }
+ Prompt = Header Document Footer
+ print "HTTP/1.0", Status, Reason |& HttpService
+ print "Connection: Close" |& HttpService
+ print "Pragma: no-cache" |& HttpService
+ len = length(Prompt) + length(ORS)
+ print "Content-length:", len |& HttpService
+ print ORS Prompt |& HttpService
+ # ignore all the header lines
+ while ((HttpService |& getline) > 0)
+ ;
+ # stop talking to this client
+ close(HttpService)
+ # wait for new client request
+ HttpService |& getline
+ # do some logging
+ print systime(), strftime(), $0
+ # read request parameters
+ CGI_setup($1, $2, $3)
+ }
+ }
+
+This web server presents menu choices in the form of HTML links.
+Therefore, it has to tell the browser the name of the host it is
+residing on. When starting the server, the user may supply the name of
+the host from the command line with `gawk -v MyHost="Rumpelstilzchen"'.
+If the user does not do this, the server looks up the name of the host
+it is running on for later use as a web address in HTML documents. The
+same applies to the port number. These values are inserted later into
+the HTML content of the web pages to refer to the home system.
+
+Each server that is built around this core has to initialize some
+application-dependent variables (such as the default home page) in a
+procedure `SetUpServer', which is called immediately before entering the
+infinite loop of the server. For now, we will write an instance that
+initiates a trivial interaction. With this home page, the client user
+can click on two possible choices, and receive the current date either
+in human-readable format or in seconds since 1970:
+
+ function SetUpServer() {
+ TopHeader = "<HTML><HEAD>"
+ TopHeader = TopHeader \
+ "<title>My name is GAWK, GNU AWK</title></HEAD>"
+ TopDoc = "<BODY><h2>\
+ Do you prefer your date <A HREF=" MyPrefix \
+ "/human>human</A> or \
+ <A HREF=" MyPrefix "/POSIX>POSIXed</A>?</h2>" ORS ORS
+ TopFooter = "</BODY></HTML>"
+ }
+
+On the first run through the main loop, the default line terminators are
+set and the default home page is copied to the actual home page. Since
+this is the first run, `GETARG["Method"]' is not initialized yet, hence
+the case selection over the method does nothing. Now that the home page
+is initialized, the server can start communicating to a client browser.
+
+It does so by printing the HTTP header into the network connection
+(`print ... |& HttpService'). This command blocks execution of the
+server script until a client connects. If this server script is
+compared with the primitive one we wrote before, you will notice two
+additional lines in the header. The first instructs the browser to
+close the connection after each request. The second tells the browser
+that it should never try to _remember_ earlier requests that had
+identical web addresses (no caching). Otherwise, it could happen that
+the browser retrieves the time of day in the previous example just once,
+and later it takes the web page from the cache, always displaying the
+same time of day although time advances each second.
+
+Having supplied the initial home page to the browser with a valid
+document stored in the parameter `Prompt', it closes the connection and
+waits for the next request. When the request comes, a log line is
+printed that allows us to see which request the server receives. The
+final step in the loop is to call the function `CGI_setup', which reads
+all the lines of the request (coming from the browser), processes them,
+and stores the transmitted parameters in the array `PARAM'. The complete
+text of these application-independent functions can be found in *Note A
+Simple CGI Library: CGI Lib. For now, we use a simplified version of
+`CGI_setup':
+
+ function CGI_setup( method, uri, version, i) {
+ delete GETARG; delete MENU; delete PARAM
+ GETARG["Method"] = $1
+ GETARG["URI"] = $2
+ GETARG["Version"] = $3
+ i = index($2, "?")
+ # is there a "?" indicating a CGI request?
+ if (i > 0) {
+ split(substr($2, 1, i-1), MENU, "[/:]")
+ split(substr($2, i+1), PARAM, "&")
+ for (i in PARAM) {
+ j = index(PARAM[i], "=")
+ GETARG[substr(PARAM[i], 1, j-1)] = \
+ substr(PARAM[i], j+1)
+ }
+ } else { # there is no "?", no need for splitting PARAMs
+ split($2, MENU, "[/:]")
+ }
+ }
+
+At first, the function clears all variables used for global storage of
+request parameters. The rest of the function serves the purpose of
+filling the global parameters with the extracted new values. To
+accomplish this, the name of the requested resource is split into parts
+and stored for later evaluation. If the request contains a `?', then
+the request has CGI variables seamlessly appended to the web address.
+Everything in front of the `?' is split up into menu items, and
+everything behind the `?' is a list of `VARIABLE=VALUE' pairs
+(separated by `&') that also need splitting. This way, CGI variables are
+isolated and stored. This procedure lacks recognition of special
+characters that are transmitted in coded form(1). Here, any optional
+request header and body parts are ignored. We do not need header
+parameters and the request body. However, when refining our approach or
+working with the `POST' and `PUT' methods, reading the header and body
+becomes inevitable. Header parameters should then be stored in a global
+array as well as the body.
+
+On each subsequent run through the main loop, one request from a
+browser is received, evaluated, and answered according to the user's
+choice. This can be done by letting the value of the HTTP method guide
+the main loop into execution of the procedure `HandleGET', which
+evaluates the user's choice. In this case, we have only one
+hierarchical level of menus, but in the general case, menus are nested.
+The menu choices at each level are separated by `/', just as in file
+names. Notice how simple it is to construct menus of arbitrary depth:
+
+ function HandleGET() {
+ if ( MENU[2] == "human") {
+ Footer = strftime() TopFooter
+ } else if (MENU[2] == "POSIX") {
+ Footer = systime() TopFooter
+ }
+ }
+
+The disadvantage of this approach is that our server is slow and can
+handle only one request at a time. Its main advantage, however, is that
+the server consists of just one `gawk' program. No need for installing
+an `httpd', and no need for static separate HTML files, CGI scripts, or
+`root' privileges. This is rapid prototyping. This program can be
+started on the same host that runs your browser. Then let your browser
+point to `http://localhost:8080'.
+
+It is also possible to include images into the HTML pages. Most
+browsers support the not very well-known `.xbm' format, which may
+contain only monochrome pictures but is an ASCII format. Binary images
+are possible but not so easy to handle. Another way of including images
+is to generate them with a tool such as GNUPlot, by calling the tool
+with the `system' function or through a pipe.
+
+---------- Footnotes ----------
+
+(1) As defined in RFC 2068.
+
+\1f
+File: gawkinet.info, Node: CGI Lib, Prev: Interacting Service, Up: Interacting Service
+
+2.9.1 A Simple CGI Library
+--------------------------
+
+ HTTP is like being married: you have to be able to handle whatever
+ you're given, while being very careful what you send back.
+ Phil Smith III,
+ `http://www.netfunny.com/rhf/jokes/99/Mar/http.html'
+
+In *Note A Web Service with Interaction: Interacting Service, we saw
+the function `CGI_setup' as part of the web server "core logic"
+framework. The code presented there handles almost everything necessary
+for CGI requests. One thing it doesn't do is handle encoded characters
+in the requests. For example, an `&' is encoded as a percent sign
+followed by the hexadecimal value: `%26'. These encoded values should
+be decoded. Following is a simple library to perform these tasks.
+This code is used for all web server examples used throughout the rest
+of this Info file. If you want to use it for your own web server,
+store the source code into a file named `inetlib.awk'. Then you can
+include these functions into your code by placing the following
+statement into your program (on the first line of your script):
+
+ @include inetlib.awk
+
+But beware, this mechanism is only possible if you invoke your web
+server script with `igawk' instead of the usual `awk' or `gawk'. Here
+is the code:
+
+ # CGI Library and core of a web server
+ # Global arrays
+ # GETARG --- arguments to CGI GET command
+ # MENU --- menu items (path names)
+ # PARAM --- parameters of form x=y
+
+ # Optional variable MyHost contains host address
+ # Optional variable MyPort contains port number
+ # Needs TopHeader, TopDoc, TopFooter
+ # Sets MyPrefix, HttpService, Status, Reason
+
+ BEGIN {
+ if (MyHost == "") {
+ "uname -n" | getline MyHost
+ close("uname -n")
+ }
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ MyPrefix = "http://" MyHost ":" MyPort
+ SetUpServer()
+ while ("awk" != "complex") {
+ # header lines are terminated this way
+ RS = ORS = "\r\n"
+ Status = 200 # this means OK
+ Reason = "OK"
+ Header = TopHeader
+ Document = TopDoc
+ Footer = TopFooter
+ if (GETARG["Method"] == "GET") {
+ HandleGET()
+ } else if (GETARG["Method"] == "HEAD") {
+ # not yet implemented
+ } else if (GETARG["Method"] != "") {
+ print "bad method", GETARG["Method"]
+ }
+ Prompt = Header Document Footer
+ print "HTTP/1.0", Status, Reason |& HttpService
+ print "Connection: Close" |& HttpService
+ print "Pragma: no-cache" |& HttpService
+ len = length(Prompt) + length(ORS)
+ print "Content-length:", len |& HttpService
+ print ORS Prompt |& HttpService
+ # ignore all the header lines
+ while ((HttpService |& getline) > 0)
+ continue
+ # stop talking to this client
+ close(HttpService)
+ # wait for new client request
+ HttpService |& getline
+ # do some logging
+ print systime(), strftime(), $0
+ CGI_setup($1, $2, $3)
+ }
+ }
+
+ function CGI_setup( method, uri, version, i)
+ {
+ delete GETARG
+ delete MENU
+ delete PARAM
+ GETARG["Method"] = method
+ GETARG["URI"] = uri
+ GETARG["Version"] = version
+
+ i = index(uri, "?")
+ if (i > 0) { # is there a "?" indicating a CGI request?
+ split(substr(uri, 1, i-1), MENU, "[/:]")
+ split(substr(uri, i+1), PARAM, "&")
+ for (i in PARAM) {
+ PARAM[i] = _CGI_decode(PARAM[i])
+ j = index(PARAM[i], "=")
+ GETARG[substr(PARAM[i], 1, j-1)] = \
+ substr(PARAM[i], j+1)
+ }
+ } else { # there is no "?", no need for splitting PARAMs
+ split(uri, MENU, "[/:]")
+ }
+ for (i in MENU) # decode characters in path
+ if (i > 4) # but not those in host name
+ MENU[i] = _CGI_decode(MENU[i])
+ }
+
+This isolates details in a single function, `CGI_setup'. Decoding of
+encoded characters is pushed off to a helper function, `_CGI_decode'.
+The use of the leading underscore (`_') in the function name is
+intended to indicate that it is an "internal" function, although there
+is nothing to enforce this:
+
+ function _CGI_decode(str, hexdigs, i, pre, code1, code2,
+ val, result)
+ {
+ hexdigs = "123456789abcdef"
+
+ i = index(str, "%")
+ if (i == 0) # no work to do
+ return str
+
+ do {
+ pre = substr(str, 1, i-1) # part before %xx
+ code1 = substr(str, i+1, 1) # first hex digit
+ code2 = substr(str, i+2, 1) # second hex digit
+ str = substr(str, i+3) # rest of string
+
+ code1 = tolower(code1)
+ code2 = tolower(code2)
+ val = index(hexdigs, code1) * 16 \
+ + index(hexdigs, code2)
+
+ result = result pre sprintf("%c", val)
+ i = index(str, "%")
+ } while (i != 0)
+ if (length(str) > 0)
+ result = result str
+ return result
+ }
+
+This works by splitting the string apart around an encoded character.
+The two digits are converted to lowercase characters and looked up in a
+string of hex digits. Note that `0' is not in the string on purpose;
+`index' returns zero when it's not found, automatically giving the
+correct value! Once the hexadecimal value is converted from characters
+in a string into a numerical value, `sprintf' converts the value back
+into a real character. The following is a simple test harness for the
+above functions:
+
+ BEGIN {
+ CGI_setup("GET",
+ "http://www.gnu.org/cgi-bin/foo?p1=stuff&p2=stuff%26junk" \
+ "&percent=a %25 sign",
+ "1.0")
+ for (i in MENU)
+ printf "MENU[\"%s\"] = %s\n", i, MENU[i]
+ for (i in PARAM)
+ printf "PARAM[\"%s\"] = %s\n", i, PARAM[i]
+ for (i in GETARG)
+ printf "GETARG[\"%s\"] = %s\n", i, GETARG[i]
+ }
+
+And this is the result when we run it:
+
+ $ gawk -f testserv.awk
+ -| MENU["4"] = www.gnu.org
+ -| MENU["5"] = cgi-bin
+ -| MENU["6"] = foo
+ -| MENU["1"] = http
+ -| MENU["2"] =
+ -| MENU["3"] =
+ -| PARAM["1"] = p1=stuff
+ -| PARAM["2"] = p2=stuff&junk
+ -| PARAM["3"] = percent=a % sign
+ -| GETARG["p1"] = stuff
+ -| GETARG["percent"] = a % sign
+ -| GETARG["p2"] = stuff&junk
+ -| GETARG["Method"] = GET
+ -| GETARG["Version"] = 1.0
+ -| GETARG["URI"] = http://www.gnu.org/cgi-bin/foo?p1=stuff&
+ p2=stuff%26junk&percent=a %25 sign
+
+\1f
+File: gawkinet.info, Node: Simple Server, Next: Caveats, Prev: Interacting Service, Up: Using Networking
+
+2.10 A Simple Web Server
+========================
+
+In the preceding node, we built the core logic for event-driven GUIs.
+In this node, we finally extend the core to a real application. No one
+would actually write a commercial web server in `gawk', but it is
+instructive to see that it is feasible in principle.
+
+The application is ELIZA, the famous program by Joseph Weizenbaum that
+mimics the behavior of a professional psychotherapist when talking to
+you. Weizenbaum would certainly object to this description, but this
+is part of the legend around ELIZA. Take the site-independent core
+logic and append the following code:
+
+ function SetUpServer() {
+ SetUpEliza()
+ TopHeader = \
+ "<HTML><title>An HTTP-based System with GAWK</title>\
+ <HEAD><META HTTP-EQUIV=\"Content-Type\"\
+ CONTENT=\"text/html; charset=iso-8859-1\"></HEAD>\
+ <BODY BGCOLOR=\"#ffffff\" TEXT=\"#000000\"\
+ LINK=\"#0000ff\" VLINK=\"#0000ff\"\
+ ALINK=\"#0000ff\"> <A NAME=\"top\">"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI>\
+ <A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ </LI><LI>\
+ <A HREF=" MyPrefix "/AboutELIZA>About Eliza</A></LI>\
+ <LI>\
+ <A HREF=" MyPrefix \
+ "/StartELIZA>Start talking to Eliza</A></LI></UL>"
+ TopFooter = "</BODY></HTML>"
+ }
+
+`SetUpServer' is similar to the previous example, except for calling
+another function, `SetUpEliza'. This approach can be used to implement
+other kinds of servers. The only changes needed to do so are hidden in
+the functions `SetUpServer' and `HandleGET'. Perhaps it might be
+necessary to implement other HTTP methods. The `igawk' program that
+comes with `gawk' may be useful for this process.
+
+When extending this example to a complete application, the first thing
+to do is to implement the function `SetUpServer' to initialize the HTML
+pages and some variables. These initializations determine the way your
+HTML pages look (colors, titles, menu items, etc.).
+
+The function `HandleGET' is a nested case selection that decides which
+page the user wants to see next. Each nesting level refers to a menu
+level of the GUI. Each case implements a certain action of the menu. On
+the deepest level of case selection, the handler essentially knows what
+the user wants and stores the answer into the variable that holds the
+HTML page contents:
+
+ function HandleGET() {
+ # A real HTTP server would treat some parts of the URI as a file name.
+ # We take parts of the URI as menu choices and go on accordingly.
+ if(MENU[2] == "AboutServer") {
+ Document = "This is not a CGI script.\
+ This is an httpd, an HTML file, and a CGI script all \
+ in one GAWK script. It needs no separate www-server, \
+ no installation, and no root privileges.\
+ <p>To run it, do this:</p><ul>\
+ <li> start this script with \"gawk -f httpserver.awk\",</li>\
+ <li> and on the same host let your www browser open location\
+ \"http://localhost:8080\"</li>\
+ </ul>\<p>\ Details of HTTP come from:</p><ul>\
+ <li>Hethmon: Illustrated Guide to HTTP</p>\
+ <li>RFC 2068</li></ul><p>JK 14.9.1997</p>"
+ } else if (MENU[2] == "AboutELIZA") {
+ Document = "This is an implementation of the famous ELIZA\
+ program by Joseph Weizenbaum. It is written in GAWK and\
+ /bin/sh: expad: command not found
+ } else if (MENU[2] == "StartELIZA") {
+ gsub(/\+/, " ", GETARG["YouSay"])
+ # Here we also have to substitute coded special characters
+ Document = "<form method=GET>" \
+ "<h3>" ElizaSays(GETARG["YouSay"]) "</h3>\
+ <p><input type=text name=YouSay value=\"\" size=60>\
+ <br><input type=submit value=\"Tell her about it\"></p></form>"
+ }
+ }
+
+Now we are down to the heart of ELIZA, so you can see how it works.
+Initially the user does not say anything; then ELIZA resets its money
+counter and asks the user to tell what comes to mind open heartedly.
+The subsequent answers are converted to uppercase characters and stored
+for later comparison. ELIZA presents the bill when being confronted with
+a sentence that contains the phrase "shut up." Otherwise, it looks for
+keywords in the sentence, conjugates the rest of the sentence, remembers
+the keyword for later use, and finally selects an answer from the set of
+possible answers:
+
+ function ElizaSays(YouSay) {
+ if (YouSay == "") {
+ cost = 0
+ answer = "HI, IM ELIZA, TELL ME YOUR PROBLEM"
+ } else {
+ q = toupper(YouSay)
+ gsub("'", "", q)
+ if(q == qold) {
+ answer = "PLEASE DONT REPEAT YOURSELF !"
+ } else {
+ if (index(q, "SHUT UP") > 0) {
+ answer = "WELL, PLEASE PAY YOUR BILL. ITS EXACTLY ... $"\
+ int(100*rand()+30+cost/100)
+ } else {
+ qold = q
+ w = "-" # no keyword recognized yet
+ for (i in k) { # search for keywords
+ if (index(q, i) > 0) {
+ w = i
+ break
+ }
+ }
+ if (w == "-") { # no keyword, take old subject
+ w = wold
+ subj = subjold
+ } else { # find subject
+ subj = substr(q, index(q, w) + length(w)+1)
+ wold = w
+ subjold = subj # remember keyword and subject
+ }
+ for (i in conj)
+ gsub(i, conj[i], q) # conjugation
+ # from all answers to this keyword, select one randomly
+ answer = r[indices[int(split(k[w], indices) * rand()) + 1]]
+ # insert subject into answer
+ gsub("_", subj, answer)
+ }
+ }
+ }
+ cost += length(answer) # for later payment : 1 cent per character
+ return answer
+ }
+
+In the long but simple function `SetUpEliza', you can see tables for
+conjugation, keywords, and answers.(1) The associative array `k'
+contains indices into the array of answers `r'. To choose an answer,
+ELIZA just picks an index randomly:
+
+ function SetUpEliza() {
+ srand()
+ wold = "-"
+ subjold = " "
+
+ # table for conjugation
+ conj[" ARE " ] = " AM "
+ conj["WERE " ] = "WAS "
+ conj[" YOU " ] = " I "
+ conj["YOUR " ] = "MY "
+ conj[" IVE " ] =\
+ conj[" I HAVE " ] = " YOU HAVE "
+ conj[" YOUVE " ] =\
+ conj[" YOU HAVE "] = " I HAVE "
+ conj[" IM " ] =\
+ conj[" I AM " ] = " YOU ARE "
+ conj[" YOURE " ] =\
+ conj[" YOU ARE " ] = " I AM "
+
+ # table of all answers
+ r[1] = "DONT YOU BELIEVE THAT I CAN _"
+ r[2] = "PERHAPS YOU WOULD LIKE TO BE ABLE TO _ ?"
+ ...
+
+ # table for looking up answers that
+ # fit to a certain keyword
+ k["CAN YOU"] = "1 2 3"
+ k["CAN I"] = "4 5"
+ k["YOU ARE"] =\
+ k["YOURE"] = "6 7 8 9"
+ ...
+
+ }
+
+Some interesting remarks and details (including the original source code
+of ELIZA) are found on Mark Humphrys' home page. Yahoo! also has a
+page with a collection of ELIZA-like programs. Many of them are written
+in Java, some of them disclosing the Java source code, and a few even
+explain how to modify the Java source code.
+
+---------- Footnotes ----------
+
+(1) The version shown here is abbreviated. The full version comes with
+the `gawk' distribution.
+
+\1f
+File: gawkinet.info, Node: Caveats, Next: Challenges, Prev: Simple Server, Up: Using Networking
+
+2.11 Network Programming Caveats
+================================
+
+By now it should be clear that debugging a networked application is more
+complicated than debugging a single-process single-hosted application.
+The behavior of a networked application sometimes looks noncausal
+because it is not reproducible in a strong sense. Whether a network
+application works or not sometimes depends on the following:
+
+ * How crowded the underlying network is
+
+ * If the party at the other end is running or not
+
+ * The state of the party at the other end
+
+The most difficult problems for a beginner arise from the hidden states
+of the underlying network. After closing a TCP connection, it's often
+necessary to wait a short while before reopening the connection. Even
+more difficult is the establishment of a connection that previously
+ended with a "broken pipe." Those connections have to "time out" for a
+minute or so before they can reopen. Check this with the command
+`netstat -a', which provides a list of still "active" connections.
+
+\1f
+File: gawkinet.info, Node: Challenges, Prev: Caveats, Up: Using Networking
+
+2.12 Where To Go From Here
+==========================
+
+Now, you have learned enough to build your own application. You could,
+for example, take part in the Loebner Contest to win $100,000. The
+Loebner Prize is the first formal instantiation of a Turing Test. Hugh
+Loebner agreed with The Cambridge Center for Behavioral Studies to
+underwrite a contest designed to implement the Turing Test. Dr.
+Loebner pledged a Grand Prize of $100,000 for the first computer whose
+responses were indistinguishable from a human's. Each year an annual
+prize of $2000 and a bronze medal is awarded to the _most_ human
+computer. The winner of the annual contest is the best entry relative
+to other entries that year, irrespective of how good it is in an
+absolute sense. Here is an example of a conversation with the winning
+program of 1997:
+
+ (c)1997 Cambridge Center For Behavioral Studies all rights reserved [CONVERSE]
+ [Intelligent Research Ltd.] Start at: [1997/04/29 08:59:40]
+ PROGRAM[10:39:20]Hi, my name is Catherine, what's yours?
+ JUDGE02[10:39:36]My name is Nathan.
+ PROGRAM[10:39:37]Well, it's nice to meet you, Nathan.
+ PROGRAM[10:39:45]Did you see that story on CNN last night about the lesbian
+ PROGRAM[10:40:03]couple who came out at a White House party on Sunday?
+ JUDGE02[10:40:45]No. I'm sorry I missed that. How did the Prez take it?
+ PROGRAM[10:40:47]Ellen Degeneres was one of them - she was kissing her lover
+ PROGRAM[10:41:08]in front of Bill Clinton. Do you think he was very
+ PROGRAM[10:41:21]embarrassed?
+ JUDGE02[10:41:37]You tell me. I didn't see it.
+ PROGRAM[10:41:38]Are you still a Friend of Bill Clinton?
+ JUDGE02[10:42:22]Yes. I would like to talk about something else. Do you know anything about sculpture.
+ PROGRAM[10:42:24]Well, I suppose he's doing his best like most of us, but he
+ PROGRAM[10:42:35]does seem to attract an UNUSUAL amount of bad publicity,
+ PROGRAM[10:42:51]wouldnt you say--can it all be bad luck?
+ JUDGE02[10:43:20]I asked you if you knew anything about sculpture.
+ PROGRAM[10:43:21]OK, but what happens now--does it all drift on, with
+ PROGRAM[10:43:36]everyone waiting to see how much his friends have said about
+ PROGRAM[10:43:47]him under threat of lots and lots of jail-or will something
+ PROGRAM[10:44:01]dramatic actually happen?
+ JUDGE02[10:44:19]Do you know what sculpture is?
+ PROGRAM[10:44:20]Well, youre more a fan of his than I am I guess---though I
+ PROGRAM[10:44:34]cant SWEAR what Id have done in that locked hotel room, I
+ PROGRAM[10:44:51]must say.
+ JUDGE02[10:45:26]Have you ever been to the Salmagundi Club?
+ PROGRAM[10:45:29]Never. to go back to the original discussion Time to get
+ PROGRAM[10:45:43]off this one I think and onto something more down to earth!
+ JUDGE02[10:46:20]What is more down to earth than art?
+ PROGRAM[10:46:21]I don't know what -- to be honest. -
+ PROGRAM[10:46:30]I suppose it depends on where you're coming from, but as the
+ PROGRAM[10:46:46]song goes in My Fair Lady, "Why can't a woman be more like a
+ PROGRAM[10:47:03]man? "
+ JUDGE02[10:47:52]I liked that song but I prefer "Why can't children be more like we are"
+ JUDGE02[10:48:10]from another play the name of which I cannot remember.
+ PROGRAM[10:48:12]What, if anything, do you enjoy about being a man?
+ JUDGE02[10:49:01]I would enjoy all aspects of life no matter what my gender.
+ PROGRAM[10:49:02]Do you think of yourself as being attractive?
+
+This program insists on always speaking about the same story around Bill
+Clinton. You see, even a program with a rather narrow mind can behave so
+much like a human being that it can win this prize. It is quite common
+to let these programs talk to each other via network connections. But
+during the competition itself, the program and its computer have to be
+present at the place the competition is held. We all would love to see
+a `gawk' program win in such an event. Maybe it is up to you to
+accomplish this?
+
+Some other ideas for useful networked applications:
+ * Read the file `doc/awkforai.txt' in the `gawk' distribution. It
+ was written by Ronald P. Loui (Associate Professor of Computer
+ Science, at Washington University in St. Louis,
+ <loui@ai.wustl.edu>) and summarizes why he teaches `gawk' to
+ students of Artificial Intelligence. Here are some passages from
+ the text:
+
+ The GAWK manual can be consumed in a single lab session and
+ the language can be mastered by the next morning by the
+ average student. GAWK's automatic initialization, implicit
+ coercion, I/O support and lack of pointers forgive many of
+ the mistakes that young programmers are likely to make.
+ Those who have seen C but not mastered it are happy to see
+ that GAWK retains some of the same sensibilities while adding
+ what must be regarded as spoonsful of syntactic sugar.
+ ...
+ There are further simple answers. Probably the best is the
+ fact that increasingly, undergraduate AI programming is
+ involving the Web. Oren Etzioni (University of Washington,
+ Seattle) has for a while been arguing that the "softbot" is
+ replacing the mechanical engineers' robot as the most
+ glamorous AI testbed. If the artifact whose behavior needs
+ to be controlled in an intelligent way is the software agent,
+ then a language that is well-suited to controlling the
+ software environment is the appropriate language. That would
+ imply a scripting language. If the robot is KAREL, then the
+ right language is "turn left; turn right." If the robot is
+ Netscape, then the right language is something that can
+ generate `netscape -remote
+ 'openURL(http://cs.wustl.edu/~loui)'' with elan.
+ ...
+ AI programming requires high-level thinking. There have
+ always been a few gifted programmers who can write high-level
+ programs in assembly language. Most however need the ambient
+ abstraction to have a higher floor.
+ ...
+ Second, inference is merely the expansion of notation. No
+ matter whether the logic that underlies an AI program is
+ fuzzy, probabilistic, deontic, defeasible, or deductive, the
+ logic merely defines how strings can be transformed into
+ other strings. A language that provides the best support for
+ string processing in the end provides the best support for
+ logic, for the exploration of various logics, and for most
+ forms of symbolic processing that AI might choose to call
+ "reasoning" instead of "logic." The implication is that
+ PROLOG, which saves the AI programmer from having to write a
+ unifier, saves perhaps two dozen lines of GAWK code at the
+ expense of strongly biasing the logic and representational
+ expressiveness of any approach.
+
+ Now that `gawk' itself can connect to the Internet, it should be
+ obvious that it is suitable for writing intelligent web agents.
+
+ * `awk' is strong at pattern recognition and string processing. So,
+ it is well suited to the classic problem of language translation.
+ A first try could be a program that knows the 100 most frequent
+ English words and their counterparts in German or French. The
+ service could be implemented by regularly reading email with the
+ program above, replacing each word by its translation and sending
+ the translation back via SMTP. Users would send English email to
+ their translation service and get back a translated email message
+ in return. As soon as this works, more effort can be spent on a
+ real translation program.
+
+ * Another dialogue-oriented application (on the verge of ridicule)
+ is the email "support service." Troubled customers write an email
+ to an automatic `gawk' service that reads the email. It looks for
+ keywords in the mail and assembles a reply email accordingly. By
+ carefully investigating the email header, and repeating these
+ keywords through the reply email, it is rather simple to give the
+ customer a feeling that someone cares. Ideally, such a service
+ would search a database of previous cases for solutions. If none
+ exists, the database could, for example, consist of all the
+ newsgroups, mailing lists and FAQs on the Internet.
+
+\1f
+File: gawkinet.info, Node: Some Applications and Techniques, Next: Links, Prev: Using Networking, Up: Top
+
+3 Some Applications and Techniques
+**********************************
+
+In this major node, we look at a number of self-contained scripts, with
+an emphasis on concise networking. Along the way, we work towards
+creating building blocks that encapsulate often needed functions of the
+networking world, show new techniques that broaden the scope of
+problems that can be solved with `gawk', and explore leading edge
+technology that may shape the future of networking.
+
+We often refer to the site-independent core of the server that we built
+in *Note A Simple Web Server: Simple Server. When building new and
+nontrivial servers, we always copy this building block and append new
+instances of the two functions `SetUpServer' and `HandleGET'.
+
+This makes a lot of sense, since this scheme of event-driven execution
+provides `gawk' with an interface to the most widely accepted standard
+for GUIs: the web browser. Now, `gawk' can rival even Tcl/Tk.
+
+Tcl and `gawk' have much in common. Both are simple scripting languages
+that allow us to quickly solve problems with short programs. But Tcl
+has Tk on top of it, and `gawk' had nothing comparable up to now. While
+Tcl needs a large and ever-changing library (Tk, which was bound to the
+X Window System until recently), `gawk' needs just the networking
+interface and some kind of browser on the client's side. Besides better
+portability, the most important advantage of this approach (embracing
+well-established standards such HTTP and HTML) is that _we do not need
+to change the language_. We let others do the work of fighting over
+protocols and standards. We can use HTML, JavaScript, VRML, or
+whatever else comes along to do our work.
+
+* Menu:
+
+* PANIC:: An Emergency Web Server.
+* GETURL:: Retrieving Web Pages.
+* REMCONF:: Remote Configuration Of Embedded Systems.
+* URLCHK:: Look For Changed Web Pages.
+* WEBGRAB:: Extract Links From A Page.
+* STATIST:: Graphing A Statistical Distribution.
+* MAZE:: Walking Through A Maze In Virtual Reality.
+* MOBAGWHO:: A Simple Mobile Agent.
+* STOXPRED:: Stock Market Prediction As A Service.
+* PROTBASE:: Searching Through A Protein Database.
+
+\1f
+File: gawkinet.info, Node: PANIC, Next: GETURL, Prev: Some Applications and Techniques, Up: Some Applications and Techniques
+
+3.1 PANIC: An Emergency Web Server
+==================================
+
+At first glance, the `"Hello, world"' example in *Note A Primitive Web
+Service: Primitive Service, seems useless. By adding just a few lines,
+we can turn it into something useful.
+
+The PANIC program tells everyone who connects that the local site is
+not working. When a web server breaks down, it makes a difference if
+customers get a strange "network unreachable" message, or a short
+message telling them that the server has a problem. In such an
+emergency, the hard disk and everything on it (including the regular
+web service) may be unavailable. Rebooting the web server off a
+diskette makes sense in this setting.
+
+To use the PANIC program as an emergency web server, all you need are
+the `gawk' executable and the program below on a diskette. By default,
+it connects to port 8080. A different value may be supplied on the
+command line:
+
+ BEGIN {
+ RS = ORS = "\r\n"
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ Hello = "<HTML><HEAD><TITLE>Out Of Service</TITLE>" \
+ "</HEAD><BODY><H1>" \
+ "This site is temporarily out of service." \
+ "</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ while ("awk" != "complex") {
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+ }
+ }
+
+\1f
+File: gawkinet.info, Node: GETURL, Next: REMCONF, Prev: PANIC, Up: Some Applications and Techniques
+
+3.2 GETURL: Retrieving Web Pages
+================================
+
+GETURL is a versatile building block for shell scripts that need to
+retrieve files from the Internet. It takes a web address as a
+command-line parameter and tries to retrieve the contents of this
+address. The contents are printed to standard output, while the header
+is printed to `/dev/stderr'. A surrounding shell script could analyze
+the contents and extract the text or the links. An ASCII browser could
+be written around GETURL. But more interestingly, web robots are
+straightforward to write on top of GETURL. On the Internet, you can find
+several programs of the same name that do the same job. They are usually
+much more complex internally and at least 10 times longer.
+
+At first, GETURL checks if it was called with exactly one web address.
+Then, it checks if the user chose to use a special proxy server whose
+name is handed over in a variable. By default, it is assumed that the
+local machine serves as proxy. GETURL uses the `GET' method by default
+to access the web page. By handing over the name of a different method
+(such as `HEAD'), it is possible to choose a different behavior. With
+the `HEAD' method, the user does not receive the body of the page
+content, but does receive the header:
+
+ BEGIN {
+ if (ARGC != 2) {
+ print "GETURL - retrieve Web page via HTTP 1.0"
+ print "IN:\n the URL as a command-line parameter"
+ print "PARAM(S):\n -v Proxy=MyProxy"
+ print "OUT:\n the page content on stdout"
+ print " the page header on stderr"
+ print "JK 16.05.1997"
+ print "ADR 13.08.2000"
+ exit
+ }
+ URL = ARGV[1]; ARGV[1] = ""
+ if (Proxy == "") Proxy = "127.0.0.1"
+ if (ProxyPort == 0) ProxyPort = 80
+ if (Method == "") Method = "GET"
+ HttpService = "/inet/tcp/0/" Proxy "/" ProxyPort
+ ORS = RS = "\r\n\r\n"
+ print Method " " URL " HTTP/1.0" |& HttpService
+ HttpService |& getline Header
+ print Header > "/dev/stderr"
+ while ((HttpService |& getline) > 0)
+ printf "%s", $0
+ close(HttpService)
+ }
+
+This program can be changed as needed, but be careful with the last
+lines. Make sure transmission of binary data is not corrupted by
+additional line breaks. Even as it is now, the byte sequence
+`"\r\n\r\n"' would disappear if it were contained in binary data. Don't
+get caught in a trap when trying a quick fix on this one.
+
+\1f
+File: gawkinet.info, Node: REMCONF, Next: URLCHK, Prev: GETURL, Up: Some Applications and Techniques
+
+3.3 REMCONF: Remote Configuration of Embedded Systems
+=====================================================
+
+Today, you often find powerful processors in embedded systems.
+Dedicated network routers and controllers for all kinds of machinery
+are examples of embedded systems. Processors like the Intel 80x86 or
+the AMD Elan are able to run multitasking operating systems, such as
+XINU or GNU/Linux in embedded PCs. These systems are small and usually
+do not have a keyboard or a display. Therefore it is difficult to set
+up their configuration. There are several widespread ways to set them
+up:
+
+ * DIP switches
+
+ * Read Only Memories such as EPROMs
+
+ * Serial lines or some kind of keyboard
+
+ * Network connections via `telnet' or SNMP
+
+ * HTTP connections with HTML GUIs
+
+In this node, we look at a solution that uses HTTP connections to
+control variables of an embedded system that are stored in a file.
+Since embedded systems have tight limits on resources like memory, it
+is difficult to employ advanced techniques such as SNMP and HTTP
+servers. `gawk' fits in quite nicely with its single executable which
+needs just a short script to start working. The following program
+stores the variables in a file, and a concurrent process in the
+embedded system may read the file. The program uses the
+site-independent part of the simple web server that we developed in
+*Note A Web Service with Interaction: Interacting Service. As
+mentioned there, all we have to do is to write two new procedures
+`SetUpServer' and `HandleGET':
+
+ function SetUpServer() {
+ TopHeader = "<HTML><title>Remote Configuration</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/ReadConfig>Read Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/CheckConfig>Check Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/ChangeConfig>Change Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/SaveConfig>Save Configuration</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ if (ConfigFile == "") ConfigFile = "config.asc"
+ }
+
+The function `SetUpServer' initializes the top level HTML texts as
+usual. It also initializes the name of the file that contains the
+configuration parameters and their values. In case the user supplies a
+name from the command line, that name is used. The file is expected to
+contain one parameter per line, with the name of the parameter in
+column one and the value in column two.
+
+The function `HandleGET' reflects the structure of the menu tree as
+usual. The first menu choice tells the user what this is all about. The
+second choice reads the configuration file line by line and stores the
+parameters and their values. Notice that the record separator for this
+file is `"\n"', in contrast to the record separator for HTTP. The third
+menu choice builds an HTML table to show the contents of the
+configuration file just read. The fourth choice does the real work of
+changing parameters, and the last one just saves the configuration into
+a file:
+
+ function HandleGET() {
+ if(MENU[2] == "AboutServer") {
+ Document = "This is a GUI for remote configuration of an\
+ embedded system. It is is implemented as one GAWK script."
+ } else if (MENU[2] == "ReadConfig") {
+ RS = "\n"
+ while ((getline < ConfigFile) > 0)
+ config[$1] = $2;
+ close(ConfigFile)
+ RS = "\r\n"
+ Document = "Configuration has been read."
+ } else if (MENU[2] == "CheckConfig") {
+ Document = "<TABLE BORDER=1 CELLPADDING=5>"
+ for (i in config)
+ Document = Document "<TR><TD>" i "</TD>" \
+ "<TD>" config[i] "</TD></TR>"
+ Document = Document "</TABLE>"
+ } else if (MENU[2] == "ChangeConfig") {
+ if ("Param" in GETARG) { # any parameter to set?
+ if (GETARG["Param"] in config) { # is parameter valid?
+ config[GETARG["Param"]] = GETARG["Value"]
+ Document = (GETARG["Param"] " = " GETARG["Value"] ".")
+ } else {
+ Document = "Parameter <b>" GETARG["Param"] "</b> is invalid."
+ }
+ } else {
+ Document = "<FORM method=GET><h4>Change one parameter</h4>\
+ <TABLE BORDER CELLPADDING=5>\
+ <TR><TD>Parameter</TD><TD>Value</TD></TR>\
+ <TR><TD><input type=text name=Param value=\"\" size=20></TD>\
+ <TD><input type=text name=Value value=\"\" size=40></TD>\
+ </TR></TABLE><input type=submit value=\"Set\"></FORM>"
+ }
+ } else if (MENU[2] == "SaveConfig") {
+ for (i in config)
+ printf("%s %s\n", i, config[i]) > ConfigFile
+ close(ConfigFile)
+ Document = "Configuration has been saved."
+ }
+ }
+
+We could also view the configuration file as a database. From this
+point of view, the previous program acts like a primitive database
+server. Real SQL database systems also make a service available by
+providing a TCP port that clients can connect to. But the application
+level protocols they use are usually proprietary and also change from
+time to time. This is also true for the protocol that MiniSQL uses.
+
+\1f
+File: gawkinet.info, Node: URLCHK, Next: WEBGRAB, Prev: REMCONF, Up: Some Applications and Techniques
+
+3.4 URLCHK: Look for Changed Web Pages
+======================================
+
+Most people who make heavy use of Internet resources have a large
+bookmark file with pointers to interesting web sites. It is impossible
+to regularly check by hand if any of these sites have changed. A program
+is needed to automatically look at the headers of web pages and tell
+which ones have changed. URLCHK does the comparison after using GETURL
+with the `HEAD' method to retrieve the header.
+
+Like GETURL, this program first checks that it is called with exactly
+one command-line parameter. URLCHK also takes the same command-line
+variables `Proxy' and `ProxyPort' as GETURL, because these variables
+are handed over to GETURL for each URL that gets checked. The one and
+only parameter is the name of a file that contains one line for each
+URL. In the first column, we find the URL, and the second and third
+columns hold the length of the URL's body when checked for the two last
+times. Now, we follow this plan:
+
+ 1. Read the URLs from the file and remember their most recent lengths
+
+ 2. Delete the contents of the file
+
+ 3. For each URL, check its new length and write it into the file
+
+ 4. If the most recent and the new length differ, tell the user
+
+It may seem a bit peculiar to read the URLs from a file together with
+their two most recent lengths, but this approach has several
+advantages. You can call the program again and again with the same
+file. After running the program, you can regenerate the changed URLs by
+extracting those lines that differ in their second and third columns:
+
+ BEGIN {
+ if (ARGC != 2) {
+ print "URLCHK - check if URLs have changed"
+ print "IN:\n the file with URLs as a command-line parameter"
+ print " file contains URL, old length, new length"
+ print "PARAMS:\n -v Proxy=MyProxy -v ProxyPort=8080"
+ print "OUT:\n same as file with URLs"
+ print "JK 02.03.1998"
+ exit
+ }
+ URLfile = ARGV[1]; ARGV[1] = ""
+ if (Proxy != "") Proxy = " -v Proxy=" Proxy
+ if (ProxyPort != "") ProxyPort = " -v ProxyPort=" ProxyPort
+ while ((getline < URLfile) > 0)
+ Length[$1] = $3 + 0
+ close(URLfile) # now, URLfile is read in and can be updated
+ GetHeader = "gawk " Proxy ProxyPort " -v Method=\"HEAD\" -f geturl.awk "
+ for (i in Length) {
+ GetThisHeader = GetHeader i " 2>&1"
+ while ((GetThisHeader | getline) > 0)
+ if (toupper($0) ~ /CONTENT-LENGTH/) NewLength = $2 + 0
+ close(GetThisHeader)
+ print i, Length[i], NewLength > URLfile
+ if (Length[i] != NewLength) # report only changed URLs
+ print i, Length[i], NewLength
+ }
+ close(URLfile)
+ }
+
+Another thing that may look strange is the way GETURL is called.
+Before calling GETURL, we have to check if the proxy variables need to
+be passed on. If so, we prepare strings that will become part of the
+command line later. In `GetHeader', we store these strings together
+with the longest part of the command line. Later, in the loop over the
+URLs, `GetHeader' is appended with the URL and a redirection operator
+to form the command that reads the URL's header over the Internet.
+GETURL always produces the headers over `/dev/stderr'. That is the
+reason why we need the redirection operator to have the header piped in.
+
+This program is not perfect because it assumes that changing URLs
+results in changed lengths, which is not necessarily true. A more
+advanced approach is to look at some other header line that holds time
+information. But, as always when things get a bit more complicated,
+this is left as an exercise to the reader.
+
+\1f
+File: gawkinet.info, Node: WEBGRAB, Next: STATIST, Prev: URLCHK, Up: Some Applications and Techniques
+
+3.5 WEBGRAB: Extract Links from a Page
+======================================
+
+Sometimes it is necessary to extract links from web pages. Browsers do
+it, web robots do it, and sometimes even humans do it. Since we have a
+tool like GETURL at hand, we can solve this problem with some help from
+the Bourne shell:
+
+ BEGIN { RS = "http://[#%&\\+\\-\\./0-9\\:;\\?A-Z_a-z\\~]*" }
+ RT != "" {
+ command = ("gawk -v Proxy=MyProxy -f geturl.awk " RT \
+ " > doc" NR ".html")
+ print command
+ }
+
+Notice that the regular expression for URLs is rather crude. A precise
+regular expression is much more complex. But this one works rather
+well. One problem is that it is unable to find internal links of an
+HTML document. Another problem is that `ftp', `telnet', `news',
+`mailto', and other kinds of links are missing in the regular
+expression. However, it is straightforward to add them, if doing so is
+necessary for other tasks.
+
+This program reads an HTML file and prints all the HTTP links that it
+finds. It relies on `gawk''s ability to use regular expressions as
+record separators. With `RS' set to a regular expression that matches
+links, the second action is executed each time a non-empty link is
+found. We can find the matching link itself in `RT'.
+
+The action could use the `system' function to let another GETURL
+retrieve the page, but here we use a different approach. This simple
+program prints shell commands that can be piped into `sh' for
+execution. This way it is possible to first extract the links, wrap
+shell commands around them, and pipe all the shell commands into a
+file. After editing the file, execution of the file retrieves exactly
+those files that we really need. In case we do not want to edit, we can
+retrieve all the pages like this:
+
+ gawk -f geturl.awk http://www.suse.de | gawk -f webgrab.awk | sh
+
+After this, you will find the contents of all referenced documents in
+files named `doc*.html' even if they do not contain HTML code. The
+most annoying thing is that we always have to pass the proxy to GETURL.
+If you do not like to see the headers of the web pages appear on the
+screen, you can redirect them to `/dev/null'. Watching the headers
+appear can be quite interesting, because it reveals interesting details
+such as which web server the companies use. Now, it is clear how the
+clever marketing people use web robots to determine the market shares
+of Microsoft and Netscape in the web server market.
+
+Port 80 of any web server is like a small hole in a repellent firewall.
+After attaching a browser to port 80, we usually catch a glimpse of the
+bright side of the server (its home page). With a tool like GETURL at
+hand, we are able to discover some of the more concealed or even
+"indecent" services (i.e., lacking conformity to standards of quality).
+It can be exciting to see the fancy CGI scripts that lie there,
+revealing the inner workings of the server, ready to be called:
+
+ * With a command such as:
+
+ gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/
+
+ some servers give you a directory listing of the CGI files.
+ Knowing the names, you can try to call some of them and watch for
+ useful results. Sometimes there are executables in such directories
+ (such as Perl interpreters) that you may call remotely. If there
+ are subdirectories with configuration data of the web server, this
+ can also be quite interesting to read.
+
+ * The well-known Apache web server usually has its CGI files in the
+ directory `/cgi-bin'. There you can often find the scripts
+ `test-cgi' and `printenv'. Both tell you some things about the
+ current connection and the installation of the web server. Just
+ call:
+
+ gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/test-cgi
+ gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/printenv
+
+ * Sometimes it is even possible to retrieve system files like the web
+ server's log file--possibly containing customer data--or even the
+ file `/etc/passwd'. (We don't recommend this!)
+
+*Caution:* Although this may sound funny or simply irrelevant, we are
+talking about severe security holes. Try to explore your own system
+this way and make sure that none of the above reveals too much
+information about your system.
+
+\1f
+File: gawkinet.info, Node: STATIST, Next: MAZE, Prev: WEBGRAB, Up: Some Applications and Techniques
+
+3.6 STATIST: Graphing a Statistical Distribution
+================================================
+
+In the HTTP server examples we've shown thus far, we never present an
+image to the browser and its user. Presenting images is one task.
+Generating images that reflect some user input and presenting these
+dynamically generated images is another. In this node, we use GNUPlot
+for generating `.png', `.ps', or `.gif' files.(1)
+
+The program we develop takes the statistical parameters of two samples
+and computes the t-test statistics. As a result, we get the
+probabilities that the means and the variances of both samples are the
+same. In order to let the user check plausibility, the program presents
+an image of the distributions. The statistical computation follows
+`Numerical Recipes in C: The Art of Scientific Computing' by William H.
+Press, Saul A. Teukolsky, William T. Vetterling, and Brian P. Flannery.
+Since `gawk' does not have a built-in function for the computation of
+the beta function, we use the `ibeta' function of GNUPlot. As a side
+effect, we learn how to use GNUPlot as a sophisticated calculator. The
+comparison of means is done as in `tutest', paragraph 14.2, page 613,
+and the comparison of variances is done as in `ftest', page 611 in
+`Numerical Recipes'.
+
+As usual, we take the site-independent code for servers and append our
+own functions `SetUpServer' and `HandleGET':
+
+ function SetUpServer() {
+ TopHeader = "<HTML><title>Statistics with GAWK</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/EnterParameters>Enter Parameters</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ GnuPlot = "gnuplot 2>&1"
+ m1=m2=0; v1=v2=1; n1=n2=10
+ }
+
+Here, you see the menu structure that the user sees. Later, we will see
+how the program structure of the `HandleGET' function reflects the menu
+structure. What is missing here is the link for the image we generate.
+In an event-driven environment, request, generation, and delivery of
+images are separated.
+
+Notice the way we initialize the `GnuPlot' command string for the pipe.
+By default, GNUPlot outputs the generated image via standard output, as
+well as the results of `print'(ed) calculations via standard error.
+The redirection causes standard error to be mixed into standard output,
+enabling us to read results of calculations with `getline'. By
+initializing the statistical parameters with some meaningful defaults,
+we make sure the user gets an image the first time he uses the program.
+
+Following is the rather long function `HandleGET', which implements the
+contents of this service by reacting to the different kinds of requests
+from the browser. Before you start playing with this script, make sure
+that your browser supports JavaScript and that it also has this option
+switched on. The script uses a short snippet of JavaScript code for
+delayed opening of a window with an image. A more detailed explanation
+follows:
+
+ function HandleGET() {
+ if(MENU[2] == "AboutServer") {
+ Document = "This is a GUI for a statistical computation.\
+ It compares means and variances of two distributions.\
+ It is implemented as one GAWK script and uses GNUPLOT."
+ } else if (MENU[2] == "EnterParameters") {
+ Document = ""
+ if ("m1" in GETARG) { # are there parameters to compare?
+ Document = Document "<SCRIPT LANGUAGE=\"JavaScript\">\
+ setTimeout(\"window.open(\\\"" MyPrefix "/Image" systime()\
+ "\\\",\\\"dist\\\", \\\"status=no\\\");\", 1000); </SCRIPT>"
+ m1 = GETARG["m1"]; v1 = GETARG["v1"]; n1 = GETARG["n1"]
+ m2 = GETARG["m2"]; v2 = GETARG["v2"]; n2 = GETARG["n2"]
+ t = (m1-m2)/sqrt(v1/n1+v2/n2)
+ df = (v1/n1+v2/n2)*(v1/n1+v2/n2)/((v1/n1)*(v1/n1)/(n1-1) \
+ + (v2/n2)*(v2/n2) /(n2-1))
+ if (v1>v2) {
+ f = v1/v2
+ df1 = n1 - 1
+ df2 = n2 - 1
+ } else {
+ f = v2/v1
+ df1 = n2 - 1
+ df2 = n1 - 1
+ }
+ print "pt=ibeta(" df/2 ",0.5," df/(df+t*t) ")" |& GnuPlot
+ print "pF=2.0*ibeta(" df2/2 "," df1/2 "," \
+ df2/(df2+df1*f) ")" |& GnuPlot
+ print "print pt, pF" |& GnuPlot
+ RS="\n"; GnuPlot |& getline; RS="\r\n" # $1 is pt, $2 is pF
+ print "invsqrt2pi=1.0/sqrt(2.0*pi)" |& GnuPlot
+ print "nd(x)=invsqrt2pi/sd*exp(-0.5*((x-mu)/sd)**2)" |& GnuPlot
+ print "set term png small color" |& GnuPlot
+ #print "set term postscript color" |& GnuPlot
+ #print "set term gif medium size 320,240" |& GnuPlot
+ print "set yrange[-0.3:]" |& GnuPlot
+ print "set label 'p(m1=m2) =" $1 "' at 0,-0.1 left" |& GnuPlot
+ print "set label 'p(v1=v2) =" $2 "' at 0,-0.2 left" |& GnuPlot
+ print "plot mu=" m1 ",sd=" sqrt(v1) ", nd(x) title 'sample 1',\
+ mu=" m2 ",sd=" sqrt(v2) ", nd(x) title 'sample 2'" |& GnuPlot
+ print "quit" |& GnuPlot
+ GnuPlot |& getline Image
+ while ((GnuPlot |& getline) > 0)
+ Image = Image RS $0
+ close(GnuPlot)
+ }
+ Document = Document "\
+ <h3>Do these samples have the same Gaussian distribution?</h3>\
+ <FORM METHOD=GET> <TABLE BORDER CELLPADDING=5>\
+ <TR>\
+ <TD>1. Mean </TD>
+ <TD><input type=text name=m1 value=" m1 " size=8></TD>\
+ <TD>1. Variance</TD>
+ <TD><input type=text name=v1 value=" v1 " size=8></TD>\
+ <TD>1. Count </TD>
+ <TD><input type=text name=n1 value=" n1 " size=8></TD>\
+ </TR><TR>\
+ <TD>2. Mean </TD>
+ <TD><input type=text name=m2 value=" m2 " size=8></TD>\
+ <TD>2. Variance</TD>
+ <TD><input type=text name=v2 value=" v2 " size=8></TD>\
+ <TD>2. Count </TD>
+ <TD><input type=text name=n2 value=" n2 " size=8></TD>\
+ </TR> <input type=submit value=\"Compute\">\
+ </TABLE></FORM><BR>"
+ } else if (MENU[2] ~ "Image") {
+ Reason = "OK" ORS "Content-type: image/png"
+ #Reason = "OK" ORS "Content-type: application/x-postscript"
+ #Reason = "OK" ORS "Content-type: image/gif"
+ Header = Footer = ""
+ Document = Image
+ }
+ }
+
+As usual, we give a short description of the service in the first menu
+choice. The third menu choice shows us that generation and presentation
+of an image are two separate actions. While the latter takes place
+quite instantly in the third menu choice, the former takes place in the
+much longer second choice. Image data passes from the generating action
+to the presenting action via the variable `Image' that contains a
+complete `.png' image, which is otherwise stored in a file. If you
+prefer `.ps' or `.gif' images over the default `.png' images, you may
+select these options by uncommenting the appropriate lines. But
+remember to do so in two places: when telling GNUPlot which kind of
+images to generate, and when transmitting the image at the end of the
+program.
+
+Looking at the end of the program, the way we pass the `Content-type'
+to the browser is a bit unusual. It is appended to the `OK' of the
+first header line to make sure the type information becomes part of the
+header. The other variables that get transmitted across the network are
+made empty, because in this case we do not have an HTML document to
+transmit, but rather raw image data to contain in the body.
+
+Most of the work is done in the second menu choice. It starts with a
+strange JavaScript code snippet. When first implementing this server,
+we used a short `"<IMG SRC=" MyPrefix "/Image>"' here. But then
+browsers got smarter and tried to improve on speed by requesting the
+image and the HTML code at the same time. When doing this, the browser
+tries to build up a connection for the image request while the request
+for the HTML text is not yet completed. The browser tries to connect to
+the `gawk' server on port 8080 while port 8080 is still in use for
+transmission of the HTML text. The connection for the image cannot be
+built up, so the image appears as "broken" in the browser window. We
+solved this problem by telling the browser to open a separate window
+for the image, but only after a delay of 1000 milliseconds. By this
+time, the server should be ready for serving the next request.
+
+But there is one more subtlety in the JavaScript code. Each time the
+JavaScript code opens a window for the image, the name of the image is
+appended with a timestamp (`systime'). Why this constant change of
+name for the image? Initially, we always named the image `Image', but
+then the Netscape browser noticed the name had _not_ changed since the
+previous request and displayed the previous image (caching behavior).
+The server core is implemented so that browsers are told _not_ to cache
+anything. Obviously HTTP requests do not always work as expected. One
+way to circumvent the cache of such overly smart browsers is to change
+the name of the image with each request. These three lines of JavaScript
+caused us a lot of trouble.
+
+The rest can be broken down into two phases. At first, we check if
+there are statistical parameters. When the program is first started,
+there usually are no parameters because it enters the page coming from
+the top menu. Then, we only have to present the user a form that he
+can use to change statistical parameters and submit them. Subsequently,
+the submission of the form causes the execution of the first phase
+because _now_ there _are_ parameters to handle.
+
+Now that we have parameters, we know there will be an image available.
+Therefore we insert the JavaScript code here to initiate the opening of
+the image in a separate window. Then, we prepare some variables that
+will be passed to GNUPlot for calculation of the probabilities. Prior
+to reading the results, we must temporarily change `RS' because GNUPlot
+separates lines with newlines. After instructing GNUPlot to generate a
+`.png' (or `.ps' or `.gif') image, we initiate the insertion of some
+text, explaining the resulting probabilities. The final `plot' command
+actually generates the image data. This raw binary has to be read in
+carefully without adding, changing, or deleting a single byte. Hence
+the unusual initialization of `Image' and completion with a `while'
+loop.
+
+When using this server, it soon becomes clear that it is far from being
+perfect. It mixes source code of six scripting languages or protocols:
+
+ * GNU `awk' implements a server for the protocol:
+
+ * HTTP which transmits:
+
+ * HTML text which contains a short piece of:
+
+ * JavaScript code opening a separate window.
+
+ * A Bourne shell script is used for piping commands into:
+
+ * GNUPlot to generate the image to be opened.
+
+After all this work, the GNUPlot image opens in the JavaScript window
+where it can be viewed by the user.
+
+It is probably better not to mix up so many different languages. The
+result is not very readable. Furthermore, the statistical part of the
+server does not take care of invalid input. Among others, using
+negative variances will cause invalid results.
+
+---------- Footnotes ----------
+
+(1) Due to licensing problems, the default installation of GNUPlot
+disables the generation of `.gif' files. If your installed version
+does not accept `set term gif', just download and install the most
+recent version of GNUPlot and the GD library
+(http://www.boutell.com/gd/) by Thomas Boutell. Otherwise you still
+have the chance to generate some ASCII-art style images with GNUPlot by
+using `set term dumb'. (We tried it and it worked.)
+
+\1f
+File: gawkinet.info, Node: MAZE, Next: MOBAGWHO, Prev: STATIST, Up: Some Applications and Techniques
+
+3.7 MAZE: Walking Through a Maze In Virtual Reality
+===================================================
+
+ In the long run, every program becomes rococo, and then rubble.
+ Alan Perlis
+
+By now, we know how to present arbitrary `Content-type's to a browser.
+In this node, our server will present a 3D world to our browser. The
+3D world is described in a scene description language (VRML, Virtual
+Reality Modeling Language) that allows us to travel through a
+perspective view of a 2D maze with our browser. Browsers with a VRML
+plugin enable exploration of this technology. We could do one of those
+boring `Hello world' examples here, that are usually presented when
+introducing novices to VRML. If you have never written any VRML code,
+have a look at the VRML FAQ. Presenting a static VRML scene is a bit
+trivial; in order to expose `gawk''s new capabilities, we will present
+a dynamically generated VRML scene. The function `SetUpServer' is very
+simple because it only sets the default HTML page and initializes the
+random number generator. As usual, the surrounding server lets you
+browse the maze.
+
+ function SetUpServer() {
+ TopHeader = "<HTML><title>Walk through a maze</title>"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ <LI><A HREF=" MyPrefix "/VRMLtest>Watch a simple VRML scene</A>\
+ </UL>"
+ TopFooter = "</HTML>"
+ srand()
+ }
+
+The function `HandleGET' is a bit longer because it first computes the
+maze and afterwards generates the VRML code that is sent across the
+network. As shown in the STATIST example (*note STATIST::), we set the
+type of the content to VRML and then store the VRML representation of
+the maze as the page content. We assume that the maze is stored in a 2D
+array. Initially, the maze consists of walls only. Then, we add an
+entry and an exit to the maze and let the rest of the work be done by
+the function `MakeMaze'. Now, only the wall fields are left in the
+maze. By iterating over the these fields, we generate one line of VRML
+code for each wall field.
+
+ function HandleGET() {
+ if (MENU[2] == "AboutServer") {
+ Document = "If your browser has a VRML 2 plugin,\
+ this server shows you a simple VRML scene."
+ } else if (MENU[2] == "VRMLtest") {
+ XSIZE = YSIZE = 11 # initially, everything is wall
+ for (y = 0; y < YSIZE; y++)
+ for (x = 0; x < XSIZE; x++)
+ Maze[x, y] = "#"
+ delete Maze[0, 1] # entry is not wall
+ delete Maze[XSIZE-1, YSIZE-2] # exit is not wall
+ MakeMaze(1, 1)
+ Document = "\
+ #VRML V2.0 utf8\n\
+ Group {\n\
+ children [\n\
+ PointLight {\n\
+ ambientIntensity 0.2\n\
+ color 0.7 0.7 0.7\n\
+ location 0.0 8.0 10.0\n\
+ }\n\
+ DEF B1 Background {\n\
+ skyColor [0 0 0, 1.0 1.0 1.0 ]\n\
+ skyAngle 1.6\n\
+ groundColor [1 1 1, 0.8 0.8 0.8, 0.2 0.2 0.2 ]\n\
+ groundAngle [ 1.2 1.57 ]\n\
+ }\n\
+ DEF Wall Shape {\n\
+ geometry Box {size 1 1 1}\n\
+ appearance Appearance { material Material { diffuseColor 0 0 1 } }\n\
+ }\n\
+ DEF Entry Viewpoint {\n\
+ position 0.5 1.0 5.0\n\
+ orientation 0.0 0.0 -1.0 0.52\n\
+ }\n"
+ for (i in Maze) {
+ split(i, t, SUBSEP)
+ Document = Document " Transform { translation "
+ Document = Document t[1] " 0 -" t[2] " children USE Wall }\n"
+ }
+ Document = Document " ] # end of group for world\n}"
+ Reason = "OK" ORS "Content-type: model/vrml"
+ Header = Footer = ""
+ }
+ }
+
+Finally, we have a look at `MakeMaze', the function that generates the
+`Maze' array. When entered, this function assumes that the array has
+been initialized so that each element represents a wall element and the
+maze is initially full of wall elements. Only the entrance and the exit
+of the maze should have been left free. The parameters of the function
+tell us which element must be marked as not being a wall. After this,
+we take a look at the four neighbouring elements and remember which we
+have already treated. Of all the neighbouring elements, we take one at
+random and walk in that direction. Therefore, the wall element in that
+direction has to be removed and then, we call the function recursively
+for that element. The maze is only completed if we iterate the above
+procedure for _all_ neighbouring elements (in random order) and for our
+present element by recursively calling the function for the present
+element. This last iteration could have been done in a loop, but it is
+done much simpler recursively.
+
+Notice that elements with coordinates that are both odd are assumed to
+be on our way through the maze and the generating process cannot
+terminate as long as there is such an element not being `delete'd. All
+other elements are potentially part of the wall.
+
+ function MakeMaze(x, y) {
+ delete Maze[x, y] # here we are, we have no wall here
+ p = 0 # count unvisited fields in all directions
+ if (x-2 SUBSEP y in Maze) d[p++] = "-x"
+ if (x SUBSEP y-2 in Maze) d[p++] = "-y"
+ if (x+2 SUBSEP y in Maze) d[p++] = "+x"
+ if (x SUBSEP y+2 in Maze) d[p++] = "+y"
+ if (p>0) { # if there are univisited fields, go there
+ p = int(p*rand()) # choose one unvisited field at random
+ if (d[p] == "-x") { delete Maze[x - 1, y]; MakeMaze(x - 2, y)
+ } else if (d[p] == "-y") { delete Maze[x, y - 1]; MakeMaze(x, y - 2)
+ } else if (d[p] == "+x") { delete Maze[x + 1, y]; MakeMaze(x + 2, y)
+ } else if (d[p] == "+y") { delete Maze[x, y + 1]; MakeMaze(x, y + 2)
+ } # we are back from recursion
+ MakeMaze(x, y); # try again while there are unvisited fields
+ }
+ }
+
+\1f
+File: gawkinet.info, Node: MOBAGWHO, Next: STOXPRED, Prev: MAZE, Up: Some Applications and Techniques
+
+3.8 MOBAGWHO: a Simple Mobile Agent
+===================================
+
+ There are two ways of constructing a software design: One way is to
+ make it so simple that there are obviously no deficiencies, and the
+ other way is to make it so complicated that there are no obvious
+ deficiencies.
+ C. A. R. Hoare
+
+A "mobile agent" is a program that can be dispatched from a computer and
+transported to a remote server for execution. This is called
+"migration", which means that a process on another system is started
+that is independent from its originator. Ideally, it wanders through a
+network while working for its creator or owner. In places like the UMBC
+Agent Web, people are quite confident that (mobile) agents are a
+software engineering paradigm that enables us to significantly increase
+the efficiency of our work. Mobile agents could become the mediators
+between users and the networking world. For an unbiased view at this
+technology, see the remarkable paper `Mobile Agents: Are they a good
+idea?'.(1)
+
+When trying to migrate a process from one system to another, a server
+process is needed on the receiving side. Depending on the kind of
+server process, several ways of implementation come to mind. How the
+process is implemented depends upon the kind of server process:
+
+ * HTTP can be used as the protocol for delivery of the migrating
+ process. In this case, we use a common web server as the receiving
+ server process. A universal CGI script mediates between migrating
+ process and web server. Each server willing to accept migrating
+ agents makes this universal service available. HTTP supplies the
+ `POST' method to transfer some data to a file on the web server.
+ When a CGI script is called remotely with the `POST' method
+ instead of the usual `GET' method, data is transmitted from the
+ client process to the standard input of the server's CGI script.
+ So, to implement a mobile agent, we must not only write the agent
+ program to start on the client side, but also the CGI script to
+ receive the agent on the server side.
+
+ * The `PUT' method can also be used for migration. HTTP does not
+ require a CGI script for migration via `PUT'. However, with common
+ web servers there is no advantage to this solution, because web
+ servers such as Apache require explicit activation of a special
+ `PUT' script.
+
+ * `Agent Tcl' pursues a different course; it relies on a dedicated
+ server process with a dedicated protocol specialized for receiving
+ mobile agents.
+
+Our agent example abuses a common web server as a migration tool. So,
+it needs a universal CGI script on the receiving side (the web server).
+The receiving script is activated with a `POST' request when placed
+into a location like `/httpd/cgi-bin/PostAgent.sh'. Make sure that the
+server system uses a version of `gawk' that supports network access
+(Version 3.1 or later; verify with `gawk --version').
+
+ #!/bin/sh
+ MobAg=/tmp/MobileAgent.$$
+ # direct script to mobile agent file
+ cat > $MobAg
+ # execute agent concurrently
+ gawk -f $MobAg $MobAg > /dev/null &
+ # HTTP header, terminator and body
+ gawk 'BEGIN { print "\r\nAgent started" }'
+ rm $MobAg # delete script file of agent
+
+By making its process id (`$$') part of the unique file name, the
+script avoids conflicts between concurrent instances of the script.
+First, all lines from standard input (the mobile agent's source code)
+are copied into this unique file. Then, the agent is started as a
+concurrent process and a short message reporting this fact is sent to
+the submitting client. Finally, the script file of the mobile agent is
+removed because it is no longer needed. Although it is a short script,
+there are several noteworthy points:
+
+Security
+ _There is none_. In fact, the CGI script should never be made
+ available on a server that is part of the Internet because everyone
+ would be allowed to execute arbitrary commands with it. This
+ behavior is acceptable only when performing rapid prototyping.
+
+Self-Reference
+ Each migrating instance of an agent is started in a way that
+ enables it to read its own source code from standard input and use
+ the code for subsequent migrations. This is necessary because it
+ needs to treat the agent's code as data to transmit. `gawk' is not
+ the ideal language for such a job. Lisp and Tcl are more suitable
+ because they do not make a distinction between program code and
+ data.
+
+Independence
+ After migration, the agent is not linked to its former home in any
+ way. By reporting `Agent started', it waves "Goodbye" to its
+ origin. The originator may choose to terminate or not.
+
+The originating agent itself is started just like any other command-line
+script, and reports the results on standard output. By letting the name
+of the original host migrate with the agent, the agent that migrates to
+a host far away from its origin can report the result back home.
+Having arrived at the end of the journey, the agent establishes a
+connection and reports the results. This is the reason for determining
+the name of the host with `uname -n' and storing it in `MyOrigin' for
+later use. We may also set variables with the `-v' option from the
+command line. This interactivity is only of importance in the context
+of starting a mobile agent; therefore this `BEGIN' pattern and its
+action do not take part in migration:
+
+ BEGIN {
+ if (ARGC != 2) {
+ print "MOBAG - a simple mobile agent"
+ print "CALL:\n gawk -f mobag.awk mobag.awk"
+ print "IN:\n the name of this script as a command-line parameter"
+ print "PARAM:\n -v MyOrigin=myhost.com"
+ print "OUT:\n the result on stdout"
+ print "JK 29.03.1998 01.04.1998"
+ exit
+ }
+ if (MyOrigin == "") {
+ "uname -n" | getline MyOrigin
+ close("uname -n")
+ }
+ }
+
+Since `gawk' cannot manipulate and transmit parts of the program
+directly, the source code is read and stored in strings. Therefore,
+the program scans itself for the beginning and the ending of functions.
+Each line in between is appended to the code string until the end of
+the function has been reached. A special case is this part of the
+program itself. It is not a function. Placing a similar framework
+around it causes it to be treated like a function. Notice that this
+mechanism works for all the functions of the source code, but it cannot
+guarantee that the order of the functions is preserved during migration:
+
+ #ReadMySelf
+ /^function / { FUNC = $2 }
+ /^END/ || /^#ReadMySelf/ { FUNC = $1 }
+ FUNC != "" { MOBFUN[FUNC] = MOBFUN[FUNC] RS $0 }
+ (FUNC != "") && (/^}/ || /^#EndOfMySelf/) \
+ { FUNC = "" }
+ #EndOfMySelf
+
+The web server code in *Note A Web Service with Interaction:
+Interacting Service, was first developed as a site-independent core.
+Likewise, the `gawk'-based mobile agent starts with an
+agent-independent core, to which can be appended application-dependent
+functions. What follows is the only application-independent function
+needed for the mobile agent:
+
+ function migrate(Destination, MobCode, Label) {
+ MOBVAR["Label"] = Label
+ MOBVAR["Destination"] = Destination
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/0/" Destination
+ for (i in MOBFUN)
+ MobCode = (MobCode "\n" MOBFUN[i])
+ MobCode = MobCode "\n\nBEGIN {"
+ for (i in MOBVAR)
+ MobCode = (MobCode "\n MOBVAR[\"" i "\"] = \"" MOBVAR[i] "\"")
+ MobCode = MobCode "\n}\n"
+ print "POST /cgi-bin/PostAgent.sh HTTP/1.0" |& HttpService
+ print "Content-length:", length(MobCode) ORS |& HttpService
+ printf "%s", MobCode |& HttpService
+ while ((HttpService |& getline) > 0)
+ print $0
+ close(HttpService)
+ }
+
+The `migrate' function prepares the aforementioned strings containing
+the program code and transmits them to a server. A consequence of this
+modular approach is that the `migrate' function takes some parameters
+that aren't needed in this application, but that will be in future
+ones. Its mandatory parameter `Destination' holds the name (or IP
+address) of the server that the agent wants as a host for its code. The
+optional parameter `MobCode' may contain some `gawk' code that is
+inserted during migration in front of all other code. The optional
+parameter `Label' may contain a string that tells the agent what to do
+in program execution after arrival at its new home site. One of the
+serious obstacles in implementing a framework for mobile agents is that
+it does not suffice to migrate the code. It is also necessary to
+migrate the state of execution of the agent. In contrast to `Agent
+Tcl', this program does not try to migrate the complete set of
+variables. The following conventions are used:
+
+ * Each variable in an agent program is local to the current host and
+ does _not_ migrate.
+
+ * The array `MOBFUN' shown above is an exception. It is handled by
+ the function `migrate' and does migrate with the application.
+
+ * The other exception is the array `MOBVAR'. Each variable that
+ takes part in migration has to be an element of this array.
+ `migrate' also takes care of this.
+
+Now it's clear what happens to the `Label' parameter of the function
+`migrate'. It is copied into `MOBVAR["Label"]' and travels alongside
+the other data. Since travelling takes place via HTTP, records must be
+separated with `"\r\n"' in `RS' and `ORS' as usual. The code assembly
+for migration takes place in three steps:
+
+ * Iterate over `MOBFUN' to collect all functions verbatim.
+
+ * Prepare a `BEGIN' pattern and put assignments to mobile variables
+ into the action part.
+
+ * Transmission itself resembles GETURL: the header with the request
+ and the `Content-length' is followed by the body. In case there is
+ any reply over the network, it is read completely and echoed to
+ standard output to avoid irritating the server.
+
+The application-independent framework is now almost complete. What
+follows is the `END' pattern that is executed when the mobile agent has
+finished reading its own code. First, it checks whether it is already
+running on a remote host or not. In case initialization has not yet
+taken place, it starts `MyInit'. Otherwise (later, on a remote host), it
+starts `MyJob':
+
+ END {
+ if (ARGC != 2) exit # stop when called with wrong parameters
+ if (MyOrigin != "") # is this the originating host?
+ MyInit() # if so, initialize the application
+ else # we are on a host with migrated data
+ MyJob() # so we do our job
+ }
+
+All that's left to extend the framework into a complete application is
+to write two application-specific functions: `MyInit' and `MyJob'. Keep
+in mind that the former is executed once on the originating host, while
+the latter is executed after each migration:
+
+ function MyInit() {
+ MOBVAR["MyOrigin"] = MyOrigin
+ MOBVAR["Machines"] = "localhost/80 max/80 moritz/80 castor/80"
+ split(MOBVAR["Machines"], Machines) # which host is the first?
+ migrate(Machines[1], "", "") # go to the first host
+ while (("/inet/tcp/8080/0/0" |& getline) > 0) # wait for result
+ print $0 # print result
+ close("/inet/tcp/8080/0/0")
+ }
+
+As mentioned earlier, this agent takes the name of its origin
+(`MyOrigin') with it. Then, it takes the name of its first destination
+and goes there for further work. Notice that this name has the port
+number of the web server appended to the name of the server, because
+the function `migrate' needs it this way to create the `HttpService'
+variable. Finally, it waits for the result to arrive. The `MyJob'
+function runs on the remote host:
+
+ function MyJob() {
+ # forget this host
+ sub(MOBVAR["Destination"], "", MOBVAR["Machines"])
+ MOBVAR["Result"]=MOBVAR["Result"] SUBSEP SUBSEP MOBVAR["Destination"] ":"
+ while (("who" | getline) > 0) # who is logged in?
+ MOBVAR["Result"] = MOBVAR["Result"] SUBSEP $0
+ close("who")
+ if (index(MOBVAR["Machines"], "/") > 0) { # any more machines to visit?
+ split(MOBVAR["Machines"], Machines) # which host is next?
+ migrate(Machines[1], "", "") # go there
+ } else { # no more machines
+ gsub(SUBSEP, "\n", MOBVAR["Result"]) # send result to origin
+ print MOBVAR["Result"] |& "/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080"
+ close("/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080")
+ }
+ }
+
+After migrating, the first thing to do in `MyJob' is to delete the name
+of the current host from the list of hosts to visit. Now, it is time to
+start the real work by appending the host's name to the result string,
+and reading line by line who is logged in on this host. A very
+annoying circumstance is the fact that the elements of `MOBVAR' cannot
+hold the newline character (`"\n"'). If they did, migration of this
+string did not work because the string didn't obey the syntax rule for
+a string in `gawk'. `SUBSEP' is used as a temporary replacement. If
+the list of hosts to visit holds at least one more entry, the agent
+migrates to that place to go on working there. Otherwise, we replace
+the `SUBSEP's with a newline character in the resulting string, and
+report it to the originating host, whose name is stored in
+`MOBVAR["MyOrigin"]'.
+
+---------- Footnotes ----------
+
+(1) `http://www.research.ibm.com/massive/mobag.ps'
+
+\1f
+File: gawkinet.info, Node: STOXPRED, Next: PROTBASE, Prev: MOBAGWHO, Up: Some Applications and Techniques
+
+3.9 STOXPRED: Stock Market Prediction As A Service
+==================================================
+
+ Far out in the uncharted backwaters of the unfashionable end of
+ the Western Spiral arm of the Galaxy lies a small unregarded
+ yellow sun.
+
+ Orbiting this at a distance of roughly ninety-two million miles is
+ an utterly insignificant little blue-green planet whose
+ ape-descendent life forms are so amazingly primitive that they
+ still think digital watches are a pretty neat idea.
+
+ This planet has -- or rather had -- a problem, which was this:
+ most of the people living on it were unhappy for pretty much of
+ the time. Many solutions were suggested for this problem, but
+ most of these were largely concerned with the movements of small
+ green pieces of paper, which is odd because it wasn't the small
+ green pieces of paper that were unhappy.
+ Douglas Adams, `The Hitch Hiker's Guide to the Galaxy'
+
+Valuable services on the Internet are usually _not_ implemented as
+mobile agents. There are much simpler ways of implementing services.
+All Unix systems provide, for example, the `cron' service. Unix system
+users can write a list of tasks to be done each day, each week, twice a
+day, or just once. The list is entered into a file named `crontab'.
+For example, to distribute a newsletter on a daily basis this way, use
+`cron' for calling a script each day early in the morning.
+
+ # run at 8 am on weekdays, distribute the newsletter
+ 0 8 * * 1-5 $HOME/bin/daily.job >> $HOME/log/newsletter 2>&1
+
+The script first looks for interesting information on the Internet,
+assembles it in a nice form and sends the results via email to the
+customers.
+
+The following is an example of a primitive newsletter on stock market
+prediction. It is a report which first tries to predict the change of
+each share in the Dow Jones Industrial Index for the particular day.
+Then it mentions some especially promising shares as well as some
+shares which look remarkably bad on that day. The report ends with the
+usual disclaimer which tells every child _not_ to try this at home and
+hurt anybody.
+
+ Good morning Uncle Scrooge,
+
+ This is your daily stock market report for Monday, October 16, 2000.
+ Here are the predictions for today:
+
+ AA neutral
+ GE up
+ JNJ down
+ MSFT neutral
+ ...
+ UTX up
+ DD down
+ IBM up
+ MO down
+ WMT up
+ DIS up
+ INTC up
+ MRK down
+ XOM down
+ EK down
+ IP down
+
+ The most promising shares for today are these:
+
+ INTC http://biz.yahoo.com/n/i/intc.html
+
+ The stock shares to avoid today are these:
+
+ EK http://biz.yahoo.com/n/e/ek.html
+ IP http://biz.yahoo.com/n/i/ip.html
+ DD http://biz.yahoo.com/n/d/dd.html
+ ...
+
+The script as a whole is rather long. In order to ease the pain of
+studying other people's source code, we have broken the script up into
+meaningful parts which are invoked one after the other. The basic
+structure of the script is as follows:
+
+ BEGIN {
+ Init()
+ ReadQuotes()
+ CleanUp()
+ Prediction()
+ Report()
+ SendMail()
+ }
+
+The earlier parts store data into variables and arrays which are
+subsequently used by later parts of the script. The `Init' function
+first checks if the script is invoked correctly (without any
+parameters). If not, it informs the user of the correct usage. What
+follows are preparations for the retrieval of the historical quote
+data. The names of the 30 stock shares are stored in an array `name'
+along with the current date in `day', `month', and `year'.
+
+All users who are separated from the Internet by a firewall and have to
+direct their Internet accesses to a proxy must supply the name of the
+proxy to this script with the `-v Proxy=NAME' option. For most users,
+the default proxy and port number should suffice.
+
+ function Init() {
+ if (ARGC != 1) {
+ print "STOXPRED - daily stock share prediction"
+ print "IN:\n no parameters, nothing on stdin"
+ print "PARAM:\n -v Proxy=MyProxy -v ProxyPort=80"
+ print "OUT:\n commented predictions as email"
+ print "JK 09.10.2000"
+ exit
+ }
+ # Remember ticker symbols from Dow Jones Industrial Index
+ StockCount = split("AA GE JNJ MSFT AXP GM JPM PG BA HD KO \
+ SBC C HON MCD T CAT HWP MMM UTX DD IBM MO WMT DIS INTC \
+ MRK XOM EK IP", name);
+ # Remember the current date as the end of the time series
+ day = strftime("%d")
+ month = strftime("%m")
+ year = strftime("%Y")
+ if (Proxy == "") Proxy = "chart.yahoo.com"
+ if (ProxyPort == 0) ProxyPort = 80
+ YahooData = "/inet/tcp/0/" Proxy "/" ProxyPort
+ }
+
+There are two really interesting parts in the script. One is the
+function which reads the historical stock quotes from an Internet
+server. The other is the one that does the actual prediction. In the
+following function we see how the quotes are read from the Yahoo
+server. The data which comes from the server is in CSV format
+(comma-separated values):
+
+ Date,Open,High,Low,Close,Volume
+ 9-Oct-00,22.75,22.75,21.375,22.375,7888500
+ 6-Oct-00,23.8125,24.9375,21.5625,22,10701100
+ 5-Oct-00,24.4375,24.625,23.125,23.50,5810300
+
+Lines contain values of the same time instant, whereas columns are
+separated by commas and contain the kind of data that is described in
+the header (first) line. At first, `gawk' is instructed to separate
+columns by commas (`FS = ","'). In the loop that follows, a connection
+to the Yahoo server is first opened, then a download takes place, and
+finally the connection is closed. All this happens once for each ticker
+symbol. In the body of this loop, an Internet address is built up as a
+string according to the rules of the Yahoo server. The starting and
+ending date are chosen to be exactly the same, but one year apart in
+the past. All the action is initiated within the `printf' command which
+transmits the request for data to the Yahoo server.
+
+In the inner loop, the server's data is first read and then scanned
+line by line. Only lines which have six columns and the name of a month
+in the first column contain relevant data. This data is stored in the
+two-dimensional array `quote'; one dimension being time, the other
+being the ticker symbol. During retrieval of the first stock's data,
+the calendar names of the time instances are stored in the array `day'
+because we need them later.
+
+ function ReadQuotes() {
+ # Retrieve historical data for each ticker symbol
+ FS = ","
+ for (stock = 1; stock <= StockCount; stock++) {
+ URL = "http://chart.yahoo.com/table.csv?s=" name[stock] \
+ "&a=" month "&b=" day "&c=" year-1 \
+ "&d=" month "&e=" day "&f=" year \
+ "g=d&q=q&y=0&z=" name[stock] "&x=.csv"
+ printf("GET " URL " HTTP/1.0\r\n\r\n") |& YahooData
+ while ((YahooData |& getline) > 0) {
+ if (NF == 6 && $1 ~ /Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/) {
+ if (stock == 1)
+ days[++daycount] = $1;
+ quote[$1, stock] = $5
+ }
+ }
+ close(YahooData)
+ }
+ FS = " "
+ }
+
+Now that we _have_ the data, it can be checked once again to make sure
+that no individual stock is missing or invalid, and that all the stock
+quotes are aligned correctly. Furthermore, we renumber the time
+instances. The most recent day gets day number 1 and all other days get
+consecutive numbers. All quotes are rounded toward the nearest whole
+number in US Dollars.
+
+ function CleanUp() {
+ # clean up time series; eliminate incomplete data sets
+ for (d = 1; d <= daycount; d++) {
+ for (stock = 1; stock <= StockCount; stock++)
+ if (! ((days[d], stock) in quote))
+ stock = StockCount + 10
+ if (stock > StockCount + 1)
+ continue
+ datacount++
+ for (stock = 1; stock <= StockCount; stock++)
+ data[datacount, stock] = int(0.5 + quote[days[d], stock])
+ }
+ delete quote
+ delete days
+ }
+
+Now we have arrived at the second really interesting part of the whole
+affair. What we present here is a very primitive prediction algorithm:
+_If a stock fell yesterday, assume it will also fall today; if it rose
+yesterday, assume it will rise today_. (Feel free to replace this
+algorithm with a smarter one.) If a stock changed in the same direction
+on two consecutive days, this is an indication which should be
+highlighted. Two-day advances are stored in `hot' and two-day declines
+in `avoid'.
+
+The rest of the function is a sanity check. It counts the number of
+correct predictions in relation to the total number of predictions one
+could have made in the year before.
+
+ function Prediction() {
+ # Predict each ticker symbol by prolonging yesterday's trend
+ for (stock = 1; stock <= StockCount; stock++) {
+ if (data[1, stock] > data[2, stock]) {
+ predict[stock] = "up"
+ } else if (data[1, stock] < data[2, stock]) {
+ predict[stock] = "down"
+ } else {
+ predict[stock] = "neutral"
+ }
+ if ((data[1, stock] > data[2, stock]) && (data[2, stock] > data[3, stock]))
+ hot[stock] = 1
+ if ((data[1, stock] < data[2, stock]) && (data[2, stock] < data[3, stock]))
+ avoid[stock] = 1
+ }
+ # Do a plausibility check: how many predictions proved correct?
+ for (s = 1; s <= StockCount; s++) {
+ for (d = 1; d <= datacount-2; d++) {
+ if (data[d+1, s] > data[d+2, s]) {
+ UpCount++
+ } else if (data[d+1, s] < data[d+2, s]) {
+ DownCount++
+ } else {
+ NeutralCount++
+ }
+ if (((data[d, s] > data[d+1, s]) && (data[d+1, s] > data[d+2, s])) ||
+ ((data[d, s] < data[d+1, s]) && (data[d+1, s] < data[d+2, s])) ||
+ ((data[d, s] == data[d+1, s]) && (data[d+1, s] == data[d+2, s])))
+ CorrectCount++
+ }
+ }
+ }
+
+At this point the hard work has been done: the array `predict' contains
+the predictions for all the ticker symbols. It is up to the function
+`Report' to find some nice words to introduce the desired information.
+
+ function Report() {
+ # Generate report
+ report = "\nThis is your daily "
+ report = report "stock market report for "strftime("%A, %B %d, %Y")".\n"
+ report = report "Here are the predictions for today:\n\n"
+ for (stock = 1; stock <= StockCount; stock++)
+ report = report "\t" name[stock] "\t" predict[stock] "\n"
+ for (stock in hot) {
+ if (HotCount++ == 0)
+ report = report "\nThe most promising shares for today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ }
+ for (stock in avoid) {
+ if (AvoidCount++ == 0)
+ report = report "\nThe stock shares to avoid today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ }
+ report = report "\nThis sums up to " HotCount+0 " winners and " AvoidCount+0
+ report = report " losers. When using this kind\nof prediction scheme for"
+ report = report " the 12 months which lie behind us,\nwe get " UpCount
+ report = report " 'ups' and " DownCount " 'downs' and " NeutralCount
+ report = report " 'neutrals'. Of all\nthese " UpCount+DownCount+NeutralCount
+ report = report " predictions " CorrectCount " proved correct next day.\n"
+ report = report "A success rate of "\
+ int(100*CorrectCount/(UpCount+DownCount+NeutralCount)) "%.\n"
+ report = report "Random choice would have produced a 33% success rate.\n"
+ report = report "Disclaimer: Like every other prediction of the stock\n"
+ report = report "market, this report is, of course, complete nonsense.\n"
+ report = report "If you are stupid enough to believe these predictions\n"
+ report = report "you should visit a doctor who can treat your ailment."
+ }
+
+The function `SendMail' goes through the list of customers and opens a
+pipe to the `mail' command for each of them. Each one receives an email
+message with a proper subject heading and is addressed with his full
+name.
+
+ function SendMail() {
+ # send report to customers
+ customer["uncle.scrooge@ducktown.gov"] = "Uncle Scrooge"
+ customer["more@utopia.org" ] = "Sir Thomas More"
+ customer["spinoza@denhaag.nl" ] = "Baruch de Spinoza"
+ customer["marx@highgate.uk" ] = "Karl Marx"
+ customer["keynes@the.long.run" ] = "John Maynard Keynes"
+ customer["bierce@devil.hell.org" ] = "Ambrose Bierce"
+ customer["laplace@paris.fr" ] = "Pierre Simon de Laplace"
+ for (c in customer) {
+ MailPipe = "mail -s 'Daily Stock Prediction Newsletter'" c
+ print "Good morning " customer[c] "," | MailPipe
+ print report "\n.\n" | MailPipe
+ close(MailPipe)
+ }
+ }
+
+Be patient when running the script by hand. Retrieving the data for
+all the ticker symbols and sending the emails may take several minutes
+to complete, depending upon network traffic and the speed of the
+available Internet link. The quality of the prediction algorithm is
+likely to be disappointing. Try to find a better one. Should you find
+one with a success rate of more than 50%, please tell us about it! It
+is only for the sake of curiosity, of course. `:-)'
+
+\1f
+File: gawkinet.info, Node: PROTBASE, Prev: STOXPRED, Up: Some Applications and Techniques
+
+3.10 PROTBASE: Searching Through A Protein Database
+===================================================
+
+ Hoare's Law of Large Problems: Inside every large problem is a
+ small problem struggling to get out.
+
+Yahoo's database of stock market data is just one among the many large
+databases on the Internet. Another one is located at NCBI (National
+Center for Biotechnology Information). Established in 1988 as a
+national resource for molecular biology information, NCBI creates
+public databases, conducts research in computational biology, develops
+software tools for analyzing genome data, and disseminates biomedical
+information. In this section, we look at one of NCBI's public services,
+which is called BLAST (Basic Local Alignment Search Tool).
+
+You probably know that the information necessary for reproducing living
+cells is encoded in the genetic material of the cells. The genetic
+material is a very long chain of four base nucleotides. It is the order
+of appearance (the sequence) of nucleotides which contains the
+information about the substance to be produced. Scientists in
+biotechnology often find a specific fragment, determine the nucleotide
+sequence, and need to know where the sequence at hand comes from. This
+is where the large databases enter the game. At NCBI, databases store
+the knowledge about which sequences have ever been found and where they
+have been found. When the scientist sends his sequence to the BLAST
+service, the server looks for regions of genetic material in its
+database which look the most similar to the delivered nucleotide
+sequence. After a search time of some seconds or minutes the server
+sends an answer to the scientist. In order to make access simple, NCBI
+chose to offer their database service through popular Internet
+protocols. There are four basic ways to use the so-called BLAST
+services:
+
+ * The easiest way to use BLAST is through the web. Users may simply
+ point their browsers at the NCBI home page and link to the BLAST
+ pages. NCBI provides a stable URL that may be used to perform
+ BLAST searches without interactive use of a web browser. This is
+ what we will do later in this section. A demonstration client and
+ a `README' file demonstrate how to access this URL.
+
+ * Currently, `blastcl3' is the standard network BLAST client. You
+ can download `blastcl3' from the anonymous FTP location.
+
+ * BLAST 2.0 can be run locally as a full executable and can be used
+ to run BLAST searches against private local databases, or
+ downloaded copies of the NCBI databases. BLAST 2.0 executables may
+ be found on the NCBI anonymous FTP server.
+
+ * The NCBI BLAST Email server is the best option for people without
+ convenient access to the web. A similarity search can be performed
+ by sending a properly formatted mail message containing the
+ nucleotide or protein query sequence to <blast@ncbi.nlm.nih.gov>.
+ The query sequence is compared against the specified database
+ using the BLAST algorithm and the results are returned in an email
+ message. For more information on formulating email BLAST searches,
+ you can send a message consisting of the word "HELP" to the same
+ address, <blast@ncbi.nlm.nih.gov>.
+
+Our starting point is the demonstration client mentioned in the first
+option. The `README' file that comes along with the client explains
+the whole process in a nutshell. In the rest of this section, we first
+show what such requests look like. Then we show how to use `gawk' to
+implement a client in about 10 lines of code. Finally, we show how to
+interpret the result returned from the service.
+
+Sequences are expected to be represented in the standard IUB/IUPAC
+amino acid and nucleic acid codes, with these exceptions: lower-case
+letters are accepted and are mapped into upper-case; a single hyphen or
+dash can be used to represent a gap of indeterminate length; and in
+amino acid sequences, `U' and `*' are acceptable letters (see below).
+Before submitting a request, any numerical digits in the query sequence
+should either be removed or replaced by appropriate letter codes (e.g.,
+`N' for unknown nucleic acid residue or `X' for unknown amino acid
+residue). The nucleic acid codes supported are:
+
+ A --> adenosine M --> A C (amino)
+ C --> cytidine S --> G C (strong)
+ G --> guanine W --> A T (weak)
+ T --> thymidine B --> G T C
+ U --> uridine D --> G A T
+ R --> G A (purine) H --> A C T
+ Y --> T C (pyrimidine) V --> G C A
+ K --> G T (keto) N --> A G C T (any)
+ - gap of indeterminate length
+
+Now you know the alphabet of nucleotide sequences. The last two lines
+of the following example query show you such a sequence, which is
+obviously made up only of elements of the alphabet just described.
+Store this example query into a file named `protbase.request'. You are
+now ready to send it to the server with the demonstration client.
+
+ PROGRAM blastn
+ DATALIB month
+ EXPECT 0.75
+ BEGIN
+ >GAWK310 the gawking gene GNU AWK
+ tgcttggctgaggagccataggacgagagcttcctggtgaagtgtgtttcttgaaatcat
+ caccaccatggacagcaaa
+
+The actual search request begins with the mandatory parameter `PROGRAM'
+in the first column followed by the value `blastn' (the name of the
+program) for searching nucleic acids. The next line contains the
+mandatory search parameter `DATALIB' with the value `month' for the
+newest nucleic acid sequences. The third line contains an optional
+`EXPECT' parameter and the value desired for it. The fourth line
+contains the mandatory `BEGIN' directive, followed by the query
+sequence in FASTA/Pearson format. Each line of information must be
+less than 80 characters in length.
+
+The "month" database contains all new or revised sequences released in
+the last 30 days and is useful for searching against new sequences.
+There are five different blast programs, `blastn' being the one that
+compares a nucleotide query sequence against a nucleotide sequence
+database.
+
+The last server directive that must appear in every request is the
+`BEGIN' directive. The query sequence should immediately follow the
+`BEGIN' directive and must appear in FASTA/Pearson format. A sequence
+in FASTA/Pearson format begins with a single-line description. The
+description line, which is required, is distinguished from the lines of
+sequence data that follow it by having a greater-than (`>') symbol in
+the first column. For the purposes of the BLAST server, the text of
+the description is arbitrary.
+
+If you prefer to use a client written in `gawk', just store the
+following 10 lines of code into a file named `protbase.awk' and use
+this client instead. Invoke it with `gawk -f protbase.awk
+protbase.request'. Then wait a minute and watch the result coming in.
+In order to replicate the demonstration client's behaviour as closely
+as possible, this client does not use a proxy server. We could also
+have extended the client program in *Note Retrieving Web Pages: GETURL,
+to implement the client request from `protbase.awk' as a special case.
+
+ { request = request "\n" $0 }
+
+ END {
+ BLASTService = "/inet/tcp/0/www.ncbi.nlm.nih.gov/80"
+ printf "POST /cgi-bin/BLAST/nph-blast_report HTTP/1.0\n" |& BLASTService
+ printf "Content-Length: " length(request) "\n\n" |& BLASTService
+ printf request |& BLASTService
+ while ((BLASTService |& getline) > 0)
+ print $0
+ close(BLASTService)
+ }
+
+The demonstration client from NCBI is 214 lines long (written in C) and
+it is not immediately obvious what it does. Our client is so short that
+it _is_ obvious what it does. First it loops over all lines of the
+query and stores the whole query into a variable. Then the script
+establishes an Internet connection to the NCBI server and transmits the
+query by framing it with a proper HTTP request. Finally it receives and
+prints the complete result coming from the server.
+
+Now, let us look at the result. It begins with an HTTP header, which you
+can ignore. Then there are some comments about the query having been
+filtered to avoid spuriously high scores. After this, there is a
+reference to the paper that describes the software being used for
+searching the data base. After a repitition of the original query's
+description we find the list of significant alignments:
+
+ Sequences producing significant alignments: (bits) Value
+
+ gb|AC021182.14|AC021182 Homo sapiens chromosome 7 clone RP11-733... 38 0.20
+ gb|AC021056.12|AC021056 Homo sapiens chromosome 3 clone RP11-115... 38 0.20
+ emb|AL160278.10|AL160278 Homo sapiens chromosome 9 clone RP11-57... 38 0.20
+ emb|AL391139.11|AL391139 Homo sapiens chromosome X clone RP11-35... 38 0.20
+ emb|AL365192.6|AL365192 Homo sapiens chromosome 6 clone RP3-421H... 38 0.20
+ emb|AL138812.9|AL138812 Homo sapiens chromosome 11 clone RP1-276... 38 0.20
+ gb|AC073881.3|AC073881 Homo sapiens chromosome 15 clone CTD-2169... 38 0.20
+
+This means that the query sequence was found in seven human chromosomes.
+But the value 0.20 (20%) means that the probability of an accidental
+match is rather high (20%) in all cases and should be taken into
+account. You may wonder what the first column means. It is a key to
+the specific database in which this occurence was found. The unique
+sequence identifiers reported in the search results can be used as
+sequence retrieval keys via the NCBI server. The syntax of sequence
+header lines used by the NCBI BLAST server depends on the database from
+which each sequence was obtained. The table below lists the
+identifiers for the databases from which the sequences were derived.
+
+ Database Name Identifier Syntax
+ ============================ ========================
+ GenBank gb|accession|locus
+ EMBL Data Library emb|accession|locus
+ DDBJ, DNA Database of Japan dbj|accession|locus
+ NBRF PIR pir||entry
+ Protein Research Foundation prf||name
+ SWISS-PROT sp|accession|entry name
+ Brookhaven Protein Data Bank pdb|entry|chain
+ Kabat's Sequences of Immuno... gnl|kabat|identifier
+ Patents pat|country|number
+ GenInfo Backbone Id bbs|number
+
+For example, an identifier might be `gb|AC021182.14|AC021182', where the
+`gb' tag indicates that the identifier refers to a GenBank sequence,
+`AC021182.14' is its GenBank ACCESSION, and `AC021182' is the GenBank
+LOCUS. The identifier contains no spaces, so that a space indicates
+the end of the identifier.
+
+Let us continue in the result listing. Each of the seven alignments
+mentioned above is subsequently described in detail. We will have a
+closer look at the first of them.
+
+ >gb|AC021182.14|AC021182 Homo sapiens chromosome 7 clone RP11-733N23, WORKING DRAFT SEQUENCE, 4
+ unordered pieces
+ Length = 176383
+
+ Score = 38.2 bits (19), Expect = 0.20
+ Identities = 19/19 (100%)
+ Strand = Plus / Plus
+
+ Query: 35 tggtgaagtgtgtttcttg 53
+ |||||||||||||||||||
+ Sbjct: 69786 tggtgaagtgtgtttcttg 69804
+
+This alignment was located on the human chromosome 7. The fragment on
+which part of the query was found had a total length of 176383. Only 19
+of the nucleotides matched and the matching sequence ran from character
+35 to 53 in the query sequence and from 69786 to 69804 in the fragment
+on chromosome 7. If you are still reading at this point, you are
+probably interested in finding out more about Computational Biology and
+you might appreciate the following hints.
+
+ 1. There is a book called `Introduction to Computational Biology' by
+ Michael S. Waterman, which is worth reading if you are seriously
+ interested. You can find a good book review on the Internet.
+
+ 2. While Waterman's book can explain to you the algorithms employed
+ internally in the database search engines, most practicioners
+ prefer to approach the subject differently. The applied side of
+ Computational Biology is called Bioinformatics, and emphasizes the
+ tools available for day-to-day work as well as how to actually
+ _use_ them. One of the very few affordable books on Bioinformatics
+ is `Developing Bioinformatics Computer Skills'.
+
+ 3. The sequences _gawk_ and _gnuawk_ are in widespread use in the
+ genetic material of virtually every earthly living being. Let us
+ take this as a clear indication that the divine creator has
+ intended `gawk' to prevail over other scripting languages such as
+ `perl', `tcl', or `python' which are not even proper sequences.
+ (:-)
+
+\1f
+File: gawkinet.info, Node: Links, Next: GNU Free Documentation License, Prev: Some Applications and Techniques, Up: Top
+
+4 Related Links
+***************
+
+This section lists the URLs for various items discussed in this major
+node. They are presented in the order in which they appear.
+
+`Internet Programming with Python'
+ `http://www.fsbassociates.com/books/python.htm'
+
+`Advanced Perl Programming'
+ `http://www.oreilly.com/catalog/advperl'
+
+`Web Client Programming with Perl'
+ `http://www.oreilly.com/catalog/webclient'
+
+Richard Stevens's home page and book
+ `http://www.kohala.com/~rstevens'
+
+The SPAK home page
+ `http://www.userfriendly.net/linux/RPM/contrib/libc6/i386/spak-0.6b-1.i386.html'
+
+Volume III of `Internetworking with TCP/IP', by Comer and Stevens
+ `http://www.cs.purdue.edu/homes/dec/tcpip3s.cont.html'
+
+XBM Graphics File Format
+ `http://www.wotsit.org/download.asp?f=xbm'
+
+GNUPlot
+ `http://www.cs.dartmouth.edu/gnuplot_info.html'
+
+Mark Humphrys' Eliza page
+ `http://www.compapp.dcu.ie/~humphrys/eliza.html'
+
+Yahoo! Eliza Information
+ `http://dir.yahoo.com/Recreation/Games/Computer_Games/Internet_Games/Web_Games/Artificial_Intelligence'
+
+Java versions of Eliza
+ `http://www.tjhsst.edu/Psych/ch1/eliza.html'
+
+Java versions of Eliza with source code
+ `http://home.adelphia.net/~lifeisgood/eliza/eliza.htm'
+
+Eliza Programs with Explanations
+ `http://chayden.net/chayden/eliza/Eliza.shtml'
+
+Loebner Contest
+ `http://acm.org/~loebner/loebner-prize.htmlx'
+
+Tck/Tk Information
+ `http://www.scriptics.com/'
+
+Intel 80x86 Processors
+ `http://developer.intel.com/design/platform/embedpc/what_is.htm'
+
+AMD Elan Processors
+ `http://www.amd.com/products/epd/processors/4.32bitcont/32bitcont/index.html'
+
+XINU
+ `http://willow.canberra.edu.au/~chrisc/xinu.html'
+
+GNU/Linux
+ `http://uclinux.lineo.com/'
+
+Embedded PCs
+ `http://dir.yahoo.com/Business_and_Economy/Business_to_Business/Computers/Hardware/Embedded_Control/'
+
+MiniSQL
+ `http://www.hughes.com.au/library/'
+
+Market Share Surveys
+ `http://www.netcraft.com/survey'
+
+`Numerical Recipes in C: The Art of Scientific Computing'
+ `http://www.nr.com'
+
+VRML
+ `http://www.vrml.org'
+
+The VRML FAQ
+ `http://www.vrml.org/technicalinfo/specifications/specifications.htm#FAQ'
+
+The UMBC Agent Web
+ `http://www.cs.umbc.edu/agents'
+
+Apache Web Server
+ `http://www.apache.org'
+
+National Center for Biotechnology Information (NCBI)
+ `http://www.ncbi.nlm.nih.gov'
+
+Basic Local Alignment Search Tool (BLAST)
+ `http://www.ncbi.nlm.nih.gov/BLAST/blast_overview.html'
+
+NCBI Home Page
+ `http://www.ncbi.nlm.nih.gov'
+
+BLAST Pages
+ `http://www.ncbi.nlm.nih.gov/BLAST'
+
+BLAST Demonstration Client
+ `ftp://ncbi.nlm.nih.gov/blast/blasturl/'
+
+BLAST anonymous FTP location
+ `ftp://ncbi.nlm.nih.gov/blast/network/netblast/'
+
+BLAST 2.0 Executables
+ `ftp://ncbi.nlm.nih.gov/blast/executables/'
+
+IUB/IUPAC Amino Acid and Nucleic Acid Codes
+ `http://www.uthscsa.edu/geninfo/blastmail.html#item6'
+
+FASTA/Pearson Format
+ `http://www.ncbi.nlm.nih.gov/BLAST/fasta.html'
+
+Fasta/Pearson Sequence in Java
+ `http://www.kazusa.or.jp/java/codon_table_java/'
+
+Book Review of `Introduction to Computational Biology'
+ `http://www.acm.org/crossroads/xrds5-1/introcb.html'
+
+`Developing Bioinformatics Computer Skills'
+ `http://www.oreilly.com/catalog/bioskills/'
+
+
+\1f
+File: gawkinet.info, Node: GNU Free Documentation License, Next: Index, Prev: Links, Up: Top
+
+GNU Free Documentation License
+******************************
+
+ Version 1.2, November 2002
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warrany Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+\1f
+File: gawkinet.info, Node: Index, Prev: GNU Free Documentation License, Up: Top
+
+Index
+*****
+
+* Menu:
+
+* /inet/ files (gawk): Gawk Special Files. (line 490)
+* /inet/raw special files (gawk): File /inet/raw. (line 712)
+* /inet/tcp special files (gawk): File /inet/tcp. (line 647)
+* /inet/udp special files (gawk): File /inet/udp. (line 679)
+* advanced features, network connections: Troubleshooting. (line 834)
+* agent <1>: MOBAGWHO. (line 2766)
+* agent: Challenges. (line 1887)
+* AI: Challenges. (line 1887)
+* apache <1>: MOBAGWHO. (line 2802)
+* apache: WEBGRAB. (line 2372)
+* Bioinformatics: PROTBASE. (line 3590)
+* BLAST, Basic Local Alignment Search Tool: PROTBASE. (line 3369)
+* blocking: Making Connections. (line 383)
+* Boutell, Thomas: STATIST. (line 2396)
+* CGI (Common Gateway Interface): MOBAGWHO. (line 2802)
+* CGI (Common Gateway Interface), dynamic web pages and: Web page.
+ (line 1130)
+* CGI (Common Gateway Interface), library: CGI Lib. (line 1418)
+* clients: Making Connections. (line 369)
+* Clinton, Bill: Challenges. (line 1870)
+* Common Gateway Interface, See CGI: Web page. (line 1130)
+* Computational Biology: PROTBASE. (line 3590)
+* contest: Challenges. (line 1817)
+* cron utility: STOXPRED. (line 3068)
+* CSV format: STOXPRED. (line 3173)
+* dark corner, RAW protocol: File /inet/raw. (line 719)
+* Dow Jones Industrial Index: STOXPRED. (line 3089)
+* ELIZA program: Simple Server. (line 1606)
+* email: Email. (line 1045)
+* FASTA/Pearson format: PROTBASE. (line 3465)
+* FDL (Free Documentation License): GNU Free Documentation License.
+ (line 3742)
+* filenames, for network access: Gawk Special Files. (line 485)
+* files, /inet/ (gawk): Gawk Special Files. (line 490)
+* files, /inet/raw (gawk): File /inet/raw. (line 712)
+* files, /inet/tcp (gawk): File /inet/tcp. (line 647)
+* files, /inet/udp (gawk): File /inet/udp. (line 679)
+* finger utility: Setting Up. (line 981)
+* Free Documentation License (FDL): GNU Free Documentation License.
+ (line 3742)
+* FTP (File Transfer Protocol): Basic Protocols. (line 316)
+* gawk, networking: Using Networking. (line 414)
+* gawk, networking, connections <1>: TCP Connecting. (line 781)
+* gawk, networking, connections: Special File Fields.
+ (line 549)
+* gawk, networking, filenames: Gawk Special Files. (line 485)
+* gawk, networking, See Also email: Email. (line 1040)
+* gawk, networking, service, establishing: Setting Up. (line 965)
+* gawk, networking, troubleshooting: Caveats. (line 1791)
+* gawk, web and, See web service: Interacting Service.
+ (line 1214)
+* getline command: TCP Connecting. (line 786)
+* GETURL program: GETURL. (line 2050)
+* GIF image format <1>: STATIST. (line 2396)
+* GIF image format: Web page. (line 1130)
+* GNU Free Documentation License: GNU Free Documentation License.
+ (line 3742)
+* GNU/Linux <1>: REMCONF. (line 2107)
+* GNU/Linux <2>: Interacting. (line 931)
+* GNU/Linux: Troubleshooting. (line 882)
+* GNUPlot utility <1>: STATIST. (line 2396)
+* GNUPlot utility: Interacting Service.
+ (line 1396)
+* Hoare, C.A.R. <1>: PROTBASE. (line 3369)
+* Hoare, C.A.R.: MOBAGWHO. (line 2766)
+* hostname field: Special File Fields.
+ (line 529)
+* HTML (Hypertext Markup Language): Web page. (line 1114)
+* HTTP (Hypertext Transfer Protocol) <1>: Web page. (line 1090)
+* HTTP (Hypertext Transfer Protocol): Basic Protocols. (line 316)
+* HTTP (Hypertext Transfer Protocol), record separators and: Web page.
+ (line 1114)
+* HTTP server, core logic: Interacting Service.
+ (line 1214)
+* Humphrys, Mark: Simple Server. (line 1774)
+* Hypertext Markup Language (HTML): Web page. (line 1114)
+* Hypertext Transfer Protocol, See HTTP: Web page. (line 1090)
+* image format: STATIST. (line 2396)
+* images, in web pages: Interacting Service.
+ (line 1396)
+* images, retrieving over networks: Web page. (line 1130)
+* input/output, two-way, See Also gawk, networking: Gawk Special Files.
+ (line 475)
+* Internet, See networks: Interacting. (line 952)
+* JavaScript: STATIST. (line 2446)
+* Linux <1>: REMCONF. (line 2107)
+* Linux <2>: Interacting. (line 931)
+* Linux: Troubleshooting. (line 882)
+* Lisp: MOBAGWHO. (line 2858)
+* localport field: Gawk Special Files. (line 490)
+* Loebner, Hugh: Challenges. (line 1817)
+* Loui, Ronald: Challenges. (line 1887)
+* MAZE: MAZE. (line 2634)
+* Microsoft Windows: WEBGRAB. (line 2343)
+* Microsoft Windows, networking: Troubleshooting. (line 882)
+* Microsoft Windows, networking, ports: Setting Up. (line 996)
+* MiniSQL: REMCONF. (line 2212)
+* MOBAGWHO program: MOBAGWHO. (line 2766)
+* NCBI, National Center for Biotechnology Information: PROTBASE.
+ (line 3369)
+* networks, gawk and: Using Networking. (line 414)
+* networks, gawk and, connections <1>: TCP Connecting. (line 781)
+* networks, gawk and, connections: Special File Fields.
+ (line 549)
+* networks, gawk and, filenames: Gawk Special Files. (line 485)
+* networks, gawk and, See Also email: Email. (line 1040)
+* networks, gawk and, service, establishing: Setting Up. (line 965)
+* networks, gawk and, troubleshooting: Caveats. (line 1791)
+* networks, ports, reserved: Setting Up. (line 996)
+* networks, ports, specifying: Special File Fields.
+ (line 518)
+* networks, See Also web pages: PANIC. (line 2008)
+* Numerical Recipes: STATIST. (line 2414)
+* ORS variable, HTTP and: Web page. (line 1114)
+* ORS variable, POP and: Email. (line 1070)
+* PANIC program: PANIC. (line 2008)
+* Perl: Using Networking. (line 422)
+* Perl, gawk networking and: Using Networking. (line 432)
+* Perlis, Alan: MAZE. (line 2634)
+* pipes, networking and: TCP Connecting. (line 805)
+* PNG image format <1>: STATIST. (line 2396)
+* PNG image format: Web page. (line 1130)
+* POP (Post Office Protocol): Email. (line 1040)
+* Post Office Protocol (POP): Email. (line 1040)
+* PostScript: STATIST. (line 2528)
+* PROLOG: Challenges. (line 1887)
+* PROTBASE: PROTBASE. (line 3369)
+* protocol field: Special File Fields.
+ (line 511)
+* PS image format: STATIST. (line 2396)
+* Python: Using Networking. (line 422)
+* Python, gawk networking and: Using Networking. (line 432)
+* RAW protocol: File /inet/raw. (line 712)
+* record separators, HTTP and: Web page. (line 1114)
+* record separators, POP and: Email. (line 1070)
+* REMCONF program: REMCONF. (line 2107)
+* remoteport field: Gawk Special Files. (line 490)
+* robot <1>: WEBGRAB. (line 2306)
+* robot: Challenges. (line 1896)
+* RS variable, HTTP and: Web page. (line 1114)
+* RS variable, POP and: Email. (line 1070)
+* servers <1>: Setting Up. (line 981)
+* servers: Making Connections. (line 362)
+* servers, as hosts: Special File Fields.
+ (line 529)
+* servers, HTTP: Interacting Service.
+ (line 1214)
+* servers, web: Simple Server. (line 1601)
+* Simple Mail Transfer Protocol (SMTP): Email. (line 1040)
+* SMTP (Simple Mail Transfer Protocol) <1>: Email. (line 1040)
+* SMTP (Simple Mail Transfer Protocol): Basic Protocols. (line 316)
+* SPAK utility: File /inet/raw. (line 727)
+* STATIST program: STATIST. (line 2396)
+* STOXPRED program: STOXPRED. (line 3051)
+* synchronous communications: Making Connections. (line 383)
+* Tcl/Tk: Using Networking. (line 422)
+* Tcl/Tk, gawk and <1>: Some Applications and Techniques.
+ (line 1977)
+* Tcl/Tk, gawk and: Using Networking. (line 432)
+* TCP (Transmission Control Protocol) <1>: File /inet/tcp. (line 647)
+* TCP (Transmission Control Protocol): Using Networking. (line 437)
+* TCP (Transmission Control Protocol), connection, establishing: TCP Connecting.
+ (line 781)
+* TCP (Transmission Control Protocol), UDP and: Interacting. (line 952)
+* TCP/IP, protocols, selecting: Special File Fields.
+ (line 511)
+* TCP/IP, sockets and: Gawk Special Files. (line 475)
+* Transmission Control Protocol, See TCP: Using Networking. (line 437)
+* troubleshooting, gawk, networks: Caveats. (line 1791)
+* troubleshooting, networks, connections: Troubleshooting. (line 834)
+* troubleshooting, networks, timeouts: Caveats. (line 1803)
+* UDP (User Datagram Protocol): File /inet/udp. (line 679)
+* UDP (User Datagram Protocol), TCP and: Interacting. (line 952)
+* Unix, network ports and: Setting Up. (line 996)
+* URLCHK program: URLCHK. (line 2225)
+* User Datagram Protocol, See UDP: File /inet/udp. (line 679)
+* vertical bar (|), |& operator (I/O): TCP Connecting. (line 800)
+* VRML: MAZE. (line 2634)
+* web browsers, See web service: Interacting Service.
+ (line 1214)
+* web pages: Web page. (line 1090)
+* web pages, images in: Interacting Service.
+ (line 1396)
+* web pages, retrieving: GETURL. (line 2050)
+* web servers: Simple Server. (line 1601)
+* web service <1>: PANIC. (line 2008)
+* web service: Primitive Service. (line 1156)
+* WEBGRAB program: WEBGRAB. (line 2306)
+* Weizenbaum, Joseph: Simple Server. (line 1606)
+* XBM image format: Interacting Service.
+ (line 1396)
+* Yahoo! <1>: STOXPRED. (line 3051)
+* Yahoo!: REMCONF. (line 2107)
+* | (vertical bar), |& operator (I/O): TCP Connecting. (line 800)
+
+
+\1f
+Tag Table:
+Node: Top\7f2000
+Node: Preface\7f5688
+Node: Introduction\7f7063
+Node: Stream Communications\7f8088
+Node: Datagram Communications\7f9261
+Node: The TCP/IP Protocols\7f10892
+Ref: The TCP/IP Protocols-Footnote-1\7f11576
+Node: Basic Protocols\7f11733
+Node: Ports\7f13055
+Node: Making Connections\7f14460
+Ref: Making Connections-Footnote-1\7f17027
+Ref: Making Connections-Footnote-2\7f17074
+Node: Using Networking\7f17255
+Node: Gawk Special Files\7f19609
+Node: Special File Fields\7f21609
+Ref: table-inet-components\7f25353
+Node: Comparing Protocols\7f28235
+Node: File /inet/tcp\7f28824
+Node: File /inet/udp\7f29844
+Node: File /inet/raw\7f30959
+Ref: File /inet/raw-Footnote-1\7f33974
+Node: TCP Connecting\7f34051
+Node: Troubleshooting\7f36380
+Ref: Troubleshooting-Footnote-1\7f39424
+Node: Interacting\7f39964
+Node: Setting Up\7f42684
+Node: Email\7f46166
+Node: Web page\7f48485
+Ref: Web page-Footnote-1\7f51272
+Node: Primitive Service\7f51466
+Node: Interacting Service\7f54194
+Ref: Interacting Service-Footnote-1\7f63291
+Node: CGI Lib\7f63320
+Node: Simple Server\7f70269
+Ref: Simple Server-Footnote-1\7f77975
+Node: Caveats\7f78073
+Node: Challenges\7f79213
+Node: Some Applications and Techniques\7f87874
+Node: PANIC\7f90322
+Node: GETURL\7f92034
+Node: REMCONF\7f94650
+Node: URLCHK\7f100114
+Node: WEBGRAB\7f103937
+Node: STATIST\7f108367
+Ref: STATIST-Footnote-1\7f120029
+Node: MAZE\7f120471
+Node: MOBAGWHO\7f126646
+Ref: MOBAGWHO-Footnote-1\7f140547
+Node: STOXPRED\7f140599
+Node: PROTBASE\7f154809
+Node: Links\7f167844
+Node: GNU Free Documentation License\7f171278
+Node: Index\7f193671
+\1f
+End Tag Table
--- /dev/null
+\input texinfo @c -*-texinfo-*-
+@c %**start of header (This is for running Texinfo on a region.)
+@setfilename gawkinet.info
+@settitle TCP/IP Internetworking With @command{gawk}
+@c %**end of header (This is for running Texinfo on a region.)
+@c FIXME: web vs. Web
+
+@dircategory Network applications
+@direntry
+* Gawkinet: (gawkinet). TCP/IP Internetworking With `gawk'.
+@end direntry
+
+@iftex
+@set DOCUMENT book
+@set CHAPTER chapter
+@set SECTION section
+@set DARKCORNER @inmargin{@image{lflashlight,1cm}, @image{rflashlight,1cm}}
+@end iftex
+@ifinfo
+@set DOCUMENT Info file
+@set CHAPTER major node
+@set SECTION node
+@set DARKCORNER (d.c.)
+@end ifinfo
+@ifhtml
+@set DOCUMENT web page
+@set CHAPTER chapter
+@set SECTION section
+@set DARKCORNER (d.c.)
+@end ifhtml
+
+@set FSF
+
+@set FN file name
+@set FFN File Name
+
+@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
+
+@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
+
+@smallbook
+
+@c Special files are described in chapter 6 Printing Output under
+@c 6.7 Special File Names in gawk. I think the networking does not
+@c fit into that chapter, thus this separate document. At over 50
+@c pages, I think this is the right decision. ADR.
+
+@set TITLE TCP/IP Internetworking With @command{gawk}
+@set EDITION 1.1
+@set UPDATE-MONTH January, 2004
+@c gawk versions:
+@set VERSION 3.1
+@set PATCHLEVEL 4
+
+@copying
+This is Edition @value{EDITION} of @cite{@value{TITLE}},
+for the @value{VERSION}.@value{PATCHLEVEL} (or later) version of the GNU
+implementation of AWK.
+@sp 2
+Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+@sp 2
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+@enumerate a
+@item
+``A GNU Manual''
+
+@item
+``You have freedom to copy and modify this GNU Manual, like GNU
+software. Copies published by the Free Software Foundation raise
+funds for GNU development.''
+@end enumerate
+@end copying
+
+@ifinfo
+This file documents the networking features in GNU @command{awk}.
+
+@insertcopying
+@end ifinfo
+
+@setchapternewpage odd
+
+@titlepage
+@title @value{TITLE}
+@subtitle Edition @value{EDITION}
+@subtitle @value{UPDATE-MONTH}
+@author J@"urgen Kahrs
+@author with Arnold D. Robbins
+
+@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
+@sp 2
+Published by:
+@sp 1
+
+Free Software Foundation @*
+51 Franklin Street, Fifth Floor @*
+Boston, MA 02110-1301 USA @*
+Phone: +1-617-542-5942 @*
+Fax: +1-617-542-2652 @*
+Email: @email{gnu@@gnu.org} @*
+URL: @uref{http://www.gnu.org/} @*
+
+ISBN 1-882114-93-0 @*
+
+@insertcopying
+
+@c @sp 2
+@c Cover art by ?????.
+@end titlepage
+
+@iftex
+@headings off
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+
+@ifnottex
+@node Top, Preface, (dir), (dir)
+@top General Introduction
+@comment node-name, next, previous, up
+
+This file documents the networking features in GNU Awk (@command{gawk})
+version 3.1 and later.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Preface:: About this document.
+* Introduction:: About networkiing.
+* Using Networking:: Some examples.
+* Some Applications and Techniques:: More extended examples.
+* Links:: Where to find the stuff mentioned in this
+ document.
+* GNU Free Documentation License:: The license for this document.
+* Index:: The index.
+
+@detailmenu
+* Stream Communications:: Sending data streams.
+* Datagram Communications:: Sending self-contained messages.
+* The TCP/IP Protocols:: How these models work in the Internet.
+* Basic Protocols:: The basic protocols.
+* Ports:: The idea behind ports.
+* Making Connections:: Making TCP/IP connections.
+* Gawk Special Files:: How to do @command{gawk} networking.
+* Special File Fields:: The fields in the special file name.
+* Comparing Protocols:: Differences between the protocols.
+* File /inet/tcp:: The TCP special file.
+* File /inet/udp:: The UDP special file.
+* File /inet/raw:: The RAW special file.
+* TCP Connecting:: Making a TCP connection.
+* Troubleshooting:: Troubleshooting TCP/IP connections.
+* Interacting:: Interacting with a service.
+* Setting Up:: Setting up a service.
+* Email:: Reading email.
+* Web page:: Reading a Web page.
+* Primitive Service:: A primitive Web service.
+* Interacting Service:: A Web service with interaction.
+* CGI Lib:: A simple CGI library.
+* Simple Server:: A simple Web server.
+* Caveats:: Network programming caveats.
+* Challenges:: Where to go from here.
+* PANIC:: An Emergency Web Server.
+* GETURL:: Retrieving Web Pages.
+* REMCONF:: Remote Configuration Of Embedded Systems.
+* URLCHK:: Look For Changed Web Pages.
+* WEBGRAB:: Extract Links From A Page.
+* STATIST:: Graphing A Statistical Distribution.
+* MAZE:: Walking Through A Maze In Virtual Reality.
+* MOBAGWHO:: A Simple Mobile Agent.
+* STOXPRED:: Stock Market Prediction As A Service.
+* PROTBASE:: Searching Through A Protein Database.
+@end detailmenu
+@end menu
+
+@contents
+
+@node Preface, Introduction, Top, Top
+@unnumbered Preface
+
+In May of 1997, J@"urgen Kahrs felt the need for network access
+from @command{awk}, and, with a little help from me, set about adding
+features to do this for @command{gawk}. At that time, he
+wrote the bulk of this @value{DOCUMENT}.
+
+The code and documentation were added to the @command{gawk} 3.1 development
+tree, and languished somewhat until I could finally get
+down to some serious work on that version of @command{gawk}.
+This finally happened in the middle of 2000.
+
+Meantime, J@"urgen wrote an article about the Internet special
+files and @samp{|&} operator for @cite{Linux Journal}, and made a
+networking patch for the production versions of @command{gawk}
+available from his home page.
+In August of 2000 (for @command{gawk} 3.0.6), this patch
+also made it to the main GNU @command{ftp} distribution site.
+
+For release with @command{gawk}, I edited J@"urgen's prose
+for English grammar and style, as he is not a native English
+speaker. I also
+rearranged the material somewhat for what I felt was a better order of
+presentation, and (re)wrote some of the introductory material.
+
+The majority of this document and the code are his work, and the
+high quality and interesting ideas speak for themselves. It is my
+hope that these features will be of significant value to the @command{awk}
+community.
+
+@sp 1
+@noindent
+Arnold Robbins @*
+Nof Ayalon, ISRAEL @*
+March, 2001
+
+@node Introduction, Using Networking, Preface, Top
+@chapter Networking Concepts
+
+This @value{CHAPTER} provides a (necessarily) brief intoduction to
+computer networking concepts. For many applications of @command{gawk}
+to TCP/IP networking, we hope that this is enough. For more
+advanced tasks, you will need deeper background, and it may be necessary
+to switch to lower-level programming in C or C++.
+
+There are two real-life models for the way computers send messages
+to each other over a network. While the analogies are not perfect,
+they are close enough to convey the major concepts.
+These two models are the phone system (reliable byte-stream communications),
+and the postal system (best-effort datagrams).
+
+@menu
+* Stream Communications:: Sending data streams.
+* Datagram Communications:: Sending self-contained messages.
+* The TCP/IP Protocols:: How these models work in the Internet.
+* Making Connections:: Making TCP/IP connections.
+@end menu
+
+@node Stream Communications, Datagram Communications, Introduction, Introduction
+@section Reliable Byte-streams (Phone Calls)
+
+When you make a phone call, the following steps occur:
+
+@enumerate
+@item
+You dial a number.
+
+@item
+The phone system connects to the called party, telling
+them there is an incoming call. (Their phone rings.)
+
+@item
+The other party answers the call, or, in the case of a
+computer network, refuses to answer the call.
+
+@item
+Assuming the other party answers, the connection between
+you is now a @dfn{duplex} (two-way), @dfn{reliable} (no data lost),
+sequenced (data comes out in the order sent) data stream.
+
+@item
+You and your friend may now talk freely, with the phone system
+moving the data (your voices) from one end to the other.
+From your point of view, you have a direct end-to-end
+connection with the person on the other end.
+@end enumerate
+
+The same steps occur in a duplex reliable computer networking connection.
+There is considerably more overhead in setting up the communications,
+but once it's done, data moves in both directions, reliably, in sequence.
+
+@node Datagram Communications, The TCP/IP Protocols, Stream Communications, Introduction
+@section Best-effort Datagrams (Mailed Letters)
+
+Suppose you mail three different documents to your office on the
+other side of the country on two different days. Doing so
+entails the following.
+
+@enumerate
+@item
+Each document travels in its own envelope.
+
+@item
+Each envelope contains both the sender and the
+recipient address.
+
+@item
+Each envelope may travel a different route to its destination.
+
+@item
+The envelopes may arrive in a different order from the one
+in which they were sent.
+
+@item
+One or more may get lost in the mail.
+(Although, fortunately, this does not occur very often.)
+
+@item
+In a computer network, one or more @dfn{packets}
+may also arrive multiple times. (This doesn't happen
+with the postal system!)
+
+@end enumerate
+
+The important characteristics of datagram communications, like
+those of the postal system are thus:
+
+@itemize @bullet
+@item
+Delivery is ``best effort;'' the data may never get there.
+
+@item
+Each message is self-contained, including the source and
+destination addresses.
+
+@item
+Delivery is @emph{not} sequenced; packets may arrive out
+of order, and/or multiple times.
+
+@item
+Unlike the phone system, overhead is considerably lower.
+It is not necessary to set up the call first.
+@end itemize
+
+The price the user pays for the lower overhead of datagram communications
+is exactly the lower reliability; it is often necessary for user-level
+protocols that use datagram communications to add their own reliability
+features on top of the basic communications.
+
+@node The TCP/IP Protocols, Making Connections, Datagram Communications, Introduction
+@section The Internet Protocols
+
+The Internet Protocol Suite (usually referred to as just TCP/IP)@footnote{
+It should be noted that although the Internet seems to have conquered the
+world, there are other networking protocol suites in existence and in use.}
+consists of a number of different protocols at different levels or ``layers.''
+For our purposes, three protocols provide the fundamental communications
+mechanisms. All other defined protocols are referred to as user-level
+protocols (e.g., HTTP, used later in this @value{DOCUMENT}).
+
+@menu
+* Basic Protocols:: The basic protocols.
+* Ports:: The idea behind ports.
+@end menu
+
+@node Basic Protocols, Ports, The TCP/IP Protocols, The TCP/IP Protocols
+@subsection The Basic Internet Protocols
+
+@table @asis
+@item IP
+The Internet Protocol. This protocol is almost never used directly by
+applications. It provides the basic packet delivery and routing infrastructure
+of the Internet. Much like the phone company's switching centers or the Post
+Office's trucks, it is not of much day-to-day interest to the regular user
+(or programmer).
+It happens to be a best effort datagram protocol.
+
+@item UDP
+The User Datagram Protocol. This is a best effort datagram protocol.
+It provides a small amount of extra reliability over IP, and adds
+the notion of @dfn{ports}, described in @ref{Ports, ,TCP and UDP Ports}.
+
+@item TCP
+The Transmission Control Protocol. This is a duplex, reliable, sequenced
+byte-stream protocol, again layered on top of IP, and also providing the
+notion of ports. This is the protocol that you will most likely use
+when using @command{gawk} for network programming.
+@end table
+
+All other user-level protocols use either TCP or UDP to do their basic
+communications. Examples are SMTP (Simple Mail Transfer Protocol),
+FTP (File Transfer Protocol), and HTTP (HyperText Transfer Protocol).
+@cindex SMTP (Simple Mail Transfer Protocol)
+@cindex FTP (File Transfer Protocol)
+@cindex HTTP (Hypertext Transfer Protocol)
+
+@node Ports, , Basic Protocols, The TCP/IP Protocols
+@subsection TCP and UDP Ports
+
+In the postal system, the address on an envelope indicates a physical
+location, such as a residence or office building. But there may be
+more than one person at a location; thus you have to further quantify
+the recipient by putting a person or company name on the envelope.
+
+In the phone system, one phone number may represent an entire company,
+in which case you need a person's extension number in order to
+reach that individual directly. Or, when you call a home, you have to
+say, ``May I please speak to ...'' before talking to the person directly.
+
+IP networking provides the concept of addressing. An IP address represents
+a particular computer, but no more. In order to reach the mail service
+on a system, or the FTP or WWW service on a system, you must have some
+way to further specify which service you want. In the Internet Protocol suite,
+this is done with @dfn{port numbers}, which represent the services, much
+like an extension number used with a phone number.
+
+Port numbers are 16-bit integers. Unix and Unix-like systems reserve ports
+below 1024 for ``well known'' services, such as SMTP, FTP, and HTTP.
+Numbers 1024 and above may be used by any application, although there is no
+promise made that a particular port number is always available.
+
+@node Making Connections, , The TCP/IP Protocols, Introduction
+@section Making TCP/IP Connections (And Some Terminology)
+
+Two terms come up repeatedly when discussing networking:
+@dfn{client} and @dfn{server}. For now, we'll discuss these terms
+at the @dfn{connection level}, when first establishing connections
+between two processes on different systems over a network.
+(Once the connection is established, the higher level, or
+@dfn{application level} protocols,
+such as HTTP or FTP, determine who is the client and who is the
+server. Often, it turns out that the client and server are the
+same in both roles.)
+
+@cindex servers
+The @dfn{server} is the system providing the service, such as the
+web server or email server. It is the @dfn{host} (system) which
+is @emph{connected to} in a transaction.
+For this to work though, the server must be expecting connections.
+Much as there has to be someone at the office building to answer
+the phone@footnote{In the days before voice mail systems!}, the
+server process (usually) has to be started first and be waiting
+for a connection.
+
+@cindex clients
+The @dfn{client} is the system requesting the service.
+It is the system @emph{initiating the connection} in a transaction.
+(Just as when you pick up the phone to call an office or store.)
+
+In the TCP/IP framework, each end of a connection is represented by a pair
+of (@var{address}, @var{port}) pairs. For the duration of the connection,
+the ports in use at each end are unique, and cannot be used simultaneously
+by other processes on the same system. (Only after closing a connection
+can a new one be built up on the same port. This is contrary to the usual
+behavior of fully developed web servers which have to avoid situations
+in which they are not reachable. We have to pay this price in order to
+enjoy the benefits of a simple communication paradigm in @command{gawk}.)
+
+@cindex blocking
+@cindex synchronous communications
+Furthermore, once the connection is established, communications are
+@dfn{synchronous}.@footnote{For the technically savvy, data reads
+block---if there's no incoming data, the program is made to wait until
+there is, instead of receiving a ``there's no data'' error return.} I.e.,
+each end waits on the other to finish transmitting, before replying. This
+is much like two people in a phone conversation. While both could talk
+simultaneously, doing so usually doesn't work too well.
+
+In the case of TCP, the synchronicity is enforced by the protocol when
+sending data. Data writes @dfn{block} until the data have been received on the
+other end. For both TCP and UDP, data reads block until there is incoming
+data waiting to be read. This is summarized in the following table,
+where an ``X'' indicates that the given action blocks.
+
+@ifnottex
+@multitable {Protocol} {Reads} {Writes}
+@item TCP @tab X @tab X
+@item UDP @tab X @tab
+@item RAW @tab X @tab
+@end multitable
+@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{\hfil\strut# &\vrule #& \hfil#\hfil& \hfil#\hfil\cr
+Protocol&&\quad Reads\quad &Writes\cr
+\noalign{\hrule}
+\omit&height 2pt\cr
+\noalign{\hrule height0pt}% without this the rule does not extend; why?
+TCP&&X&X\cr
+UDP&&X&\cr
+RAW&&X&\cr
+}}}
+@end tex
+
+@node Using Networking, Some Applications and Techniques, Introduction, Top
+@comment node-name, next, previous, up
+@chapter Networking With @command{gawk}
+
+@c STARTOFRANGE netgawk
+@cindex networks, @command{gawk} and
+@c STARTOFRANGE gawknet
+@cindex @command{gawk}, networking
+The @command{awk} programming language was originally developed as a
+pattern-matching language for writing short programs to perform
+data manipulation tasks.
+@command{awk}'s strength is the manipulation of textual data
+that is stored in files.
+It was never meant to be used for networking purposes.
+To exploit its features in a
+networking context, it's necessary to use an access mode for network connections
+that resembles the access of files as closely as possible.
+
+@cindex Perl
+@cindex Python
+@cindex Tcl/Tk
+@command{awk} is also meant to be a prototyping language. It is used
+to demonstrate feasibility and to play with features and user interfaces.
+This can be done with file-like handling of network
+connections.
+@command{gawk} trades the lack
+of many of the advanced features of the TCP/IP family of protocols
+for the convenience of simple connection handling.
+The advanced
+features are available when programming in C or Perl. In fact, the
+network programming
+in this @value{CHAPTER}
+is very similar to what is described in books such as
+@cite{Internet Programming with Python},
+@cite{Advanced Perl Programming},
+or
+@cite{Web Client Programming with Perl}.
+
+@cindex Perl, @command{gawk} networking and
+@cindex Python, @command{gawk} networking and
+@cindex Tcl/Tk, @command{gawk} and
+However, you can do the programming here without first having to learn object-oriented
+ideology; underlying languages such as Tcl/Tk, Perl, Python; or all of
+the libraries necessary to extend these languages before they are ready for the Internet.
+
+@cindex Transmission Control Protocol, See TCP
+@cindex TCP (Transmission Control Protocol)
+This @value{CHAPTER} demonstrates how to use the TCP protocol. The
+other protocols are much less important for most users (UDP) or even
+untractable (RAW).
+
+@menu
+* Gawk Special Files:: How to do @command{gawk} networking.
+* TCP Connecting:: Making a TCP connection.
+* Troubleshooting:: Troubleshooting TCP/IP connections.
+* Interacting:: Interacting with a service.
+* Setting Up:: Setting up a service.
+* Email:: Reading email.
+* Web page:: Reading a Web page.
+* Primitive Service:: A primitive Web service.
+* Interacting Service:: A Web service with interaction.
+* Simple Server:: A simple Web server.
+* Caveats:: Network programming caveats.
+* Challenges:: Where to go from here.
+@end menu
+
+@node Gawk Special Files, TCP Connecting, Using Networking, Using Networking
+@comment node-name, next, previous, up
+@section @command{gawk}'s Networking Mechanisms
+
+The @samp{|&} operator introduced in @command{gawk} 3.1 for use in
+communicating with a @dfn{coprocess} is described in
+@ref{Two-way I/O, ,Two-way Communications With Another Process, gawk, GAWK: Effective AWK Programming}.
+It shows how to do two-way I/O to a
+separate process, sending it data with @code{print} or @code{printf} and
+reading data with @code{getline}. If you haven't read it already, you should
+detour there to do so.
+
+@command{gawk} transparently extends the two-way I/O mechanism to simple networking through
+the use of special @value{FN}s. When a ``coprocess'' that matches
+the special files we are about to describe
+is started, @command{gawk} creates the appropriate network
+connection, and then two-way I/O proceeds as usual.
+
+@c last comma is part of see-also
+@cindex input/output, two-way, See Also @command{gawk}, networking
+@cindex TCP/IP, sockets and
+At the C, C++, and Perl level, networking is accomplished
+via @dfn{sockets}, an Application Programming Interface (API) originally
+developed at the University of California at Berkeley that is now used
+almost universally for TCP/IP networking.
+Socket level programming, while fairly straightforward, requires paying
+attention to a number of details, as well as using binary data. It is not
+well-suited for use from a high-level language like @command{awk}.
+The special files provided in @command{gawk} hide the details from
+the programmer, making things much simpler and easier to use.
+@c Who sez we can't toot our own horn occasionally?
+
+@c STARTOFRANGE filenet
+@cindex filenames, for network access
+@c STARTOFRANGE gawnetf
+@cindex @command{gawk}, networking, filenames
+@c STARTOFRANGE netgawf
+@cindex networks, @command{gawk} and, filenames
+The special @value{FN} for network access is made up of several fields, all
+of which are mandatory:
+
+@example
+/inet/@var{protocol}/@var{localport}/@var{hostname}/@var{remoteport}
+@end example
+
+@cindex @code{/inet/} files (@command{gawk})
+@cindex files, @code{/inet/} (@command{gawk})
+@cindex localport field
+@cindex remoteport field
+The @file{/inet/} field is, of course, constant when accessing the network.
+The @var{localport} and @var{remoteport} fields do not have a meaning
+when used with @file{/inet/raw} because ``ports'' only apply to
+TCP and UDP. So, when using @file{/inet/raw}, the port fields always have
+to be @samp{0}.
+
+@menu
+* Special File Fields:: The fields in the special file name.
+* Comparing Protocols:: Differences between the protocols.
+@end menu
+
+@node Special File Fields, Comparing Protocols, Gawk Special Files, Gawk Special Files
+@subsection The Fields of the Special @value{FFN}
+This @value{SECTION} explains the meaning of all the other fields,
+as well as the range of values and the defaults.
+All of the fields are mandatory. To let the system pick a value,
+or if the field doesn't apply to the protocol, specify it as @samp{0}:
+
+@table @var
+@cindex protocol field
+@c last comma is part of secondary
+@cindex TCP/IP, protocols, selecting
+@item protocol
+Determines which member of the TCP/IP
+family of protocols is selected to transport the data across the
+network. There are three possible values (always written in lowercase):
+@samp{tcp}, @samp{udp}, and @samp{raw}. The exact meaning of each is
+explained later in this @value{SECTION}.
+
+@item localport
+@cindex networks, ports, specifying
+Determines which port on the local
+machine is used to communicate across the network. It has no meaning
+with @file{/inet/raw} and must therefore be @samp{0}. Application-level clients
+usually use @samp{0} to indicate they do not care which local port is
+used---instead they specify a remote port to connect to. It is vital for
+application-level servers to use a number different from @samp{0} here
+because their service has to be available at a specific publicly known
+port number. It is possible to use a name from @file{/etc/services} here.
+
+@item hostname
+@cindex hostname field
+@cindex servers, as hosts
+Determines which remote host is to
+be at the other end of the connection. Application-level servers must fill
+this field with a @samp{0} to indicate their being open for all other hosts
+to connect to them and enforce connection level server behavior this way.
+It is not possible for an application-level server to restrict its
+availability to one remote host by entering a host name here.
+Application-level clients must enter a name different from @samp{0}.
+The name can be either symbolic
+(e.g., @samp{jpl-devvax.jpl.nasa.gov}) or numeric (e.g., @samp{128.149.1.143}).
+
+@item remoteport
+Determines which port on the remote
+machine is used to communicate across the network. It has no meaning
+with @file{/inet/raw} and must therefore be 0.
+For @file{/inet/tcp} and @file{/inet/udp},
+application-level clients @emph{must} use a number
+other than @samp{0} to indicate to which port on the remote machine
+they want to connect. Application-level servers must not fill this field with
+a @samp{0}. Instead they specify a local port to which clients connect.
+It is possible to use a name from @file{/etc/services} here.
+@end table
+
+@cindex networks, @command{gawk} and, connections
+@cindex @command{gawk}, networking, connections
+Experts in network programming will notice that the usual
+client/server asymmetry found at the level of the socket API is not visible
+here. This is for the sake of simplicity of the high-level concept. If this
+asymmetry is necessary for your application,
+use another language.
+For @command{gawk}, it is
+more important to enable users to write a client program with a minimum
+of code. What happens when first accessing a network connection is seen
+in the following pseudocode:
+
+@smallexample
+if ((name of remote host given) && (other side accepts connection)) @{
+ rendez-vous successful; transmit with getline or print
+@} else @{
+ if ((other side did not accept) && (localport == 0))
+ exit unsuccessful
+ if (TCP) @{
+ set up a server accepting connections
+ this means waiting for the client on the other side to connect
+ @} else
+ ready
+@}
+@end smallexample
+
+The exact behavior of this algorithm depends on the values of the
+fields of the special @value{FN}. When in doubt, @ref{table-inet-components}
+gives you the combinations of values and their meaning. If this
+table is too complicated, focus on the three lines printed in
+@strong{bold}. All the examples in
+@ref{Using Networking, ,Networking With @command{gawk}},
+use only the
+patterns printed in bold letters.
+
+@float Table,table-inet-components
+@caption{/inet Special File Components}
+@multitable @columnfractions .15 .15 .15 .15 .40
+@headitem @sc{protocol} @tab @sc{local port} @tab @sc{host name}
+@tab @sc{remote port} @tab @sc{Resulting connection-level behavior}
+@item @strong{tcp} @tab @strong{0} @tab @strong{x} @tab @strong{x} @tab
+ @strong{Dedicated client, fails if immediately connecting to a
+ server on the other side fails}
+@item udp @tab 0 @tab x @tab x @tab Dedicated client
+@item raw @tab 0 @tab x @tab 0 @tab Dedicated client, works only as @code{root}
+@item @strong{tcp, udp} @tab @strong{x} @tab @strong{x} @tab @strong{x} @tab
+ @strong{Client, switches to dedicated server if necessary}
+@item @strong{tcp, udp} @tab @strong{x} @tab @strong{0} @tab @strong{0} @tab
+ @strong{Dedicated server}
+@item raw @tab 0 @tab 0 @tab 0 @tab Dedicated server, works only as @code{root}
+@item tcp, udp, raw @tab x @tab x @tab 0 @tab Invalid
+@item tcp, udp, raw @tab 0 @tab 0 @tab x @tab Invalid
+@item tcp, udp, raw @tab x @tab 0 @tab x @tab Invalid
+@item tcp, udp @tab 0 @tab 0 @tab 0 @tab Invalid
+@item tcp, udp @tab 0 @tab x @tab 0 @tab Invalid
+@item raw @tab x @tab 0 @tab 0 @tab Invalid
+@item raw @tab 0 @tab x @tab x @tab Invalid
+@item raw @tab x @tab x @tab x @tab Invalid
+@end multitable
+@end float
+
+In general, TCP is the preferred mechanism to use. It is the simplest
+protocol to understand and to use. Use the others only if circumstances
+demand low-overhead.
+
+@node Comparing Protocols, , Special File Fields, Gawk Special Files
+@subsection Comparing Protocols
+
+This @value{SECTION} develops a pair of programs (sender and receiver)
+that do nothing but send a timestamp from one machine to another. The
+sender and the receiver are implemented with each of the three protocols
+available and demonstrate the differences between them.
+
+@menu
+* File /inet/tcp:: The TCP special file.
+* File /inet/udp:: The UDP special file.
+* File /inet/raw:: The RAW special file.
+@end menu
+
+@node File /inet/tcp, File /inet/udp, Comparing Protocols, Comparing Protocols
+@subsubsection @file{/inet/tcp}
+@cindex @code{/inet/tcp} special files (@command{gawk})
+@cindex files, @code{/inet/tcp} (@command{gawk})
+@cindex TCP (Transmission Control Protocol)
+Once again, always use TCP.
+(Use UDP when low overhead is a necessity, and use RAW for
+network experimentation.)
+The first example is the sender
+program:
+
+@example
+# Server
+BEGIN @{
+ print strftime() |& "/inet/tcp/8888/0/0"
+ close("/inet/tcp/8888/0/0")
+@}
+@end example
+
+The receiver is very simple:
+
+@example
+# Client
+BEGIN @{
+ "/inet/tcp/0/localhost/8888" |& getline
+ print $0
+ close("/inet/tcp/0/localhost/8888")
+@}
+@end example
+
+TCP guarantees that the bytes arrive at the receiving end in exactly
+the same order that they were sent. No byte is lost
+(except for broken connections), doubled, or out of order. Some
+overhead is necessary to accomplish this, but this is the price to pay for
+a reliable service.
+It does matter which side starts first. The sender/server has to be started
+first, and it waits for the receiver to read a line.
+
+@node File /inet/udp, File /inet/raw, File /inet/tcp, Comparing Protocols
+@subsubsection @file{/inet/udp}
+@cindex @code{/inet/udp} special files (@command{gawk})
+@cindex files, @code{/inet/udp} (@command{gawk})
+@cindex UDP (User Datagram Protocol)
+@cindex User Datagram Protocol, See UDP
+The server and client programs that use UDP are almost identical to their TCP counterparts;
+only the @var{protocol} has changed. As before, it does matter which side
+starts first. The receiving side blocks and waits for the sender.
+In this case, the receiver/client has to be started first:
+
+@page
+@example
+# Server
+BEGIN @{
+ print strftime() |& "/inet/udp/8888/0/0"
+ close("/inet/udp/8888/0/0")
+@}
+@end example
+
+The receiver is almost identical to the TCP receiver:
+
+@example
+# Client
+BEGIN @{
+ "/inet/udp/0/localhost/8888" |& getline
+ print $0
+ close("/inet/udp/0/localhost/8888")
+@}
+@end example
+
+UDP cannot guarantee that the datagrams at the receiving end will arrive in exactly
+the same order they were sent. Some datagrams could be
+lost, some doubled, and some out of order. But no overhead is necessary to
+accomplish this. This unreliable behavior is good enough for tasks
+such as data acquisition, logging, and even stateless services like NFS.
+
+@node File /inet/raw, , File /inet/udp, Comparing Protocols
+@subsubsection @file{/inet/raw}
+@cindex @code{/inet/raw} special files (@command{gawk})
+@cindex files, @code{/inet/raw} (@command{gawk})
+@cindex RAW protocol
+
+This is an IP-level protocol. Only @code{root} is allowed to access this
+special file. It is meant to be the basis for implementing
+and experimenting with transport-level protocols.@footnote{This special file
+is reserved, but not otherwise currently implemented.}
+In the most general case,
+the sender has to supply the encapsulating header bytes in front of the
+packet and the receiver has to strip the additional bytes from the message.
+
+@cindex dark corner, RAW protocol
+RAW receivers cannot receive packets sent with TCP or UDP because the
+operating system does not deliver the packets to a RAW receiver. The
+operating system knows about some of the protocols on top of IP
+and decides on its own which packet to deliver to which process.
+@value{DARKCORNER}
+Therefore, the UDP receiver must be used for receiving UDP
+datagrams sent with the RAW sender. This is a dark corner, not only of
+@command{gawk}, but also of TCP/IP.
+
+@cindex SPAK utility
+For extended experimentation with protocols, look into
+the approach implemented in a tool called SPAK.
+This tool reflects the hierarchical layering of protocols (encapsulation)
+in the way data streams are piped out of one program into the next one.
+It shows which protocol is based on which other (lower-level) protocol
+by looking at the command-line ordering of the program calls.
+Cleverly thought out, SPAK is much better than @command{gawk}'s
+@file{/inet} for learning the meaning of each and every bit in the
+protocol headers.
+
+The next example uses the RAW protocol to emulate
+the behavior of UDP. The sender program is the same as above, but with some
+additional bytes that fill the places of the UDP fields:
+
+@example
+@group
+BEGIN @{
+ Message = "Hello world\n"
+ SourcePort = 0
+ DestinationPort = 8888
+ MessageLength = length(Message)+8
+ RawService = "/inet/raw/0/localhost/0"
+ printf("%c%c%c%c%c%c%c%c%s",
+ SourcePort/256, SourcePort%256,
+ DestinationPort/256, DestinationPort%256,
+ MessageLength/256, MessageLength%256,
+ 0, 0, Message) |& RawService
+ fflush(RawService)
+ close(RawService)
+@}
+@end group
+@end example
+
+Since this program tries
+to emulate the behavior of UDP, it checks if
+the RAW sender is understood by the UDP receiver but not if the RAW receiver
+can understand the UDP sender. In a real network, the
+RAW receiver is hardly
+of any use because it gets every IP packet that
+comes across the network. There are usually so many packets that
+@command{gawk} would be too slow for processing them.
+Only on a network with little
+traffic can the IP-level receiver program be tested. Programs for analyzing
+IP traffic on modem or ISDN channels should be possible.
+
+Port numbers do not have a meaning when using @file{/inet/raw}. Their fields
+have to be @samp{0}. Only TCP and UDP use ports. Receiving data from
+@file{/inet/raw} is difficult, not only because of processing speed but also
+because data is usually binary and not restricted to ASCII. This
+implies that line separation with @code{RS} does not work as usual.
+
+@node TCP Connecting, Troubleshooting, Gawk Special Files, Using Networking
+@section Establishing a TCP Connection
+
+@c STARTOFRANGE tcpcon
+@cindex TCP (Transmission Control Protocol), connection, establishing
+@c STARTOFRANGE netcon
+@cindex networks, @command{gawk} and, connections
+@c STARTOFRANGE gawcon
+@cindex @command{gawk}, networking, connections
+Let's observe a network connection at work. Type in the following program
+and watch the output. Within a second, it connects via TCP (@file{/inet/tcp})
+to the machine it is running on (@samp{localhost}) and asks the service
+@samp{daytime} on the machine what time it is:
+
+@cindex @code{getline} command
+@example
+BEGIN @{
+ "/inet/tcp/0/localhost/daytime" |& getline
+ print $0
+ close("/inet/tcp/0/localhost/daytime")
+@}
+@end example
+
+Even experienced @command{awk} users will find the second line strange in two
+respects:
+
+@itemize @bullet
+@item
+A special file is used as a shell command that pipes its output
+into @code{getline}. One would rather expect to see the special file
+being read like any other file (@samp{getline <
+"/inet/tcp/0/localhost/daytime")}.
+
+@item
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
+The operator @samp{|&} has not been part of any @command{awk}
+implementation (until now).
+It is actually the only extension of the @command{awk}
+language needed (apart from the special files) to introduce network access.
+@end itemize
+
+@cindex pipes, networking and
+The @samp{|&} operator was introduced in @command{gawk} 3.1 in order to
+overcome the crucial restriction that access to files and pipes in
+@command{awk} is always unidirectional. It was formerly impossible to use
+both access modes on the same file or pipe. Instead of changing the whole
+concept of file access, the @samp{|&} operator
+behaves exactly like the usual pipe operator except for two additions:
+
+@itemize @bullet
+@item
+Normal shell commands connected to their @command{gawk} program with a @samp{|&}
+pipe can be accessed bidirectionally. The @samp{|&} turns out to be a quite
+general, useful, and natural extension of @command{awk}.
+
+@item
+Pipes that consist of a special @value{FN} for network connections are not
+executed as shell commands. Instead, they can be read and written to, just
+like a full-duplex network connection.
+@end itemize
+
+In the earlier example, the @samp{|&} operator tells @code{getline}
+to read a line from the special file @file{/inet/tcp/0/localhost/daytime}.
+We could also have printed a line into the special file. But instead we just
+read a line with the time, printed it, and closed the connection.
+(While we could just let @command{gawk} close the connection by finishing
+the program, in this @value{DOCUMENT}
+we are pedantic and always explicitly close the connections.)
+
+@node Troubleshooting, Interacting, TCP Connecting, Using Networking
+@section Troubleshooting Connection Problems
+@cindex advanced features, network connections
+@c last comma is part of secondary
+@cindex troubleshooting, networks, connections
+It may well be that for some reason the program shown in the previous example does not run on your
+machine. When looking at possible reasons for this, you will learn much
+about typical problems that arise in network programming. First of all,
+your implementation of @command{gawk} may not support network access
+because it is
+a pre-3.1 version or you do not have a network interface in your machine.
+Perhaps your machine uses some other protocol, such as
+DECnet or Novell's IPX. For the rest of this @value{CHAPTER},
+we will assume
+you work on a Unix machine that supports TCP/IP. If the previous example program does
+not run on your machine, it may help to replace the name
+@samp{localhost} with the name of your machine or its IP address. If it
+does, you could replace @samp{localhost} with the name of another machine
+in your vicinity---this way, the program connects to another machine.
+Now you should see the date and time being printed by the program,
+otherwise your machine may not support the @samp{daytime} service.
+Try changing the service to @samp{chargen} or @samp{ftp}. This way, the program
+connects to other services that should give you some response. If you are
+curious, you should have a look at your @file{/etc/services} file. It could
+look like this:
+
+@ignore
+@multitable {1234567890123} {1234567890123} {123456789012345678901234567890123456789012}
+@item Service @strong{name} @tab Service @strong{number}
+@item echo @tab 7/tcp @tab echo sends back each line it receivces
+@item echo @tab 7/udp @tab echo is good for testing purposes
+@item discard @tab 9/tcp @tab discard behaves like @file{/dev/null}
+@item discard @tab 9/udp @tab discard just throws away each line
+@item daytime @tab 13/tcp @tab daytime sends date & time once per connection
+@item daytime @tab 13/udp
+@item chargen @tab 19/tcp @tab chargen infinitely produces character sets
+@item chargen @tab 19/udp @tab chargen is good for testing purposes
+@item ftp @tab 21/tcp @tab ftp is the usual file transfer protocol
+@item telnet @tab 23/tcp @tab telnet is the usual login facility
+@item smtp @tab 25/tcp @tab smtp is the Simple Mail Transfer Protocol
+@item finger @tab 79/tcp @tab finger tells you who is logged in
+@item www @tab 80/tcp @tab www is the HyperText Transfer Protocol
+@item pop2 @tab 109/tcp @tab pop2 is an older version of pop3
+@item pop2 @tab 109/udp
+@item pop3 @tab 110/tcp @tab pop3 is the Post Office Protocol
+@item pop3 @tab 110/udp @tab pop3 is used for receiving email
+@item nntp @tab 119/tcp @tab nntp is the USENET News Transfer Protocol
+@item irc @tab 194/tcp @tab irc is the Internet Relay Chat
+@item irc @tab 194/udp
+@end multitable
+@end ignore
+
+@smallexample
+# /etc/services:
+#
+# Network services, Internet style
+#
+# Name Number/Protcol Alternate name # Comments
+
+echo 7/tcp
+echo 7/udp
+discard 9/tcp sink null
+discard 9/udp sink null
+daytime 13/tcp
+daytime 13/udp
+chargen 19/tcp ttytst source
+chargen 19/udp ttytst source
+ftp 21/tcp
+telnet 23/tcp
+smtp 25/tcp mail
+finger 79/tcp
+www 80/tcp http # WorldWideWeb HTTP
+www 80/udp # HyperText Transfer Protocol
+pop-2 109/tcp postoffice # POP version 2
+pop-2 109/udp
+pop-3 110/tcp # POP version 3
+pop-3 110/udp
+nntp 119/tcp readnews untp # USENET News
+irc 194/tcp # Internet Relay Chat
+irc 194/udp
+@dots{}
+@end smallexample
+
+@cindex Linux
+@cindex GNU/Linux
+@cindex Microsoft Windows, networking
+Here, you find a list of services that traditional Unix machines usually
+support. If your GNU/Linux machine does not do so, it may be that these
+services are switched off in some startup script. Systems running some
+flavor of Microsoft Windows usually do @emph{not} support these services.
+Nevertheless, it @emph{is} possible to do networking with @command{gawk} on
+Microsoft
+Windows.@footnote{Microsoft prefered to ignore the TCP/IP
+family of protocols until 1995. Then came the rise of the Netscape browser
+as a landmark ``killer application.'' Microsoft added TCP/IP support and
+their own browser to Microsoft Windows 95 at the last minute. They even back-ported
+their TCP/IP implementation to Microsoft Windows for Workgroups 3.11, but it was
+a rather rudimentary and half-hearted implementation. Nevertheless,
+the equivalent of @file{/etc/services} resides under
+@file{C:\WINNT\system32\drivers\etc\services} on Microsoft Windows 2000.}
+The first column of the file gives the name of the service, and
+the second column gives a unique number and the protocol that one can use to connect to
+this service.
+The rest of the line is treated as a comment.
+You see that some services (@samp{echo}) support TCP as
+well as UDP.
+
+@node Interacting, Setting Up, Troubleshooting, Using Networking
+@section Interacting with a Network Service
+
+The next program makes use of the possibility to really interact with a
+network service by printing something into the special file. It asks the
+so-called @command{finger} service if a user of the machine is logged in. When
+testing this program, try to change @samp{localhost} to
+some other machine name in your local network:
+
+@c system if test ! -d eg ; then mkdir eg ; fi
+@c system if test ! -d eg/network ; then mkdir eg/network ; fi
+@example
+@c file eg/network/fingerclient.awk
+BEGIN @{
+ NetService = "/inet/tcp/0/localhost/finger"
+ print "@var{name}" |& NetService
+ while ((NetService |& getline) > 0)
+ print $0
+ close(NetService)
+@}
+@c endfile
+@end example
+
+After telling the service on the machine which user to look for,
+the program repeatedly reads lines that come as a reply. When no more
+lines are coming (because the service has closed the connection), the
+program also closes the connection. Try replacing @code{"@var{name}"} with your
+login name (or the name of someone else logged in). For a list
+of all users currently logged in, replace @var{name} with an empty string
+(@code{""}).
+
+@cindex Linux
+@cindex GNU/Linux
+The final @code{close} command could be safely deleted from
+the above script, because the operating system closes any open connection
+by default when a script reaches the end of execution. In order to avoid
+portability problems, it is best to always close connections explicitly.
+With the Linux kernel,
+for example, proper closing results in flushing of buffers. Letting
+the close happen by default may result in discarding buffers.
+
+@ignore
+@c Chuck comments that this seems out of place. He's right. I dunno
+@c where to put it though.
+@cindex @command{finger} utility
+@cindex RFC 1288
+In the early days of the Internet (up until about 1992), you could use
+such a program to check if some user in another country was logged in on
+a specific machine.
+RFC 1288@footnote{@uref{http://www.cis.ohio-state.edu/htbin/rfc/rfc1288.html}}
+provides the exact definition of the @command{finger} protocol.
+Every contemporary Unix system also has a command named @command{finger},
+which functions as a client for the protocol of the same name.
+Still today, some people maintain simple information systems
+with this ancient protocol. For example, by typing
+@samp{finger quake@@seismo.unr.edu}
+you get the latest @dfn{Earthquake Bulletin} for the state of Nevada.
+
+@cindex Earthquake Bulletin
+@smallexample
+$ finger quake@@seismo.unr.edu
+
+[@dots{}]
+
+DATE-(UTC)-TIME LAT LON DEP MAG COMMENTS
+yy/mm/dd hh:mm:ss deg. deg. km
+
+98/12/14 21:09:22 37.47N 116.30W 0.0 2.3Md 76.4 km S of WARM SPRINGS, NEVA
+98/12/14 22:05:09 39.69N 120.41W 11.9 2.1Md 53.8 km WNW of RENO, NEVADA
+98/12/15 14:14:19 38.04N 118.60W 2.0 2.3Md 51.0 km S of HAWTHORNE, NEVADA
+98/12/17 01:49:02 36.06N 117.58W 13.9 3.0Md 74.9 km SE of LONE PINE, CALIFOR
+98/12/17 05:39:26 39.95N 120.87W 6.2 2.6Md 101.6 km WNW of RENO, NEVADA
+98/12/22 06:07:42 38.68N 119.82W 5.2 2.3Md 50.7 km S of CARSON CITY, NEVAD
+@end smallexample
+
+@noindent
+This output from @command{finger} contains the time, location, depth,
+magnitude, and a short comment about
+the earthquakes registered in that region during the last 10 days.
+In many places today the use of such services is restricted
+because most networks have firewalls and proxy servers between them
+and the Internet. Most firewalls are programmed to not let
+@command{finger} requests go beyond the local network.
+
+@cindex Coke machine
+Another (ab)use of the @command{finger} protocol are several Coke machines
+that are connected to the Internet. There is a short list of such
+Coke machines.@footnote{@uref{http://ca.yahoo.com/Computers_and_Internet/Internet/Devices_Connected_to_the_Internet/Soda_Machines/}}
+You can access them either from the command-line or with a simple
+@command{gawk} script. They usually tell you about the different
+flavors of Coke and beer available there. If you have an account there,
+you can even order some drink this way.
+@end ignore
+
+When looking at @file{/etc/services} you may have noticed that the
+@samp{daytime} service is also available with @samp{udp}. In the earlier
+example, change @samp{tcp} to @samp{udp},
+and change @samp{finger} to @samp{daytime}.
+After starting the modified program, you see the expected day and time message.
+The program then hangs, because it waits for more lines coming from the
+service. However, they never come. This behavior is a consequence of the
+differences between TCP and UDP. When using UDP, neither party is
+automatically informed about the other closing the connection.
+Continuing to experiment this way reveals many other subtle
+differences between TCP and UDP. To avoid such trouble, one should always
+remember the advice Douglas E.@: Comer and David Stevens give in
+Volume III of their series @cite{Internetworking With TCP}
+(page 14):
+
+@cindex TCP (Transmission Control Protocol), UDP and
+@cindex UDP (User Datagram Protocol), TCP and
+@cindex Internet, See networks
+@quotation
+When designing client-server applications, beginners are strongly
+advised to use TCP because it provides reliable, connection-oriented
+communication. Programs only use UDP if the application protocol handles
+reliability, the application requires hardware broadcast or multicast,
+or the application cannot tolerate virtual circuit overhead.
+@end quotation
+
+@node Setting Up, Email, Interacting, Using Networking
+@section Setting Up a Service
+@c last comma is part of tertiary
+@cindex networks, @command{gawk} and, service, establishing
+@c last comma is part of tertiary
+@cindex @command{gawk}, networking, service, establishing
+The preceding programs behaved as clients that connect to a server somewhere
+on the Internet and request a particular service. Now we set up such a
+service to mimic the behavior of the @samp{daytime} service.
+Such a server does not know in advance who is going to connect to it over
+the network. Therefore, we cannot insert a name for the host to connect to
+in our special @value{FN}.
+
+Start the following program in one window. Notice that the service does
+not have the name @samp{daytime}, but the number @samp{8888}.
+From looking at @file{/etc/services}, you know that names like @samp{daytime}
+are just mnemonics for predetermined 16-bit integers.
+Only the system administrator (@code{root}) could enter
+our new service into @file{/etc/services} with an appropriate name.
+Also notice that the service name has to be entered into a different field
+of the special @value{FN} because we are setting up a server, not a client:
+
+@cindex @command{finger} utility
+@cindex servers
+@example
+BEGIN @{
+ print strftime() |& "/inet/tcp/8888/0/0"
+ close("/inet/tcp/8888/0/0")
+@}
+@end example
+
+Now open another window on the same machine.
+Copy the client program given as the first example
+(@pxref{TCP Connecting, ,Establishing a TCP Connection})
+to a new file and edit it, changing the name @samp{daytime} to
+@samp{8888}. Then start the modified client. You should get a reply
+like this:
+
+@example
+Sat Sep 27 19:08:16 CEST 1997
+@end example
+
+@noindent
+Both programs explicitly close the connection.
+
+@c first comma is part of primary
+@cindex Microsoft Windows, networking, ports
+@cindex networks, ports, reserved
+@cindex Unix, network ports and
+Now we will intentionally make a mistake to see what happens when the name
+@samp{8888} (the so-called port) is already used by another service.
+Start the server
+program in both windows. The first one works, but the second one
+complains that it could not open the connection. Each port on a single
+machine can only be used by one server program at a time. Now terminate the
+server program and change the name @samp{8888} to @samp{echo}. After restarting it,
+the server program does not run any more, and you know why: there is already
+an @samp{echo} service running on your machine. But even if this isn't true,
+you would not get
+your own @samp{echo} server running on a Unix machine,
+because the ports with numbers smaller
+than 1024 (@samp{echo} is at port 7) are reserved for @code{root}.
+On machines running some flavor of Microsoft Windows, there is no restriction
+that reserves ports 1 to 1024 for a privileged user; hence, you can start
+an @samp{echo} server there.
+
+Turning this short server program into something really useful is simple.
+Imagine a server that first reads a @value{FN} from the client through the
+network connection, then does something with the file and
+sends a result back to the client. The server-side processing
+could be:
+
+@example
+BEGIN @{
+ NetService = "/inet/tcp/8888/0/0"
+ NetService |& getline
+ CatPipe = ("cat " $1) # sets $0 and the fields
+ while ((CatPipe | getline) > 0)
+ print $0 |& NetService
+ close(NetService)
+@}
+@end example
+
+@noindent
+and we would
+have a remote copying facility. Such a server reads the name of a file
+from any client that connects to it and transmits the contents of the
+named file across the net. The server-side processing could also be
+the execution of a command that is transmitted across the network. From this
+example, you can see how simple it is to open up a security hole on your
+machine. If you allow clients to connect to your machine and
+execute arbitrary commands, anyone would be free to do @samp{rm -rf *}.
+
+@node Email, Web page, Setting Up, Using Networking
+@section Reading Email
+@c @cindex RFC 1939
+@c @cindex RFC 821
+@cindex @command{gawk}, networking, See Also email
+@cindex networks, @command{gawk} and, See Also email
+@cindex POP (Post Office Protocol)
+@cindex SMTP (Simple Mail Transfer Protocol)
+@cindex Post Office Protocol (POP)
+@cindex Simple Mail Transfer Protocol (SMTP)
+The distribution of email is usually done by dedicated email servers that
+communicate with your machine using special protocols. To receive email, we
+will use the Post Office Protocol (POP). Sending can be done with the much
+older Simple Mail Transfer Protocol (SMTP).
+@ignore
+@footnote{RFC 1939 defines POP.
+RFC 821 defines SMTP. See
+@uref{http://rfc.fh-koeln.de/doc/rfc/html/rfc.html, RFCs in HTML}.}
+@end ignore
+
+@cindex email
+When you type in the following program, replace the @var{emailhost} by the
+name of your local email server. Ask your administrator if the server has a
+POP service, and then use its name or number in the program below.
+Now the program is ready to connect to your email server, but it will not
+succeed in retrieving your mail because it does not yet know your login
+name or password. Replace them in the program and it
+shows you the first email the server has in store:
+
+@example
+BEGIN @{
+ POPService = "/inet/tcp/0/@var{emailhost}/pop3"
+ RS = ORS = "\r\n"
+ print "user @var{name}" |& POPService
+ POPService |& getline
+ print "pass @var{password}" |& POPService
+ POPService |& getline
+ print "retr 1" |& POPService
+ POPService |& getline
+ if ($1 != "+OK") exit
+ print "quit" |& POPService
+ RS = "\r\n\\.\r\n"
+ POPService |& getline
+ print $0
+ close(POPService)
+@}
+@end example
+
+@c @cindex RFC 1939
+@cindex record separators, POP and
+@cindex @code{RS} variable, POP and
+@cindex @code{ORS} variable, POP and
+@cindex POP (Post Office Protocol)
+The record separators @code{RS} and @code{ORS} are redefined because the
+protocol (POP) requires CR-LF to separate lines. After identifying
+yourself to the email service, the command @samp{retr 1} instructs the
+service to send the first of all your email messages in line. If the service
+replies with something other than @samp{+OK}, the program exits; maybe there
+is no email. Otherwise, the program first announces that it intends to finish
+reading email, and then redefines @code{RS} in order to read the entire
+email as multiline input in one record. From the POP RFC, we know that the body
+of the email always ends with a single line containing a single dot.
+The program looks for this using @samp{RS = "\r\n\\.\r\n"}.
+When it finds this sequence in the mail message, it quits.
+You can invoke this program as often as you like; it does not delete the
+message it reads, but instead leaves it on the server.
+
+@node Web page, Primitive Service, Email, Using Networking
+@section Reading a Web Page
+@cindex web pages
+@cindex HTTP (Hypertext Transfer Protocol)
+@cindex Hypertext Transfer Protocol, See HTTP
+@c @cindex RFC 2068
+@c @cindex RFC 2616
+
+Retrieving a web page from a web server is as simple as
+retrieving email from an email server. We only have to use a
+similar, but not identical, protocol and a different port. The name of the
+protocol is HyperText Transfer Protocol (HTTP) and the port number is usually
+80. As in the preceding @value{SECTION}, ask your administrator about the
+name of your local web server or proxy web server and its port number
+for HTTP requests.
+
+@ignore
+@c Chuck says this stuff isn't necessary
+More detailed information about HTTP can be found at
+the home of the web protocols,@footnote{@uref{http://www.w3.org/pub/WWW/Protocols}}
+including the specification of HTTP in RFC 2068. The protocol specification
+in RFC 2068 is concise and you can get it for free. If you need more
+explanation and you are willing to pay for a book, you might be
+interested in one of these books:
+
+@enumerate
+
+@item
+When we started writing web clients and servers with @command{gawk},
+the only book available with details about HTTP was the one by Paul Hethmon
+called
+@cite{Illustrated Guide to HTTP}.@footnote{@uref{http://www.browsebooks.com/Hethmon/?882}}
+Hethmon not only describes HTTP,
+he also implements a simple web server in C++.
+
+@item
+Since July 2000, O'Reilly offers the book by Clinton Wong called
+@cite{HTTP Pocket Reference}.@footnote{@uref{http://www.oreilly.com/catalog/httppr}}
+It only has 75 pages but its
+focus definitely is HTTP. This pocket reference is not a replacement
+for the RFC, but I wish I had had it back in 1997 when I started writing
+scripts to handle HTTP.
+
+@item
+Another small booklet about HTTP is the one by Toexcell Incorporated Staff,
+ISBN 1-58348-270-9, called
+@cite{Hypertext Transfer Protocol Http 1.0 Specifications}
+
+@end enumerate
+@end ignore
+
+The following program employs a rather crude approach toward retrieving a
+web page. It uses the prehistoric syntax of HTTP 0.9, which almost all
+web servers still support. The most noticeable thing about it is that the
+program directs the request to the local proxy server whose name you insert
+in the special @value{FN} (which in turn calls @samp{www.yahoo.com}):
+
+@example
+BEGIN @{
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/0/@var{proxy}/80"
+ print "GET http://www.yahoo.com" |& HttpService
+ while ((HttpService |& getline) > 0)
+ print $0
+ close(HttpService)
+@}
+@end example
+
+@c @cindex RFC 1945
+@cindex record separators, HTTP and
+@cindex @code{RS} variable, HTTP and
+@cindex @code{ORS} variable, HTTP and
+@cindex HTTP (Hypertext Transfer Protocol), record separators and
+@cindex HTML (Hypertext Markup Language)
+@cindex Hypertext Markup Language (HTML)
+Again, lines are separated by a redefined @code{RS} and @code{ORS}.
+The @code{GET} request that we send to the server is the only kind of
+HTTP request that existed when the web was created in the early 1990s.
+HTTP calls this @code{GET} request a ``method,'' which tells the
+service to transmit a web page (here the home page of the Yahoo! search
+engine). Version 1.0 added the request methods @code{HEAD} and
+@code{POST}. The current version of HTTP is 1.1,@footnote{Version 1.0 of
+HTTP was defined in RFC 1945. HTTP 1.1 was initially specified in RFC
+2068. In June 1999, RFC 2068 was made obsolete by RFC 2616, an update
+without any substantial changes.} and knows the additional request
+methods @code{OPTIONS}, @code{PUT}, @code{DELETE}, and @code{TRACE}.
+You can fill in any valid web address, and the program prints the
+HTML code of that page to your screen.
+
+Notice the similarity between the responses of the POP and HTTP
+services. First, you get a header that is terminated by an empty line, and
+then you get the body of the page in HTML. The lines of the headers also
+have the same form as in POP. There is the name of a parameter,
+then a colon, and finally the value of that parameter.
+
+@cindex CGI (Common Gateway Interface), dynamic web pages and
+@cindex Common Gateway Interface, See CGI
+@cindex GIF image format
+@cindex PNG image format
+@cindex images, retrieving over networks
+Images (@file{.png} or @file{.gif} files) can also be retrieved this way,
+but then you
+get binary data that should be redirected into a file. Another
+application is calling a CGI (Common Gateway Interface) script on some
+server. CGI scripts are used when the contents of a web page are not
+constant, but generated instantly at the moment you send a request
+for the page. For example, to get a detailed report about the current
+quotes of Motorola stock shares, call a CGI script at Yahoo! with
+the following:
+
+@example
+get = "GET http://quote.yahoo.com/q?s=MOT&d=t"
+print get |& HttpService
+@end example
+
+You can also request weather reports this way.
+@ignore
+@cindex Boutell, Thomas
+A good book to go on with is
+the
+@cite{HTML Source Book}.@footnote{@uref{http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/book.html}}
+There are also some books on CGI programming
+like @cite{CGI Programming in C & Perl},
+by Thomas Boutell@footnote{@uref{http://cseng.aw.com/bookdetail.qry?ISBN=0-201-42219-0&ptype=0}},
+and @cite{The CGI Book}.@footnote{@uref{http://www.cgibook.com}}
+Another good source is @cite{The CGI Resource Index}}.@footnote{@uref{http://www.cgi-resources.com}}
+@end ignore
+
+@node Primitive Service, Interacting Service, Web page, Using Networking
+@section A Primitive Web Service
+@c STARTOFRANGE webser
+@cindex web service
+Now we know enough about HTTP to set up a primitive web service that just
+says @code{"Hello, world"} when someone connects to it with a browser.
+Compared
+to the situation in the preceding @value{SECTION}, our program changes the role. It
+tries to behave just like the server we have observed. Since we are setting
+up a server here, we have to insert the port number in the @samp{localport}
+field of the special @value{FN}. The other two fields (@var{hostname} and
+@var{remoteport}) have to contain a @samp{0} because we do not know in
+advance which host will connect to our service.
+
+In the early 1990s, all a server had to do was send an HTML document and
+close the connection. Here, we adhere to the modern syntax of HTTP.
+The steps are as follows:
+
+@enumerate 1
+@item
+Send a status line telling the web browser that everything
+is okay.
+
+@item
+Send a line to tell the browser how many bytes follow in the
+body of the message. This was not necessary earlier because both
+parties knew that the document ended when the connection closed. Nowadays
+it is possible to stay connected after the transmission of one web page.
+This is to avoid the network traffic necessary for repeatedly establishing
+TCP connections for requesting several images. Thus, there is the need to tell
+the receiving party how many bytes will be sent. The header is terminated
+as usual with an empty line.
+
+@item
+Send the @code{"Hello, world"} body
+in HTML.
+The useless @code{while} loop swallows the request of the browser.
+We could actually omit the loop, and on most machines the program would still
+work.
+First, start the following program:
+@end enumerate
+
+@example
+@c file eg/network/hello-serv.awk
+BEGIN @{
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/8080/0/0"
+ Hello = "<HTML><HEAD>" \
+ "<TITLE>A Famous Greeting</TITLE></HEAD>" \
+ "<BODY><H1>Hello, world</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+@}
+@c endfile
+@end example
+
+Now, on the same machine, start your favorite browser and let it point to
+@uref{http://localhost:8080} (the browser needs to know on which port
+our server is listening for requests). If this does not work, the browser
+probably tries to connect to a proxy server that does not know your machine.
+If so, change the browser's configuration so that the browser does not try to
+use a proxy to connect to your machine.
+
+@node Interacting Service, Simple Server, Primitive Service, Using Networking
+@section A Web Service with Interaction
+@cindex @command{gawk}, web and, See web service
+@cindex web browsers, See web service
+@c comma is part of primary
+@cindex HTTP server, core logic
+@cindex servers, HTTP
+@ifinfo
+This node shows how to set up a simple web server.
+The subnode is a library file that we will use with all the examples in
+@ref{Some Applications and Techniques}.
+@end ifinfo
+
+@menu
+* CGI Lib:: A simple CGI library.
+@end menu
+
+Setting up a web service that allows user interaction is more difficult and
+shows us the limits of network access in @command{gawk}. In this @value{SECTION},
+we develop a main program (a @code{BEGIN} pattern and its action)
+that will become the core of event-driven execution controlled by a
+graphical user interface (GUI).
+Each HTTP event that the user triggers by some action within the browser
+is received in this central procedure. Parameters and menu choices are
+extracted from this request, and an appropriate measure is taken according to
+the user's choice.
+For example:
+
+@cindex HTTP server, core logic
+@example
+BEGIN @{
+ if (MyHost == "") @{
+ "uname -n" | getline MyHost
+ close("uname -n")
+ @}
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ MyPrefix = "http://" MyHost ":" MyPort
+ SetUpServer()
+ while ("awk" != "complex") @{
+ # header lines are terminated this way
+ RS = ORS = "\r\n"
+ Status = 200 # this means OK
+ Reason = "OK"
+ Header = TopHeader
+ Document = TopDoc
+ Footer = TopFooter
+ if (GETARG["Method"] == "GET") @{
+ HandleGET()
+ @} else if (GETARG["Method"] == "HEAD") @{
+ # not yet implemented
+ @} else if (GETARG["Method"] != "") @{
+ print "bad method", GETARG["Method"]
+ @}
+ Prompt = Header Document Footer
+ print "HTTP/1.0", Status, Reason |& HttpService
+ print "Connection: Close" |& HttpService
+ print "Pragma: no-cache" |& HttpService
+ len = length(Prompt) + length(ORS)
+ print "Content-length:", len |& HttpService
+ print ORS Prompt |& HttpService
+ # ignore all the header lines
+ while ((HttpService |& getline) > 0)
+ ;
+ # stop talking to this client
+ close(HttpService)
+ # wait for new client request
+ HttpService |& getline
+ # do some logging
+ print systime(), strftime(), $0
+ # read request parameters
+ CGI_setup($1, $2, $3)
+ @}
+@}
+@end example
+
+This web server presents menu choices in the form of HTML links.
+Therefore, it has to tell the browser the name of the host it is
+residing on. When starting the server, the user may supply the name
+of the host from the command line with @samp{gawk -v MyHost="Rumpelstilzchen"}.
+If the user does not do this, the server looks up the name of the host it is
+running on for later use as a web address in HTML documents. The same
+applies to the port number. These values are inserted later into the
+HTML content of the web pages to refer to the home system.
+
+Each server that is built around this core has to initialize some
+application-dependent variables (such as the default home page) in a procedure
+@code{SetUpServer}, which is called immediately before entering the
+infinite loop of the server. For now, we will write an instance that
+initiates a trivial interaction. With this home page, the client user
+can click on two possible choices, and receive the current date either
+in human-readable format or in seconds since 1970:
+
+@example
+function SetUpServer() @{
+ TopHeader = "<HTML><HEAD>"
+ TopHeader = TopHeader \
+ "<title>My name is GAWK, GNU AWK</title></HEAD>"
+ TopDoc = "<BODY><h2>\
+ Do you prefer your date <A HREF=" MyPrefix \
+ "/human>human</A> or \
+ <A HREF=" MyPrefix "/POSIX>POSIXed</A>?</h2>" ORS ORS
+ TopFooter = "</BODY></HTML>"
+@}
+@end example
+
+On the first run through the main loop, the default line terminators are
+set and the default home page is copied to the actual home page. Since this
+is the first run, @code{GETARG["Method"]} is not initialized yet, hence the
+case selection over the method does nothing. Now that the home page is
+initialized, the server can start communicating to a client browser.
+
+@c @cindex RFC 2068
+It does so by printing the HTTP header into the network connection
+(@samp{print @dots{} |& HttpService}). This command blocks execution of
+the server script until a client connects. If this server
+script is compared with the primitive one we wrote before, you will notice
+two additional lines in the header. The first instructs the browser
+to close the connection after each request. The second tells the
+browser that it should never try to @emph{remember} earlier requests
+that had identical web addresses (no caching). Otherwise, it could happen
+that the browser retrieves the time of day in the previous example just once,
+and later it takes the web page from the cache, always displaying the same
+time of day although time advances each second.
+
+Having supplied the initial home page to the browser with a valid document
+stored in the parameter @code{Prompt}, it closes the connection and waits
+for the next request. When the request comes, a log line is printed that
+allows us to see which request the server receives. The final step in the
+loop is to call the function @code{CGI_setup}, which reads all the lines
+of the request (coming from the browser), processes them, and stores the
+transmitted parameters in the array @code{PARAM}. The complete
+text of these application-independent functions can be found in
+@ref{CGI Lib, ,A Simple CGI Library}.
+For now, we use a simplified version of @code{CGI_setup}:
+
+@example
+function CGI_setup( method, uri, version, i) @{
+ delete GETARG; delete MENU; delete PARAM
+ GETARG["Method"] = $1
+ GETARG["URI"] = $2
+ GETARG["Version"] = $3
+ i = index($2, "?")
+ # is there a "?" indicating a CGI request?
+@group
+ if (i > 0) @{
+ split(substr($2, 1, i-1), MENU, "[/:]")
+ split(substr($2, i+1), PARAM, "&")
+ for (i in PARAM) @{
+ j = index(PARAM[i], "=")
+ GETARG[substr(PARAM[i], 1, j-1)] = \
+ substr(PARAM[i], j+1)
+ @}
+ @} else @{ # there is no "?", no need for splitting PARAMs
+ split($2, MENU, "[/:]")
+ @}
+@end group
+@}
+@end example
+
+At first, the function clears all variables used for
+global storage of request parameters. The rest of the function serves
+the purpose of filling the global parameters with the extracted new values.
+To accomplish this, the name of the requested resource is split into
+parts and stored for later evaluation. If the request contains a @samp{?},
+then the request has CGI variables seamlessly appended to the web address.
+Everything in front of the @samp{?} is split up into menu items, and
+everything behind the @samp{?} is a list of @samp{@var{variable}=@var{value}} pairs
+(separated by @samp{&}) that also need splitting. This way, CGI variables are
+isolated and stored. This procedure lacks recognition of special characters
+that are transmitted in coded form@footnote{As defined in RFC 2068.}. Here, any
+optional request header and body parts are ignored. We do not need
+header parameters and the request body. However, when refining our approach or
+working with the @code{POST} and @code{PUT} methods, reading the header
+and body
+becomes inevitable. Header parameters should then be stored in a global
+array as well as the body.
+
+On each subsequent run through the main loop, one request from a browser is
+received, evaluated, and answered according to the user's choice. This can be
+done by letting the value of the HTTP method guide the main loop into
+execution of the procedure @code{HandleGET}, which evaluates the user's
+choice. In this case, we have only one hierarchical level of menus,
+but in the general case,
+menus are nested.
+The menu choices at each level are
+separated by @samp{/}, just as in @value{FN}s. Notice how simple it is to
+construct menus of arbitrary depth:
+
+@example
+function HandleGET() @{
+ if ( MENU[2] == "human") @{
+ Footer = strftime() TopFooter
+ @} else if (MENU[2] == "POSIX") @{
+ Footer = systime() TopFooter
+ @}
+@}
+@end example
+
+The disadvantage of this approach is that our server is slow and can
+handle only one request at a time. Its main advantage, however, is that
+the server
+consists of just one @command{gawk} program. No need for installing an
+@command{httpd}, and no need for static separate HTML files, CGI scripts, or
+@code{root} privileges. This is rapid prototyping.
+This program can be started on the same host that runs your browser.
+Then let your browser point to @uref{http://localhost:8080}.
+
+@cindex XBM image format
+@cindex images, in web pages
+@cindex web pages, images in
+@cindex GNUPlot utility
+It is also possible to include images into the HTML pages.
+Most browsers support the not very well-known
+@file{.xbm} format,
+which may contain only
+monochrome pictures but is an ASCII format. Binary images are possible but
+not so easy to handle. Another way of including images is to generate them
+with a tool such as GNUPlot,
+by calling the tool with the @code{system} function or through a pipe.
+
+@node CGI Lib, , Interacting Service, Interacting Service
+@subsection A Simple CGI Library
+@quotation
+@i{HTTP is like being married: you have to be able to handle whatever
+you're given, while being very careful what you send back.}@*
+Phil Smith III,@*
+@uref{http://www.netfunny.com/rhf/jokes/99/Mar/http.html}
+@end quotation
+
+@c STARTOFRANGE cgilib
+@cindex CGI (Common Gateway Interface), library
+In @ref{Interacting Service, ,A Web Service with Interaction},
+we saw the function @code{CGI_setup} as part of the web server
+``core logic'' framework. The code presented there handles almost
+everything necessary for CGI requests.
+One thing it doesn't do is handle encoded characters in the requests.
+For example, an @samp{&} is encoded as a percent sign followed by
+the hexadecimal value: @samp{%26}. These encoded values should be
+decoded.
+Following is a simple library to perform these tasks.
+This code is used for all web server examples
+used throughout the rest of this @value{DOCUMENT}.
+If you want to use it for your own web server, store the source code
+into a file named @file{inetlib.awk}. Then you can include
+these functions into your code by placing the following statement
+into your program
+(on the first line of your script):
+
+@example
+@@include inetlib.awk
+@end example
+
+@noindent
+But beware, this mechanism is
+only possible if you invoke your web server script with @command{igawk}
+instead of the usual @command{awk} or @command{gawk}.
+Here is the code:
+
+@example
+@c file eg/network/coreserv.awk
+# CGI Library and core of a web server
+@c endfile
+@ignore
+@c file eg/network/coreserv.awk
+#
+# Juergen Kahrs, Juergen.Kahrs@@vr-web.de
+# with Arnold Robbins, arnold@@gnu.org
+# September 2000
+
+@c endfile
+@end ignore
+@c file eg/network/coreserv.awk
+# Global arrays
+# GETARG --- arguments to CGI GET command
+# MENU --- menu items (path names)
+# PARAM --- parameters of form x=y
+
+# Optional variable MyHost contains host address
+# Optional variable MyPort contains port number
+# Needs TopHeader, TopDoc, TopFooter
+# Sets MyPrefix, HttpService, Status, Reason
+
+BEGIN @{
+ if (MyHost == "") @{
+ "uname -n" | getline MyHost
+ close("uname -n")
+ @}
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ MyPrefix = "http://" MyHost ":" MyPort
+ SetUpServer()
+ while ("awk" != "complex") @{
+ # header lines are terminated this way
+ RS = ORS = "\r\n"
+ Status = 200 # this means OK
+ Reason = "OK"
+ Header = TopHeader
+ Document = TopDoc
+ Footer = TopFooter
+ if (GETARG["Method"] == "GET") @{
+ HandleGET()
+ @} else if (GETARG["Method"] == "HEAD") @{
+ # not yet implemented
+ @} else if (GETARG["Method"] != "") @{
+ print "bad method", GETARG["Method"]
+ @}
+ Prompt = Header Document Footer
+ print "HTTP/1.0", Status, Reason |& HttpService
+ print "Connection: Close" |& HttpService
+ print "Pragma: no-cache" |& HttpService
+ len = length(Prompt) + length(ORS)
+ print "Content-length:", len |& HttpService
+ print ORS Prompt |& HttpService
+ # ignore all the header lines
+ while ((HttpService |& getline) > 0)
+ continue
+ # stop talking to this client
+ close(HttpService)
+ # wait for new client request
+ HttpService |& getline
+ # do some logging
+ print systime(), strftime(), $0
+ CGI_setup($1, $2, $3)
+ @}
+@}
+
+function CGI_setup( method, uri, version, i)
+@{
+ delete GETARG
+ delete MENU
+ delete PARAM
+ GETARG["Method"] = method
+ GETARG["URI"] = uri
+ GETARG["Version"] = version
+
+ i = index(uri, "?")
+ if (i > 0) @{ # is there a "?" indicating a CGI request?
+ split(substr(uri, 1, i-1), MENU, "[/:]")
+ split(substr(uri, i+1), PARAM, "&")
+ for (i in PARAM) @{
+ PARAM[i] = _CGI_decode(PARAM[i])
+ j = index(PARAM[i], "=")
+ GETARG[substr(PARAM[i], 1, j-1)] = \
+ substr(PARAM[i], j+1)
+ @}
+ @} else @{ # there is no "?", no need for splitting PARAMs
+ split(uri, MENU, "[/:]")
+ @}
+ for (i in MENU) # decode characters in path
+ if (i > 4) # but not those in host name
+ MENU[i] = _CGI_decode(MENU[i])
+@}
+@c endfile
+@end example
+
+This isolates details in a single function, @code{CGI_setup}.
+Decoding of encoded characters is pushed off to a helper function,
+@code{_CGI_decode}. The use of the leading underscore (@samp{_}) in
+the function name is intended to indicate that it is an ``internal''
+function, although there is nothing to enforce this:
+
+@example
+@c file eg/network/coreserv.awk
+function _CGI_decode(str, hexdigs, i, pre, code1, code2,
+ val, result)
+@{
+ hexdigs = "123456789abcdef"
+
+ i = index(str, "%")
+ if (i == 0) # no work to do
+ return str
+
+ do @{
+ pre = substr(str, 1, i-1) # part before %xx
+ code1 = substr(str, i+1, 1) # first hex digit
+ code2 = substr(str, i+2, 1) # second hex digit
+ str = substr(str, i+3) # rest of string
+
+ code1 = tolower(code1)
+ code2 = tolower(code2)
+ val = index(hexdigs, code1) * 16 \
+ + index(hexdigs, code2)
+
+ result = result pre sprintf("%c", val)
+ i = index(str, "%")
+ @} while (i != 0)
+ if (length(str) > 0)
+ result = result str
+ return result
+@}
+@c endfile
+@end example
+
+This works by splitting the string apart around an encoded character.
+The two digits are converted to lowercase characters and looked up in a string
+of hex digits. Note that @code{0} is not in the string on purpose;
+@code{index} returns zero when it's not found, automatically giving
+the correct value! Once the hexadecimal value is converted from
+characters in a string into a numerical value, @code{sprintf}
+converts the value back into a real character.
+The following is a simple test harness for the above functions:
+
+@example
+@c file eg/network/testserv.awk
+BEGIN @{
+ CGI_setup("GET",
+ "http://www.gnu.org/cgi-bin/foo?p1=stuff&p2=stuff%26junk" \
+ "&percent=a %25 sign",
+ "1.0")
+ for (i in MENU)
+ printf "MENU[\"%s\"] = %s\n", i, MENU[i]
+ for (i in PARAM)
+ printf "PARAM[\"%s\"] = %s\n", i, PARAM[i]
+ for (i in GETARG)
+ printf "GETARG[\"%s\"] = %s\n", i, GETARG[i]
+@}
+@c endfile
+@end example
+
+And this is the result when we run it:
+
+@c artificial line wrap in last output line
+@example
+$ gawk -f testserv.awk
+@print{} MENU["4"] = www.gnu.org
+@print{} MENU["5"] = cgi-bin
+@print{} MENU["6"] = foo
+@print{} MENU["1"] = http
+@print{} MENU["2"] =
+@print{} MENU["3"] =
+@print{} PARAM["1"] = p1=stuff
+@print{} PARAM["2"] = p2=stuff&junk
+@print{} PARAM["3"] = percent=a % sign
+@print{} GETARG["p1"] = stuff
+@print{} GETARG["percent"] = a % sign
+@print{} GETARG["p2"] = stuff&junk
+@print{} GETARG["Method"] = GET
+@print{} GETARG["Version"] = 1.0
+@print{} GETARG["URI"] = http://www.gnu.org/cgi-bin/foo?p1=stuff&
+p2=stuff%26junk&percent=a %25 sign
+@end example
+
+@node Simple Server, Caveats, Interacting Service, Using Networking
+@section A Simple Web Server
+@c STARTOFRANGE webserx
+@cindex web servers
+@c STARTOFRANGE serweb
+@cindex servers, web
+In the preceding @value{SECTION}, we built the core logic for event-driven GUIs.
+In this @value{SECTION}, we finally extend the core to a real application.
+No one would actually write a commercial web server in @command{gawk}, but
+it is instructive to see that it is feasible in principle.
+
+@cindex ELIZA program
+@cindex Weizenbaum, Joseph
+The application is ELIZA, the famous program by Joseph Weizenbaum that
+mimics the behavior of a professional psychotherapist when talking to you.
+Weizenbaum would certainly object to this description, but this is part of
+the legend around ELIZA.
+Take the site-independent core logic and append the following code:
+
+@example
+@c file eg/network/eliza.awk
+function SetUpServer() @{
+ SetUpEliza()
+ TopHeader = \
+ "<HTML><title>An HTTP-based System with GAWK</title>\
+ <HEAD><META HTTP-EQUIV=\"Content-Type\"\
+ CONTENT=\"text/html; charset=iso-8859-1\"></HEAD>\
+ <BODY BGCOLOR=\"#ffffff\" TEXT=\"#000000\"\
+ LINK=\"#0000ff\" VLINK=\"#0000ff\"\
+ ALINK=\"#0000ff\"> <A NAME=\"top\">"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI>\
+ <A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ </LI><LI>\
+ <A HREF=" MyPrefix "/AboutELIZA>About Eliza</A></LI>\
+ <LI>\
+ <A HREF=" MyPrefix \
+ "/StartELIZA>Start talking to Eliza</A></LI></UL>"
+ TopFooter = "</BODY></HTML>"
+@}
+@c endfile
+@end example
+
+@code{SetUpServer} is similar to the previous example,
+except for calling another function, @code{SetUpEliza}.
+This approach can be used to implement other kinds of servers.
+The only changes needed to do so are hidden in the functions
+@code{SetUpServer} and @code{HandleGET}. Perhaps it might be necessary to
+implement other HTTP methods.
+The @command{igawk} program that comes with @command{gawk}
+may be useful for this process.
+
+When extending this example to a complete application, the first
+thing to do is to implement the function @code{SetUpServer} to
+initialize the HTML pages and some variables. These initializations
+determine the way your HTML pages look (colors, titles, menu
+items, etc.).
+
+The function @code{HandleGET} is a nested case selection that decides
+which page the user wants to see next. Each nesting level refers to a menu
+level of the GUI. Each case implements a certain action of the menu. On the
+deepest level of case selection, the handler essentially knows what the
+user wants and stores the answer into the variable that holds the HTML
+page contents:
+
+@smallexample
+@c file eg/network/eliza.awk
+function HandleGET() @{
+ # A real HTTP server would treat some parts of the URI as a file name.
+ # We take parts of the URI as menu choices and go on accordingly.
+ if(MENU[2] == "AboutServer") @{
+ Document = "This is not a CGI script.\
+ This is an httpd, an HTML file, and a CGI script all \
+ in one GAWK script. It needs no separate www-server, \
+ no installation, and no root privileges.\
+ <p>To run it, do this:</p><ul>\
+ <li> start this script with \"gawk -f httpserver.awk\",</li>\
+ <li> and on the same host let your www browser open location\
+ \"http://localhost:8080\"</li>\
+ </ul>\<p>\ Details of HTTP come from:</p><ul>\
+ <li>Hethmon: Illustrated Guide to HTTP</p>\
+ <li>RFC 2068</li></ul><p>JK 14.9.1997</p>"
+ @} else if (MENU[2] == "AboutELIZA") @{
+ Document = "This is an implementation of the famous ELIZA\
+ program by Joseph Weizenbaum. It is written in GAWK and\
+/bin/sh: expad: command not found
+ @} else if (MENU[2] == "StartELIZA") @{
+ gsub(/\+/, " ", GETARG["YouSay"])
+ # Here we also have to substitute coded special characters
+ Document = "<form method=GET>" \
+ "<h3>" ElizaSays(GETARG["YouSay"]) "</h3>\
+ <p><input type=text name=YouSay value=\"\" size=60>\
+ <br><input type=submit value=\"Tell her about it\"></p></form>"
+ @}
+@}
+@c endfile
+@end smallexample
+
+Now we are down to the heart of ELIZA, so you can see how it works.
+Initially the user does not say anything; then ELIZA resets its money
+counter and asks the user to tell what comes to mind open heartedly.
+The subsequent answers are converted to uppercase characters and stored for
+later comparison. ELIZA presents the bill when being confronted with
+a sentence that contains the phrase ``shut up.'' Otherwise, it looks for
+keywords in the sentence, conjugates the rest of the sentence, remembers
+the keyword for later use, and finally selects an answer from the set of
+possible answers:
+
+@smallexample
+@c file eg/network/eliza.awk
+function ElizaSays(YouSay) @{
+ if (YouSay == "") @{
+ cost = 0
+ answer = "HI, IM ELIZA, TELL ME YOUR PROBLEM"
+ @} else @{
+ q = toupper(YouSay)
+ gsub("'", "", q)
+ if(q == qold) @{
+ answer = "PLEASE DONT REPEAT YOURSELF !"
+ @} else @{
+ if (index(q, "SHUT UP") > 0) @{
+ answer = "WELL, PLEASE PAY YOUR BILL. ITS EXACTLY ... $"\
+ int(100*rand()+30+cost/100)
+ @} else @{
+ qold = q
+ w = "-" # no keyword recognized yet
+ for (i in k) @{ # search for keywords
+ if (index(q, i) > 0) @{
+ w = i
+ break
+ @}
+ @}
+ if (w == "-") @{ # no keyword, take old subject
+ w = wold
+ subj = subjold
+ @} else @{ # find subject
+ subj = substr(q, index(q, w) + length(w)+1)
+ wold = w
+ subjold = subj # remember keyword and subject
+ @}
+ for (i in conj)
+ gsub(i, conj[i], q) # conjugation
+ # from all answers to this keyword, select one randomly
+ answer = r[indices[int(split(k[w], indices) * rand()) + 1]]
+ # insert subject into answer
+ gsub("_", subj, answer)
+ @}
+ @}
+ @}
+ cost += length(answer) # for later payment : 1 cent per character
+ return answer
+@}
+@c endfile
+@end smallexample
+
+In the long but simple function @code{SetUpEliza}, you can see tables
+for conjugation, keywords, and answers.@footnote{The version shown
+here is abbreviated. The full version comes with the @command{gawk}
+distribution.} The associative array @code{k}
+contains indices into the array of answers @code{r}. To choose an
+answer, ELIZA just picks an index randomly:
+
+@example
+@c file eg/network/eliza.awk
+function SetUpEliza() @{
+ srand()
+ wold = "-"
+ subjold = " "
+
+ # table for conjugation
+ conj[" ARE " ] = " AM "
+ conj["WERE " ] = "WAS "
+ conj[" YOU " ] = " I "
+ conj["YOUR " ] = "MY "
+ conj[" IVE " ] =\
+ conj[" I HAVE " ] = " YOU HAVE "
+ conj[" YOUVE " ] =\
+ conj[" YOU HAVE "] = " I HAVE "
+ conj[" IM " ] =\
+ conj[" I AM " ] = " YOU ARE "
+ conj[" YOURE " ] =\
+ conj[" YOU ARE " ] = " I AM "
+
+ # table of all answers
+ r[1] = "DONT YOU BELIEVE THAT I CAN _"
+ r[2] = "PERHAPS YOU WOULD LIKE TO BE ABLE TO _ ?"
+@c endfile
+ @dots{}
+@end example
+@ignore
+@c file eg/network/eliza.awk
+ r[3] = "YOU WANT ME TO BE ABLE TO _ ?"
+ r[4] = "PERHAPS YOU DONT WANT TO _ "
+ r[5] = "DO YOU WANT TO BE ABLE TO _ ?"
+ r[6] = "WHAT MAKES YOU THINK I AM _ ?"
+ r[7] = "DOES IT PLEASE YOU TO BELIEVE I AM _ ?"
+ r[8] = "PERHAPS YOU WOULD LIKE TO BE _ ?"
+ r[9] = "DO YOU SOMETIMES WISH YOU WERE _ ?"
+ r[10] = "DONT YOU REALLY _ ?"
+ r[11] = "WHY DONT YOU _ ?"
+ r[12] = "DO YOU WISH TO BE ABLE TO _ ?"
+ r[13] = "DOES THAT TROUBLE YOU ?"
+ r[14] = "TELL ME MORE ABOUT SUCH FEELINGS"
+ r[15] = "DO YOU OFTEN FEEL _ ?"
+ r[16] = "DO YOU ENJOY FEELING _ ?"
+ r[17] = "DO YOU REALLY BELIEVE I DONT _ ?"
+ r[18] = "PERHAPS IN GOOD TIME I WILL _ "
+ r[19] = "DO YOU WANT ME TO _ ?"
+ r[20] = "DO YOU THINK YOU SHOULD BE ABLE TO _ ?"
+ r[21] = "WHY CANT YOU _ ?"
+ r[22] = "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM _ ?"
+ r[23] = "WOULD YOU PREFER IF I WERE NOT _ ?"
+ r[24] = "PERHAPS IN YOUR FANTASIES I AM _ "
+ r[25] = "HOW DO YOU KNOW YOU CANT _ ?"
+ r[26] = "HAVE YOU TRIED ?"
+ r[27] = "PERHAPS YOU CAN NOW _ "
+ r[28] = "DID YOU COME TO ME BECAUSE YOU ARE _ ?"
+ r[29] = "HOW LONG HAVE YOU BEEN _ ?"
+ r[30] = "DO YOU BELIEVE ITS NORMAL TO BE _ ?"
+ r[31] = "DO YOU ENJOY BEING _ ?"
+ r[32] = "WE WERE DISCUSSING YOU -- NOT ME"
+ r[33] = "Oh, I _"
+ r[34] = "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU ?"
+ r[35] = "WHAT WOULD IT MEAN TO YOU, IF YOU GOT _ ?"
+ r[36] = "WHY DO YOU WANT _ ?"
+ r[37] = "SUPPOSE YOU SOON GOT _"
+ r[38] = "WHAT IF YOU NEVER GOT _ ?"
+ r[39] = "I SOMETIMES ALSO WANT _"
+ r[40] = "WHY DO YOU ASK ?"
+ r[41] = "DOES THAT QUESTION INTEREST YOU ?"
+ r[42] = "WHAT ANSWER WOULD PLEASE YOU THE MOST ?"
+ r[43] = "WHAT DO YOU THINK ?"
+ r[44] = "ARE SUCH QUESTIONS IN YOUR MIND OFTEN ?"
+ r[45] = "WHAT IS IT THAT YOU REALLY WANT TO KNOW ?"
+ r[46] = "HAVE YOU ASKED ANYONE ELSE ?"
+ r[47] = "HAVE YOU ASKED SUCH QUESTIONS BEFORE ?"
+ r[48] = "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT ?"
+ r[49] = "NAMES DON'T INTEREST ME"
+ r[50] = "I DONT CARE ABOUT NAMES -- PLEASE GO ON"
+ r[51] = "IS THAT THE REAL REASON ?"
+ r[52] = "DONT ANY OTHER REASONS COME TO MIND ?"
+ r[53] = "DOES THAT REASON EXPLAIN ANYTHING ELSE ?"
+ r[54] = "WHAT OTHER REASONS MIGHT THERE BE ?"
+ r[55] = "PLEASE DON'T APOLOGIZE !"
+ r[56] = "APOLOGIES ARE NOT NECESSARY"
+ r[57] = "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE ?"
+ r[58] = "DON'T BE SO DEFENSIVE"
+ r[59] = "WHAT DOES THAT DREAM SUGGEST TO YOU ?"
+ r[60] = "DO YOU DREAM OFTEN ?"
+ r[61] = "WHAT PERSONS APPEAR IN YOUR DREAMS ?"
+ r[62] = "ARE YOU DISTURBED BY YOUR DREAMS ?"
+ r[63] = "HOW DO YOU DO ... PLEASE STATE YOUR PROBLEM"
+ r[64] = "YOU DON'T SEEM QUITE CERTAIN"
+ r[65] = "WHY THE UNCERTAIN TONE ?"
+ r[66] = "CAN'T YOU BE MORE POSITIVE ?"
+ r[67] = "YOU AREN'T SURE ?"
+ r[68] = "DON'T YOU KNOW ?"
+ r[69] = "WHY NO _ ?"
+ r[70] = "DON'T SAY NO, IT'S ALWAYS SO NEGATIVE"
+ r[71] = "WHY NOT ?"
+ r[72] = "ARE YOU SURE ?"
+ r[73] = "WHY NO ?"
+ r[74] = "WHY ARE YOU CONCERNED ABOUT MY _ ?"
+ r[75] = "WHAT ABOUT YOUR OWN _ ?"
+ r[76] = "CAN'T YOU THINK ABOUT A SPECIFIC EXAMPLE ?"
+ r[77] = "WHEN ?"
+ r[78] = "WHAT ARE YOU THINKING OF ?"
+ r[79] = "REALLY, ALWAYS ?"
+ r[80] = "DO YOU REALLY THINK SO ?"
+ r[81] = "BUT YOU ARE NOT SURE YOU _ "
+ r[82] = "DO YOU DOUBT YOU _ ?"
+ r[83] = "IN WHAT WAY ?"
+ r[84] = "WHAT RESEMBLANCE DO YOU SEE ?"
+ r[85] = "WHAT DOES THE SIMILARITY SUGGEST TO YOU ?"
+ r[86] = "WHAT OTHER CONNECTION DO YOU SEE ?"
+ r[87] = "COULD THERE REALLY BE SOME CONNECTIONS ?"
+ r[88] = "HOW ?"
+ r[89] = "YOU SEEM QUITE POSITIVE"
+ r[90] = "ARE YOU SURE ?"
+ r[91] = "I SEE"
+ r[92] = "I UNDERSTAND"
+ r[93] = "WHY DO YOU BRING UP THE TOPIC OF FRIENDS ?"
+ r[94] = "DO YOUR FRIENDS WORRY YOU ?"
+ r[95] = "DO YOUR FRIENDS PICK ON YOU ?"
+ r[96] = "ARE YOU SURE YOU HAVE ANY FRIENDS ?"
+ r[97] = "DO YOU IMPOSE ON YOUR FRIENDS ?"
+ r[98] = "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU"
+ r[99] = "DO COMPUTERS WORRY YOU ?"
+ r[100] = "ARE YOU TALKING ABOUT ME IN PARTICULAR ?"
+ r[101] = "ARE YOU FRIGHTENED BY MACHINES ?"
+ r[102] = "WHY DO YOU MENTION COMPUTERS ?"
+ r[103] = "WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEMS ?"
+ r[104] = "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE ?"
+ r[105] = "WHAT IS IT ABOUT MACHINES THAT WORRIES YOU ?"
+ r[106] = "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS ?"
+ r[107] = "WHAT DOES THAT SUGGEST TO YOU ?"
+ r[108] = "I SEE"
+ r[109] = "IM NOT SURE I UNDERSTAND YOU FULLY"
+ r[110] = "COME COME ELUCIDATE YOUR THOUGHTS"
+ r[111] = "CAN YOU ELABORATE ON THAT ?"
+ r[112] = "THAT IS QUITE INTERESTING"
+ r[113] = "WHY DO YOU HAVE PROBLEMS WITH MONEY ?"
+ r[114] = "DO YOU THINK MONEY IS EVERYTHING ?"
+ r[115] = "ARE YOU SURE THAT MONEY IS THE PROBLEM ?"
+ r[116] = "I THINK WE WANT TO TALK ABOUT YOU, NOT ABOUT ME"
+ r[117] = "WHAT'S ABOUT ME ?"
+ r[118] = "WHY DO YOU ALWAYS BRING UP MY NAME ?"
+@c endfile
+@end ignore
+
+@example
+@c file eg/network/eliza.awk
+ # table for looking up answers that
+ # fit to a certain keyword
+ k["CAN YOU"] = "1 2 3"
+ k["CAN I"] = "4 5"
+ k["YOU ARE"] =\
+ k["YOURE"] = "6 7 8 9"
+@c endfile
+ @dots{}
+@end example
+@ignore
+@c file eg/network/eliza.awk
+ k["I DONT"] = "10 11 12 13"
+ k["I FEEL"] = "14 15 16"
+ k["WHY DONT YOU"] = "17 18 19"
+ k["WHY CANT I"] = "20 21"
+ k["ARE YOU"] = "22 23 24"
+ k["I CANT"] = "25 26 27"
+ k["I AM"] =\
+ k["IM "] = "28 29 30 31"
+ k["YOU "] = "32 33 34"
+ k["I WANT"] = "35 36 37 38 39"
+ k["WHAT"] =\
+ k["HOW"] =\
+ k["WHO"] =\
+ k["WHERE"] =\
+ k["WHEN"] =\
+ k["WHY"] = "40 41 42 43 44 45 46 47 48"
+ k["NAME"] = "49 50"
+ k["CAUSE"] = "51 52 53 54"
+ k["SORRY"] = "55 56 57 58"
+ k["DREAM"] = "59 60 61 62"
+ k["HELLO"] =\
+ k["HI "] = "63"
+ k["MAYBE"] = "64 65 66 67 68"
+ k[" NO "] = "69 70 71 72 73"
+ k["YOUR"] = "74 75"
+ k["ALWAYS"] = "76 77 78 79"
+ k["THINK"] = "80 81 82"
+ k["LIKE"] = "83 84 85 86 87 88 89"
+ k["YES"] = "90 91 92"
+ k["FRIEND"] = "93 94 95 96 97 98"
+ k["COMPUTER"] = "99 100 101 102 103 104 105"
+ k["-"] = "106 107 108 109 110 111 112"
+ k["MONEY"] = "113 114 115"
+ k["ELIZA"] = "116 117 118"
+@c endfile
+@end ignore
+@example
+@c file eg/network/eliza.awk
+@}
+@c endfile
+@end example
+
+@cindex Humphrys, Mark
+@cindex ELIZA program
+Some interesting remarks and details (including the original source code
+of ELIZA) are found on Mark Humphrys' home page. Yahoo! also has a
+page with a collection of ELIZA-like programs. Many of them are written
+in Java, some of them disclosing the Java source code, and a few even
+explain how to modify the Java source code.
+
+@node Caveats, Challenges, Simple Server, Using Networking
+@section Network Programming Caveats
+
+@cindex networks, @command{gawk} and, troubleshooting
+@cindex @command{gawk}, networking, troubleshooting
+@cindex troubleshooting, @command{gawk}, networks
+By now it should be clear
+that debugging a networked application is more
+complicated than debugging a single-process single-hosted application.
+The behavior of a networked application sometimes looks noncausal because
+it is not reproducible in a strong sense. Whether a network application
+works or not sometimes depends on the following:
+
+@itemize @bullet
+@item
+How crowded the underlying network is
+
+@item
+If the party at the other end is running or not
+
+@item
+The state of the party at the other end
+@end itemize
+
+@cindex troubleshooting, networks, timeouts
+The most difficult problems for a beginner arise from the hidden states of the
+underlying network. After closing a TCP connection, it's often necessary to wait
+a short while before reopening the connection. Even more difficult is the
+establishment of a connection that previously ended with a ``broken pipe.''
+Those connections have to ``time out'' for a minute or so
+before they can reopen.
+Check this with the command @samp{netstat -a}, which
+provides a list of still ``active'' connections.
+
+@node Challenges, , Caveats, Using Networking
+@section Where To Go From Here
+
+@cindex Loebner, Hugh
+@cindex contest
+Now, you have learned enough to build your own application. You could,
+for example, take part in the
+Loebner Contest
+to win $100,000. The Loebner Prize is the first formal instantiation of
+a Turing Test. Hugh Loebner agreed with The Cambridge Center for Behavioral
+Studies to underwrite a contest designed to implement the Turing Test.
+Dr.@: Loebner pledged a Grand Prize of $100,000 for the first computer whose
+responses were indistinguishable from a human's. Each year an annual prize
+of $2000 and a bronze medal is awarded to the @emph{most} human computer.
+The winner of the annual contest is the best entry relative to other entries
+that year, irrespective of how good it is in an absolute sense. Here is
+an example of a conversation with the winning program of 1997:
+
+@smallexample
+(c)1997 Cambridge Center For Behavioral Studies all rights reserved [CONVERSE]
+[Intelligent Research Ltd.] Start at: [1997/04/29 08:59:40]
+PROGRAM[10:39:20]Hi, my name is Catherine, what's yours?
+JUDGE02[10:39:36]My name is Nathan.
+PROGRAM[10:39:37]Well, it's nice to meet you, Nathan.
+PROGRAM[10:39:45]Did you see that story on CNN last night about the lesbian
+PROGRAM[10:40:03]couple who came out at a White House party on Sunday?
+JUDGE02[10:40:45]No. I'm sorry I missed that. How did the Prez take it?
+PROGRAM[10:40:47]Ellen Degeneres was one of them - she was kissing her lover
+PROGRAM[10:41:08]in front of Bill Clinton. Do you think he was very
+PROGRAM[10:41:21]embarrassed?
+JUDGE02[10:41:37]You tell me. I didn't see it.
+PROGRAM[10:41:38]Are you still a Friend of Bill Clinton?
+JUDGE02[10:42:22]Yes. I would like to talk about something else. Do you know anything about sculpture.
+PROGRAM[10:42:24]Well, I suppose he's doing his best like most of us, but he
+PROGRAM[10:42:35]does seem to attract an UNUSUAL amount of bad publicity,
+PROGRAM[10:42:51]wouldnt you say--can it all be bad luck?
+JUDGE02[10:43:20]I asked you if you knew anything about sculpture.
+PROGRAM[10:43:21]OK, but what happens now--does it all drift on, with
+PROGRAM[10:43:36]everyone waiting to see how much his friends have said about
+PROGRAM[10:43:47]him under threat of lots and lots of jail-or will something
+PROGRAM[10:44:01]dramatic actually happen?
+JUDGE02[10:44:19]Do you know what sculpture is?
+PROGRAM[10:44:20]Well, youre more a fan of his than I am I guess---though I
+PROGRAM[10:44:34]cant SWEAR what Id have done in that locked hotel room, I
+PROGRAM[10:44:51]must say.
+JUDGE02[10:45:26]Have you ever been to the Salmagundi Club?
+PROGRAM[10:45:29]Never. to go back to the original discussion Time to get
+PROGRAM[10:45:43]off this one I think and onto something more down to earth!
+JUDGE02[10:46:20]What is more down to earth than art?
+PROGRAM[10:46:21]I don't know what -- to be honest. -
+PROGRAM[10:46:30]I suppose it depends on where you're coming from, but as the
+PROGRAM[10:46:46]song goes in My Fair Lady, "Why can't a woman be more like a
+PROGRAM[10:47:03]man? "
+JUDGE02[10:47:52]I liked that song but I prefer "Why can't children be more like we are"
+JUDGE02[10:48:10]from another play the name of which I cannot remember.
+PROGRAM[10:48:12]What, if anything, do you enjoy about being a man?
+JUDGE02[10:49:01]I would enjoy all aspects of life no matter what my gender.
+PROGRAM[10:49:02]Do you think of yourself as being attractive?
+@end smallexample
+
+@cindex Clinton, Bill
+This program insists on always speaking about the same story around Bill
+Clinton. You see, even a program with a rather narrow mind can behave so
+much like a human being that it can win this prize. It is quite common to
+let these programs talk to each other via network connections. But during the
+competition itself, the program and its computer have to be present at the
+place the competition is held. We all would love to see a @command{gawk}
+program win in such an event. Maybe it is up to you to accomplish this?
+
+Some other ideas for useful networked applications:
+@itemize @bullet
+@item
+Read the file @file{doc/awkforai.txt} in the @command{gawk} distribution.
+It was written by Ronald P.@: Loui (Associate Professor of
+Computer Science, at Washington University in St. Louis,
+@email{loui@@ai.wustl.edu}) and summarizes why
+he teaches @command{gawk} to students of Artificial Intelligence. Here are
+some passages from the text:
+
+@cindex AI
+@cindex PROLOG
+@cindex Loui, Ronald
+@cindex agent
+@quotation
+The GAWK manual can
+be consumed in a single lab session and the language can be mastered by
+the next morning by the average student. GAWK's automatic
+initialization, implicit coercion, I/O support and lack of pointers
+forgive many of the mistakes that young programmers are likely to make.
+Those who have seen C but not mastered it are happy to see that GAWK
+retains some of the same sensibilities while adding what must be
+regarded as spoonsful of syntactic sugar.@*
+@dots{}@*
+@cindex robot
+There are further simple answers. Probably the best is the fact that
+increasingly, undergraduate AI programming is involving the Web. Oren
+Etzioni (University of Washington, Seattle) has for a while been arguing
+that the ``softbot'' is replacing the mechanical engineers' robot as the
+most glamorous AI testbed. If the artifact whose behavior needs to be
+controlled in an intelligent way is the software agent, then a language
+that is well-suited to controlling the software environment is the
+appropriate language. That would imply a scripting language. If the
+robot is KAREL, then the right language is ``turn left; turn right.'' If
+the robot is Netscape, then the right language is something that can
+generate @samp{netscape -remote 'openURL(http://cs.wustl.edu/~loui)'} with
+elan.@*
+@dots{}@*
+AI programming requires high-level thinking. There have always been a few
+gifted programmers who can write high-level programs in assembly language.
+Most however need the ambient abstraction to have a higher floor.@*
+@dots{}@*
+Second, inference is merely the expansion of notation. No matter whether
+the logic that underlies an AI program is fuzzy, probabilistic, deontic,
+defeasible, or deductive, the logic merely defines how strings can be
+transformed into other strings. A language that provides the best
+support for string processing in the end provides the best support for
+logic, for the exploration of various logics, and for most forms of
+symbolic processing that AI might choose to call ``reasoning'' instead of
+``logic.'' The implication is that PROLOG, which saves the AI programmer
+from having to write a unifier, saves perhaps two dozen lines of GAWK
+code at the expense of strongly biasing the logic and representational
+expressiveness of any approach.
+@end quotation
+
+Now that @command{gawk} itself can connect to the Internet, it should be obvious
+that it is suitable for writing intelligent web agents.
+
+@item
+@command{awk} is strong at pattern recognition and string processing.
+So, it is well suited to the classic problem of language translation.
+A first try could be a program that knows the 100 most frequent English
+words and their counterparts in German or French. The service could be
+implemented by regularly reading email with the program above, replacing
+each word by its translation and sending the translation back via SMTP.
+Users would send English email to their translation service and get
+back a translated email message in return. As soon as this works,
+more effort can be spent on a real translation program.
+
+@item
+Another dialogue-oriented application (on the verge
+of ridicule) is the email ``support service.'' Troubled customers write an
+email to an automatic @command{gawk} service that reads the email. It looks
+for keywords in the mail and assembles a reply email accordingly. By carefully
+investigating the email header, and repeating these keywords through the
+reply email, it is rather simple to give the customer a feeling that
+someone cares. Ideally, such a service would search a database of previous
+cases for solutions. If none exists, the database could, for example, consist
+of all the newsgroups, mailing lists and FAQs on the Internet.
+@end itemize
+
+@node Some Applications and Techniques, Links, Using Networking, Top
+@comment node-name, next, previous, up
+
+@chapter Some Applications and Techniques
+In this @value{CHAPTER}, we look at a number of self-contained
+scripts, with an emphasis on concise networking. Along the way, we
+work towards creating building blocks that encapsulate often needed
+functions of the networking world, show new techniques that
+broaden the scope of problems that can be solved with @command{gawk}, and
+explore leading edge technology that may shape the future of networking.
+
+We often refer to the site-independent core of the server that
+we built in
+@ref{Simple Server, ,A Simple Web Server}.
+When building new and nontrivial servers, we
+always copy this building block and append new instances of the two
+functions @code{SetUpServer} and @code{HandleGET}.
+
+This makes a lot of sense, since
+this scheme of event-driven
+execution provides @command{gawk} with an interface to the most widely
+accepted standard for GUIs: the web browser. Now, @command{gawk} can rival even
+Tcl/Tk.
+
+@cindex Tcl/Tk, @command{gawk} and
+Tcl and @command{gawk} have much in common. Both are simple scripting languages
+that allow us to quickly solve problems with short programs. But Tcl has Tk
+on top of it, and @command{gawk} had nothing comparable up to now. While Tcl
+needs a large and ever-changing library (Tk, which was bound to the X Window
+System until recently), @command{gawk} needs just the networking interface
+and some kind of browser on the client's side. Besides better portability,
+the most important advantage of this approach (embracing well-established
+standards such HTTP and HTML) is that @emph{we do not need to change the
+language}. We let others do the work of fighting over protocols and standards.
+We can use HTML, JavaScript, VRML, or whatever else comes along to do our work.
+
+@menu
+* PANIC:: An Emergency Web Server.
+* GETURL:: Retrieving Web Pages.
+* REMCONF:: Remote Configuration Of Embedded Systems.
+* URLCHK:: Look For Changed Web Pages.
+* WEBGRAB:: Extract Links From A Page.
+* STATIST:: Graphing A Statistical Distribution.
+* MAZE:: Walking Through A Maze In Virtual Reality.
+* MOBAGWHO:: A Simple Mobile Agent.
+* STOXPRED:: Stock Market Prediction As A Service.
+* PROTBASE:: Searching Through A Protein Database.
+@end menu
+
+@node PANIC, GETURL, Some Applications and Techniques, Some Applications and Techniques
+@section PANIC: An Emergency Web Server
+@cindex PANIC program
+@cindex networks, See Also web pages
+@cindex web service
+At first glance, the @code{"Hello, world"} example in
+@ref{Primitive Service, ,A Primitive Web Service},
+seems useless. By adding just a few lines, we can turn it into something useful.
+
+The PANIC program tells everyone who connects that the local
+site is not working. When a web server breaks down, it makes a difference
+if customers get a strange ``network unreachable'' message, or a short message
+telling them that the server has a problem. In such an emergency,
+the hard disk and everything on it (including the regular web service) may
+be unavailable. Rebooting the web server off a diskette makes sense in this
+setting.
+
+To use the PANIC program as an emergency web server, all you need are the
+@command{gawk} executable and the program below on a diskette. By default,
+it connects to port 8080. A different value may be supplied on the
+command line:
+
+@example
+@c file eg/network/panic.awk
+BEGIN @{
+ RS = ORS = "\r\n"
+ if (MyPort == 0) MyPort = 8080
+ HttpService = "/inet/tcp/" MyPort "/0/0"
+ Hello = "<HTML><HEAD><TITLE>Out Of Service</TITLE>" \
+ "</HEAD><BODY><H1>" \
+ "This site is temporarily out of service." \
+ "</H1></BODY></HTML>"
+ Len = length(Hello) + length(ORS)
+ while ("awk" != "complex") @{
+ print "HTTP/1.0 200 OK" |& HttpService
+ print "Content-Length: " Len ORS |& HttpService
+ print Hello |& HttpService
+ while ((HttpService |& getline) > 0)
+ continue;
+ close(HttpService)
+ @}
+@}
+@c endfile
+@end example
+
+@node GETURL, REMCONF, PANIC, Some Applications and Techniques
+@section GETURL: Retrieving Web Pages
+@cindex GETURL program
+@cindex web pages, retrieving
+GETURL is a versatile building block for shell scripts that need to retrieve
+files from the Internet. It takes a web address as a command-line parameter and
+tries to retrieve the contents of this address. The contents are printed
+to standard output, while the header is printed to @file{/dev/stderr}.
+A surrounding shell script
+could analyze the contents and extract the text or the links. An ASCII
+browser could be written around GETURL. But more interestingly, web robots are
+straightforward to write on top of GETURL. On the Internet, you can find
+several programs of the same name that do the same job. They are usually
+much more complex internally and at least 10 times longer.
+
+At first, GETURL checks if it was called with exactly one web address.
+Then, it checks if the user chose to use a special proxy server whose name
+is handed over in a variable. By default, it is assumed that the local
+machine serves as proxy. GETURL uses the @code{GET} method by default
+to access the web page. By handing over the name of a different method
+(such as @code{HEAD}), it is possible to choose a different behavior. With
+the @code{HEAD} method, the user does not receive the body of the page
+content, but does receive the header:
+
+@example
+@c file eg/network/geturl.awk
+BEGIN @{
+ if (ARGC != 2) @{
+ print "GETURL - retrieve Web page via HTTP 1.0"
+ print "IN:\n the URL as a command-line parameter"
+ print "PARAM(S):\n -v Proxy=MyProxy"
+ print "OUT:\n the page content on stdout"
+ print " the page header on stderr"
+ print "JK 16.05.1997"
+ print "ADR 13.08.2000"
+ exit
+ @}
+ URL = ARGV[1]; ARGV[1] = ""
+ if (Proxy == "") Proxy = "127.0.0.1"
+ if (ProxyPort == 0) ProxyPort = 80
+ if (Method == "") Method = "GET"
+ HttpService = "/inet/tcp/0/" Proxy "/" ProxyPort
+ ORS = RS = "\r\n\r\n"
+ print Method " " URL " HTTP/1.0" |& HttpService
+ HttpService |& getline Header
+ print Header > "/dev/stderr"
+ while ((HttpService |& getline) > 0)
+ printf "%s", $0
+ close(HttpService)
+@}
+@c endfile
+@end example
+
+This program can be changed as needed, but be careful with the last lines.
+Make sure transmission of binary data is not corrupted by additional line
+breaks. Even as it is now, the byte sequence @code{"\r\n\r\n"} would
+disappear if it were contained in binary data. Don't get caught in a
+trap when trying a quick fix on this one.
+
+@node REMCONF, URLCHK, GETURL, Some Applications and Techniques
+@section REMCONF: Remote Configuration of Embedded Systems
+@cindex REMCONF program
+@cindex Linux
+@cindex GNU/Linux
+@cindex Yahoo!
+Today, you often find powerful processors in embedded systems. Dedicated
+network routers and controllers for all kinds of machinery are examples
+of embedded systems. Processors like the Intel 80x86 or the AMD Elan are
+able to run multitasking operating systems, such as XINU or GNU/Linux
+in embedded PCs. These systems are small and usually do not have
+a keyboard or a display. Therefore it is difficult to set up their
+configuration. There are several widespread ways to set them up:
+
+@itemize @bullet
+@item
+DIP switches
+
+@item
+Read Only Memories such as EPROMs
+
+@item
+Serial lines or some kind of keyboard
+
+@item
+Network connections via @command{telnet} or SNMP
+
+@item
+HTTP connections with HTML GUIs
+@end itemize
+
+In this @value{SECTION}, we look at a solution that uses HTTP connections
+to control variables of an embedded system that are stored in a file.
+Since embedded systems have tight limits on resources like memory,
+it is difficult to employ advanced techniques such as SNMP and HTTP
+servers. @command{gawk} fits in quite nicely with its single executable
+which needs just a short script to start working.
+The following program stores the variables in a file, and a concurrent
+process in the embedded system may read the file. The program uses the
+site-independent part of the simple web server that we developed in
+@ref{Interacting Service, ,A Web Service with Interaction}.
+As mentioned there, all we have to do is to write two new procedures
+@code{SetUpServer} and @code{HandleGET}:
+
+@smallexample
+@c file eg/network/remconf.awk
+function SetUpServer() @{
+ TopHeader = "<HTML><title>Remote Configuration</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/ReadConfig>Read Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/CheckConfig>Check Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/ChangeConfig>Change Configuration</A></LI>\
+ <LI><A HREF=" MyPrefix "/SaveConfig>Save Configuration</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ if (ConfigFile == "") ConfigFile = "config.asc"
+@}
+@c endfile
+@end smallexample
+
+The function @code{SetUpServer} initializes the top level HTML texts
+as usual. It also initializes the name of the file that contains the
+configuration parameters and their values. In case the user supplies
+a name from the command line, that name is used. The file is expected to
+contain one parameter per line, with the name of the parameter in
+column one and the value in column two.
+
+The function @code{HandleGET} reflects the structure of the menu
+tree as usual. The first menu choice tells the user what this is all
+about. The second choice reads the configuration file line by line
+and stores the parameters and their values. Notice that the record
+separator for this file is @code{"\n"}, in contrast to the record separator
+for HTTP. The third menu choice builds an HTML table to show
+the contents of the configuration file just read. The fourth choice
+does the real work of changing parameters, and the last one just saves
+the configuration into a file:
+
+@smallexample
+@c file eg/network/remconf.awk
+function HandleGET() @{
+ if(MENU[2] == "AboutServer") @{
+ Document = "This is a GUI for remote configuration of an\
+ embedded system. It is is implemented as one GAWK script."
+ @} else if (MENU[2] == "ReadConfig") @{
+ RS = "\n"
+ while ((getline < ConfigFile) > 0)
+ config[$1] = $2;
+ close(ConfigFile)
+ RS = "\r\n"
+ Document = "Configuration has been read."
+ @} else if (MENU[2] == "CheckConfig") @{
+ Document = "<TABLE BORDER=1 CELLPADDING=5>"
+ for (i in config)
+ Document = Document "<TR><TD>" i "</TD>" \
+ "<TD>" config[i] "</TD></TR>"
+ Document = Document "</TABLE>"
+ @} else if (MENU[2] == "ChangeConfig") @{
+ if ("Param" in GETARG) @{ # any parameter to set?
+ if (GETARG["Param"] in config) @{ # is parameter valid?
+ config[GETARG["Param"]] = GETARG["Value"]
+ Document = (GETARG["Param"] " = " GETARG["Value"] ".")
+ @} else @{
+ Document = "Parameter <b>" GETARG["Param"] "</b> is invalid."
+ @}
+ @} else @{
+ Document = "<FORM method=GET><h4>Change one parameter</h4>\
+ <TABLE BORDER CELLPADDING=5>\
+ <TR><TD>Parameter</TD><TD>Value</TD></TR>\
+ <TR><TD><input type=text name=Param value=\"\" size=20></TD>\
+ <TD><input type=text name=Value value=\"\" size=40></TD>\
+ </TR></TABLE><input type=submit value=\"Set\"></FORM>"
+ @}
+ @} else if (MENU[2] == "SaveConfig") @{
+ for (i in config)
+ printf("%s %s\n", i, config[i]) > ConfigFile
+ close(ConfigFile)
+ Document = "Configuration has been saved."
+ @}
+@}
+@c endfile
+@end smallexample
+
+@cindex MiniSQL
+We could also view the configuration file as a database. From this
+point of view, the previous program acts like a primitive database server.
+Real SQL database systems also make a service available by providing
+a TCP port that clients can connect to. But the application level protocols
+they use are usually proprietary and also change from time to time.
+This is also true for the protocol that
+MiniSQL uses.
+
+@node URLCHK, WEBGRAB, REMCONF, Some Applications and Techniques
+@section URLCHK: Look for Changed Web Pages
+@cindex URLCHK program
+Most people who make heavy use of Internet resources have a large
+bookmark file with pointers to interesting web sites. It is impossible
+to regularly check by hand if any of these sites have changed. A program
+is needed to automatically look at the headers of web pages and tell
+which ones have changed. URLCHK does the comparison after using GETURL
+with the @code{HEAD} method to retrieve the header.
+
+Like GETURL, this program first checks that it is called with exactly
+one command-line parameter. URLCHK also takes the same command-line variables
+@code{Proxy} and @code{ProxyPort} as GETURL,
+because these variables are handed over to GETURL for each URL
+that gets checked. The one and only parameter is the name of a file that
+contains one line for each URL. In the first column, we find the URL, and
+the second and third columns hold the length of the URL's body when checked
+for the two last times. Now, we follow this plan:
+
+@enumerate
+@item
+Read the URLs from the file and remember their most recent lengths
+
+@item
+Delete the contents of the file
+
+@item
+For each URL, check its new length and write it into the file
+
+@item
+If the most recent and the new length differ, tell the user
+@end enumerate
+
+It may seem a bit peculiar to read the URLs from a file together
+with their two most recent lengths, but this approach has several
+advantages. You can call the program again and again with the same
+file. After running the program, you can regenerate the changed URLs
+by extracting those lines that differ in their second and third columns:
+
+@c inspired by URLCHK in iX 5/97 166.
+@smallexample
+@c file eg/network/urlchk.awk
+BEGIN @{
+ if (ARGC != 2) @{
+ print "URLCHK - check if URLs have changed"
+ print "IN:\n the file with URLs as a command-line parameter"
+ print " file contains URL, old length, new length"
+ print "PARAMS:\n -v Proxy=MyProxy -v ProxyPort=8080"
+ print "OUT:\n same as file with URLs"
+ print "JK 02.03.1998"
+ exit
+ @}
+ URLfile = ARGV[1]; ARGV[1] = ""
+ if (Proxy != "") Proxy = " -v Proxy=" Proxy
+ if (ProxyPort != "") ProxyPort = " -v ProxyPort=" ProxyPort
+ while ((getline < URLfile) > 0)
+ Length[$1] = $3 + 0
+ close(URLfile) # now, URLfile is read in and can be updated
+ GetHeader = "gawk " Proxy ProxyPort " -v Method=\"HEAD\" -f geturl.awk "
+ for (i in Length) @{
+ GetThisHeader = GetHeader i " 2>&1"
+ while ((GetThisHeader | getline) > 0)
+ if (toupper($0) ~ /CONTENT-LENGTH/) NewLength = $2 + 0
+ close(GetThisHeader)
+ print i, Length[i], NewLength > URLfile
+ if (Length[i] != NewLength) # report only changed URLs
+ print i, Length[i], NewLength
+ @}
+ close(URLfile)
+@}
+@c endfile
+@end smallexample
+
+Another thing that may look strange is the way GETURL is called.
+Before calling GETURL, we have to check if the proxy variables need
+to be passed on. If so, we prepare strings that will become part
+of the command line later. In @code{GetHeader}, we store these strings
+together with the longest part of the command line. Later, in the loop
+over the URLs, @code{GetHeader} is appended with the URL and a redirection
+operator to form the command that reads the URL's header over the Internet.
+GETURL always produces the headers over @file{/dev/stderr}. That is
+the reason why we need the redirection operator to have the header
+piped in.
+
+This program is not perfect because it assumes that changing URLs
+results in changed lengths, which is not necessarily true. A more
+advanced approach is to look at some other header line that
+holds time information. But, as always when things get a bit more
+complicated, this is left as an exercise to the reader.
+
+@node WEBGRAB, STATIST, URLCHK, Some Applications and Techniques
+@section WEBGRAB: Extract Links from a Page
+@cindex WEBGRAB program
+@c Inspired by iX 1/98 157.
+@cindex robot
+Sometimes it is necessary to extract links from web pages.
+Browsers do it, web robots do it, and sometimes even humans do it.
+Since we have a tool like GETURL at hand, we can solve this problem with
+some help from the Bourne shell:
+
+@example
+@c file eg/network/webgrab.awk
+BEGIN @{ RS = "http://[#%&\\+\\-\\./0-9\\:;\\?A-Z_a-z\\~]*" @}
+RT != "" @{
+ command = ("gawk -v Proxy=MyProxy -f geturl.awk " RT \
+ " > doc" NR ".html")
+ print command
+@}
+@c endfile
+@end example
+
+Notice that the regular expression for URLs is rather crude. A precise
+regular expression is much more complex. But this one works
+rather well. One problem is that it is unable to find internal links of
+an HTML document. Another problem is that
+@samp{ftp}, @samp{telnet}, @samp{news}, @samp{mailto}, and other kinds
+of links are missing in the regular expression.
+However, it is straightforward to add them, if doing so is necessary for other tasks.
+
+This program reads an HTML file and prints all the HTTP links that it finds.
+It relies on @command{gawk}'s ability to use regular expressions as record
+separators. With @code{RS} set to a regular expression that matches links,
+the second action is executed each time a non-empty link is found.
+We can find the matching link itself in @code{RT}.
+
+The action could use the @code{system} function to let another GETURL
+retrieve the page, but here we use a different approach.
+This simple program prints shell commands that can be piped into @command{sh}
+for execution. This way it is possible to first extract
+the links, wrap shell commands around them, and pipe all the shell commands
+into a file. After editing the file, execution of the file retrieves
+exactly those files that we really need. In case we do not want to edit,
+we can retrieve all the pages like this:
+
+@smallexample
+gawk -f geturl.awk http://www.suse.de | gawk -f webgrab.awk | sh
+@end smallexample
+
+@cindex Microsoft Windows
+After this, you will find the contents of all referenced documents in
+files named @file{doc*.html} even if they do not contain HTML code.
+The most annoying thing is that we always have to pass the proxy to
+GETURL. If you do not like to see the headers of the web pages
+appear on the screen, you can redirect them to @file{/dev/null}.
+Watching the headers appear can be quite interesting, because
+it reveals
+interesting details such as which web server the companies use.
+Now, it is clear how the clever marketing people
+use web robots to determine the
+market shares
+of Microsoft and Netscape in the web server market.
+
+Port 80 of any web server is like a small hole in a repellent firewall.
+After attaching a browser to port 80, we usually catch a glimpse
+of the bright side of the server (its home page). With a tool like GETURL
+at hand, we are able to discover some of the more concealed
+or even ``indecent'' services (i.e., lacking conformity to standards of quality).
+It can be exciting to see the fancy CGI scripts that lie
+there, revealing the inner workings of the server, ready to be called:
+
+@itemize @bullet
+@item
+With a command such as:
+
+@example
+gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/
+@end example
+
+some servers give you a directory listing of the CGI files.
+Knowing the names, you can try to call some of them and watch
+for useful results. Sometimes there are executables in such directories
+(such as Perl interpreters) that you may call remotely. If there are
+subdirectories with configuration data of the web server, this can also
+be quite interesting to read.
+
+@item
+@cindex apache
+The well-known Apache web server usually has its CGI files in the
+directory @file{/cgi-bin}. There you can often find the scripts
+@file{test-cgi} and @file{printenv}. Both tell you some things
+about the current connection and the installation of the web server.
+Just call:
+
+@smallexample
+gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/test-cgi
+gawk -f geturl.awk http://any.host.on.the.net/cgi-bin/printenv
+@end smallexample
+
+@item
+Sometimes it is even possible to retrieve system files like the web
+server's log file---possibly containing customer data---or even the file
+@file{/etc/passwd}.
+(We don't recommend this!)
+@end itemize
+
+@strong{Caution:}
+Although this may sound funny or simply irrelevant, we are talking about
+severe security holes. Try to explore your own system this way and make
+sure that none of the above reveals too much information about your system.
+
+@node STATIST, MAZE, WEBGRAB, Some Applications and Techniques
+@section STATIST: Graphing a Statistical Distribution
+@cindex STATIST program
+
+@cindex GNUPlot utility
+@cindex image format
+@cindex GIF image format
+@cindex PNG image format
+@cindex PS image format
+@cindex Boutell, Thomas
+@iftex
+@image{statist,3in}
+@end iftex
+In the HTTP server examples we've shown thus far, we never present an image
+to the browser and its user. Presenting images is one task. Generating
+images that reflect some user input and presenting these dynamically
+generated images is another. In this @value{SECTION}, we use GNUPlot
+for generating @file{.png}, @file{.ps}, or @file{.gif}
+files.@footnote{Due to licensing problems, the default
+installation of GNUPlot disables the generation of @file{.gif} files.
+If your installed version does not accept @samp{set term gif},
+just download and install the most recent version of GNUPlot and the
+@uref{http://www.boutell.com/gd/, GD library}
+by Thomas Boutell.
+Otherwise you still have the chance to generate some
+ASCII-art style images with GNUPlot by using @samp{set term dumb}.
+(We tried it and it worked.)}
+
+The program we develop takes the statistical parameters of two samples
+and computes the t-test statistics. As a result, we get the probabilities
+that the means and the variances of both samples are the same. In order to
+let the user check plausibility, the program presents an image of the
+distributions. The statistical computation follows
+@cite{Numerical Recipes in C: The Art of Scientific Computing}
+by William H.@: Press, Saul A.@: Teukolsky, William T.@: Vetterling, and Brian P. Flannery.
+Since @command{gawk} does not have a built-in function
+for the computation of the beta function, we use the @code{ibeta} function
+of GNUPlot. As a side effect, we learn how to use GNUPlot as a
+sophisticated calculator. The comparison of means is done as in @code{tutest},
+paragraph 14.2, page 613, and the comparison of variances is done as in @code{ftest},
+page 611 in @cite{Numerical Recipes}.
+@cindex Numerical Recipes
+
+As usual, we take the site-independent code for servers and append
+our own functions @code{SetUpServer} and @code{HandleGET}:
+
+@smallexample
+@c file eg/network/statist.awk
+function SetUpServer() @{
+ TopHeader = "<HTML><title>Statistics with GAWK</title>"
+ TopDoc = "<BODY>\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
+ <LI><A HREF=" MyPrefix "/EnterParameters>Enter Parameters</A></LI>\
+ </UL>"
+ TopFooter = "</BODY></HTML>"
+ GnuPlot = "gnuplot 2>&1"
+ m1=m2=0; v1=v2=1; n1=n2=10
+@}
+@c endfile
+@end smallexample
+
+Here, you see the menu structure that the user sees. Later, we
+will see how the program structure of the @code{HandleGET} function
+reflects the menu structure. What is missing here is the link for the
+image we generate. In an event-driven environment, request,
+generation, and delivery of images are separated.
+
+Notice the way we initialize the @code{GnuPlot} command string for
+the pipe. By default,
+GNUPlot outputs the generated image via standard output, as well as
+the results of @code{print}(ed) calculations via standard error.
+The redirection causes standard error to be mixed into standard
+output, enabling us to read results of calculations with @code{getline}.
+By initializing the statistical parameters with some meaningful
+defaults, we make sure the user gets an image the first time
+he uses the program.
+
+@cindex JavaScript
+Following is the rather long function @code{HandleGET}, which
+implements the contents of this service by reacting to the different
+kinds of requests from the browser. Before you start playing with
+this script, make sure that your browser supports JavaScript and that it also
+has this option switched on. The script uses a short snippet of
+JavaScript code for delayed opening of a window with an image.
+A more detailed explanation follows:
+
+@smallexample
+@c file eg/network/statist.awk
+function HandleGET() @{
+ if(MENU[2] == "AboutServer") @{
+ Document = "This is a GUI for a statistical computation.\
+ It compares means and variances of two distributions.\
+ It is implemented as one GAWK script and uses GNUPLOT."
+ @} else if (MENU[2] == "EnterParameters") @{
+ Document = ""
+ if ("m1" in GETARG) @{ # are there parameters to compare?
+ Document = Document "<SCRIPT LANGUAGE=\"JavaScript\">\
+ setTimeout(\"window.open(\\\"" MyPrefix "/Image" systime()\
+ "\\\",\\\"dist\\\", \\\"status=no\\\");\", 1000); </SCRIPT>"
+ m1 = GETARG["m1"]; v1 = GETARG["v1"]; n1 = GETARG["n1"]
+ m2 = GETARG["m2"]; v2 = GETARG["v2"]; n2 = GETARG["n2"]
+ t = (m1-m2)/sqrt(v1/n1+v2/n2)
+ df = (v1/n1+v2/n2)*(v1/n1+v2/n2)/((v1/n1)*(v1/n1)/(n1-1) \
+ + (v2/n2)*(v2/n2) /(n2-1))
+ if (v1>v2) @{
+ f = v1/v2
+ df1 = n1 - 1
+ df2 = n2 - 1
+ @} else @{
+ f = v2/v1
+ df1 = n2 - 1
+ df2 = n1 - 1
+ @}
+ print "pt=ibeta(" df/2 ",0.5," df/(df+t*t) ")" |& GnuPlot
+ print "pF=2.0*ibeta(" df2/2 "," df1/2 "," \
+ df2/(df2+df1*f) ")" |& GnuPlot
+ print "print pt, pF" |& GnuPlot
+ RS="\n"; GnuPlot |& getline; RS="\r\n" # $1 is pt, $2 is pF
+ print "invsqrt2pi=1.0/sqrt(2.0*pi)" |& GnuPlot
+ print "nd(x)=invsqrt2pi/sd*exp(-0.5*((x-mu)/sd)**2)" |& GnuPlot
+ print "set term png small color" |& GnuPlot
+ #print "set term postscript color" |& GnuPlot
+ #print "set term gif medium size 320,240" |& GnuPlot
+ print "set yrange[-0.3:]" |& GnuPlot
+ print "set label 'p(m1=m2) =" $1 "' at 0,-0.1 left" |& GnuPlot
+ print "set label 'p(v1=v2) =" $2 "' at 0,-0.2 left" |& GnuPlot
+ print "plot mu=" m1 ",sd=" sqrt(v1) ", nd(x) title 'sample 1',\
+ mu=" m2 ",sd=" sqrt(v2) ", nd(x) title 'sample 2'" |& GnuPlot
+ print "quit" |& GnuPlot
+ GnuPlot |& getline Image
+ while ((GnuPlot |& getline) > 0)
+ Image = Image RS $0
+ close(GnuPlot)
+ @}
+ Document = Document "\
+ <h3>Do these samples have the same Gaussian distribution?</h3>\
+ <FORM METHOD=GET> <TABLE BORDER CELLPADDING=5>\
+ <TR>\
+ <TD>1. Mean </TD>
+ <TD><input type=text name=m1 value=" m1 " size=8></TD>\
+ <TD>1. Variance</TD>
+ <TD><input type=text name=v1 value=" v1 " size=8></TD>\
+ <TD>1. Count </TD>
+ <TD><input type=text name=n1 value=" n1 " size=8></TD>\
+ </TR><TR>\
+ <TD>2. Mean </TD>
+ <TD><input type=text name=m2 value=" m2 " size=8></TD>\
+ <TD>2. Variance</TD>
+ <TD><input type=text name=v2 value=" v2 " size=8></TD>\
+ <TD>2. Count </TD>
+ <TD><input type=text name=n2 value=" n2 " size=8></TD>\
+ </TR> <input type=submit value=\"Compute\">\
+ </TABLE></FORM><BR>"
+ @} else if (MENU[2] ~ "Image") @{
+ Reason = "OK" ORS "Content-type: image/png"
+ #Reason = "OK" ORS "Content-type: application/x-postscript"
+ #Reason = "OK" ORS "Content-type: image/gif"
+ Header = Footer = ""
+ Document = Image
+ @}
+@}
+@c endfile
+@end smallexample
+
+@cindex PostScript
+As usual, we give a short description of the service in the first
+menu choice. The third menu choice shows us that generation and
+presentation of an image are two separate actions. While the latter
+takes place quite instantly in the third menu choice, the former
+takes place in the much longer second choice. Image data passes from the
+generating action to the presenting action via the variable @code{Image}
+that contains a complete @file{.png} image, which is otherwise stored
+in a file. If you prefer @file{.ps} or @file{.gif} images over the
+default @file{.png} images, you may select these options by uncommenting
+the appropriate lines. But remember to do so in two places: when
+telling GNUPlot which kind of images to generate, and when transmitting the
+image at the end of the program.
+
+Looking at the end of the program,
+the way we pass the @samp{Content-type} to the browser is a bit unusual.
+It is appended to the @samp{OK} of the first header line
+to make sure the type information becomes part of the header.
+The other variables that get transmitted across the network are
+made empty, because in this case we do not have an HTML document to
+transmit, but rather raw image data to contain in the body.
+
+Most of the work is done in the second menu choice. It starts with a
+strange JavaScript code snippet. When first implementing this server,
+we used a short @code{@w{"<IMG SRC="} MyPrefix "/Image>"} here. But then
+browsers got smarter and tried to improve on speed by requesting the
+image and the HTML code at the same time. When doing this, the browser
+tries to build up a connection for the image request while the request for
+the HTML text is not yet completed. The browser tries to connect
+to the @command{gawk} server on port 8080 while port 8080 is still in use for
+transmission of the HTML text. The connection for the image cannot be
+built up, so the image appears as ``broken'' in the browser window.
+We solved this problem by telling the browser to open a separate window
+for the image, but only after a delay of 1000 milliseconds.
+By this time, the server should be ready for serving the next request.
+
+But there is one more subtlety in the JavaScript code.
+Each time the JavaScript code opens a window for the image, the
+name of the image is appended with a timestamp (@code{systime}).
+Why this constant change of name for the image? Initially, we always named
+the image @code{Image}, but then the Netscape browser noticed the name
+had @emph{not} changed since the previous request and displayed the
+previous image (caching behavior). The server core
+is implemented so that browsers are told @emph{not} to cache anything.
+Obviously HTTP requests do not always work as expected. One way to
+circumvent the cache of such overly smart browsers is to change the
+name of the image with each request. These three lines of JavaScript
+caused us a lot of trouble.
+
+The rest can be broken
+down into two phases. At first, we check if there are statistical
+parameters. When the program is first started, there usually are no
+parameters because it enters the page coming from the top menu.
+Then, we only have to present the user a form that he can use to change
+statistical parameters and submit them. Subsequently, the submission of
+the form causes the execution of the first phase because @emph{now}
+there @emph{are} parameters to handle.
+
+Now that we have parameters, we know there will be an image available.
+Therefore we insert the JavaScript code here to initiate the opening
+of the image in a separate window. Then,
+we prepare some variables that will be passed to GNUPlot for calculation
+of the probabilities. Prior to reading the results, we must temporarily
+change @code{RS} because GNUPlot separates lines with newlines.
+After instructing GNUPlot to generate a @file{.png} (or @file{.ps} or
+@file{.gif}) image, we initiate the insertion of some text,
+explaining the resulting probabilities. The final @samp{plot} command
+actually generates the image data. This raw binary has to be read in carefully
+without adding, changing, or deleting a single byte. Hence the unusual
+initialization of @code{Image} and completion with a @code{while} loop.
+
+When using this server, it soon becomes clear that it is far from being
+perfect. It mixes source code of six scripting languages or protocols:
+
+@itemize @bullet
+@item GNU @command{awk} implements a server for the protocol:
+@item HTTP which transmits:
+@item HTML text which contains a short piece of:
+@item JavaScript code opening a separate window.
+@item A Bourne shell script is used for piping commands into:
+@item GNUPlot to generate the image to be opened.
+@end itemize
+
+After all this work, the GNUPlot image opens in the JavaScript window
+where it can be viewed by the user.
+
+It is probably better not to mix up so many different languages.
+The result is not very readable. Furthermore, the
+statistical part of the server does not take care of invalid input.
+Among others, using negative variances will cause invalid results.
+
+@node MAZE, MOBAGWHO, STATIST, Some Applications and Techniques
+@section MAZE: Walking Through a Maze In Virtual Reality
+@cindex MAZE
+@cindex VRML
+@c VRML in iX 11/96 134.
+@quotation
+@cindex Perlis, Alan
+@i{In the long run, every program becomes rococo, and then rubble.}@*
+Alan Perlis
+@end quotation
+
+By now, we know how to present arbitrary @samp{Content-type}s to a browser.
+In this @value{SECTION}, our server will present a 3D world to our browser.
+The 3D world is described in a scene description language (VRML,
+Virtual Reality Modeling Language) that allows us to travel through a
+perspective view of a 2D maze with our browser. Browsers with a
+VRML plugin enable exploration of this technology. We could do
+one of those boring @samp{Hello world} examples here, that are usually
+presented when introducing novices to
+VRML. If you have never written
+any VRML code, have a look at
+the VRML FAQ.
+Presenting a static VRML scene is a bit trivial; in order to expose
+@command{gawk}'s new capabilities, we will present a dynamically generated
+VRML scene. The function @code{SetUpServer} is very simple because it
+only sets the default HTML page and initializes the random number
+generator. As usual, the surrounding server lets you browse the maze.
+
+@smallexample
+@c file eg/network/maze.awk
+function SetUpServer() @{
+ TopHeader = "<HTML><title>Walk through a maze</title>"
+ TopDoc = "\
+ <h2>Please choose one of the following actions:</h2>\
+ <UL>\
+ <LI><A HREF=" MyPrefix "/AboutServer>About this server</A>\
+ <LI><A HREF=" MyPrefix "/VRMLtest>Watch a simple VRML scene</A>\
+ </UL>"
+ TopFooter = "</HTML>"
+ srand()
+@}
+@c endfile
+@end smallexample
+
+The function @code{HandleGET} is a bit longer because it first computes
+the maze and afterwards generates the VRML code that is sent across
+the network. As shown in the STATIST example
+(@pxref{STATIST}),
+we set the type of the
+content to VRML and then store the VRML representation of the maze as the
+page content. We assume that the maze is stored in a 2D array. Initially,
+the maze consists of walls only. Then, we add an entry and an exit to the
+maze and let the rest of the work be done by the function @code{MakeMaze}.
+Now, only the wall fields are left in the maze. By iterating over the these
+fields, we generate one line of VRML code for each wall field.
+
+@smallexample
+@c file eg/network/maze.awk
+function HandleGET() @{
+ if (MENU[2] == "AboutServer") @{
+ Document = "If your browser has a VRML 2 plugin,\
+ this server shows you a simple VRML scene."
+ @} else if (MENU[2] == "VRMLtest") @{
+ XSIZE = YSIZE = 11 # initially, everything is wall
+ for (y = 0; y < YSIZE; y++)
+ for (x = 0; x < XSIZE; x++)
+ Maze[x, y] = "#"
+ delete Maze[0, 1] # entry is not wall
+ delete Maze[XSIZE-1, YSIZE-2] # exit is not wall
+ MakeMaze(1, 1)
+ Document = "\
+#VRML V2.0 utf8\n\
+Group @{\n\
+ children [\n\
+ PointLight @{\n\
+ ambientIntensity 0.2\n\
+ color 0.7 0.7 0.7\n\
+ location 0.0 8.0 10.0\n\
+ @}\n\
+ DEF B1 Background @{\n\
+ skyColor [0 0 0, 1.0 1.0 1.0 ]\n\
+ skyAngle 1.6\n\
+ groundColor [1 1 1, 0.8 0.8 0.8, 0.2 0.2 0.2 ]\n\
+ groundAngle [ 1.2 1.57 ]\n\
+ @}\n\
+ DEF Wall Shape @{\n\
+ geometry Box @{size 1 1 1@}\n\
+ appearance Appearance @{ material Material @{ diffuseColor 0 0 1 @} @}\n\
+ @}\n\
+ DEF Entry Viewpoint @{\n\
+ position 0.5 1.0 5.0\n\
+ orientation 0.0 0.0 -1.0 0.52\n\
+ @}\n"
+ for (i in Maze) @{
+ split(i, t, SUBSEP)
+ Document = Document " Transform @{ translation "
+ Document = Document t[1] " 0 -" t[2] " children USE Wall @}\n"
+ @}
+ Document = Document " ] # end of group for world\n@}"
+ Reason = "OK" ORS "Content-type: model/vrml"
+ Header = Footer = ""
+ @}
+@}
+@c endfile
+@end smallexample
+
+Finally, we have a look at @code{MakeMaze}, the function that generates
+the @code{Maze} array. When entered, this function assumes that the array
+has been initialized so that each element represents a wall element and
+the maze is initially full of wall elements. Only the entrance and the exit
+of the maze should have been left free. The parameters of the function tell
+us which element must be marked as not being a wall. After this, we take
+a look at the four neighbouring elements and remember which we have already
+treated. Of all the neighbouring elements, we take one at random and
+walk in that direction. Therefore, the wall element in that direction has
+to be removed and then, we call the function recursively for that element.
+The maze is only completed if we iterate the above procedure for
+@emph{all} neighbouring elements (in random order) and for our present
+element by recursively calling the function for the present element. This
+last iteration could have been done in a loop,
+but it is done much simpler recursively.
+
+Notice that elements with coordinates that are both odd are assumed to be
+on our way through the maze and the generating process cannot terminate
+as long as there is such an element not being @code{delete}d. All other
+elements are potentially part of the wall.
+
+@smallexample
+@c file eg/network/maze.awk
+function MakeMaze(x, y) @{
+ delete Maze[x, y] # here we are, we have no wall here
+ p = 0 # count unvisited fields in all directions
+ if (x-2 SUBSEP y in Maze) d[p++] = "-x"
+ if (x SUBSEP y-2 in Maze) d[p++] = "-y"
+ if (x+2 SUBSEP y in Maze) d[p++] = "+x"
+ if (x SUBSEP y+2 in Maze) d[p++] = "+y"
+ if (p>0) @{ # if there are univisited fields, go there
+ p = int(p*rand()) # choose one unvisited field at random
+ if (d[p] == "-x") @{ delete Maze[x - 1, y]; MakeMaze(x - 2, y)
+ @} else if (d[p] == "-y") @{ delete Maze[x, y - 1]; MakeMaze(x, y - 2)
+ @} else if (d[p] == "+x") @{ delete Maze[x + 1, y]; MakeMaze(x + 2, y)
+ @} else if (d[p] == "+y") @{ delete Maze[x, y + 1]; MakeMaze(x, y + 2)
+ @} # we are back from recursion
+ MakeMaze(x, y); # try again while there are unvisited fields
+ @}
+@}
+@c endfile
+@end smallexample
+
+@node MOBAGWHO, STOXPRED, MAZE, Some Applications and Techniques
+@section MOBAGWHO: a Simple Mobile Agent
+@cindex MOBAGWHO program
+@cindex agent
+@quotation
+@cindex Hoare, C.A.R.
+@i{There are two ways of constructing a software design: One way is to
+make it so simple that there are obviously no deficiencies, and the
+other way is to make it so complicated that there are no obvious
+deficiencies.} @*
+C. A. R. Hoare
+@end quotation
+
+A @dfn{mobile agent} is a program that can be dispatched from a computer and
+transported to a remote server for execution. This is called @dfn{migration},
+which means that a process on another system is started that is independent
+from its originator. Ideally, it wanders through
+a network while working for its creator or owner. In places like
+the UMBC Agent Web,
+people are quite confident that (mobile) agents are a software engineering
+paradigm that enables us to significantly increase the efficiency
+of our work. Mobile agents could become the mediators between users and
+the networking world. For an unbiased view at this technology,
+see the remarkable paper @cite{Mobile Agents: Are they a good
+idea?}.@footnote{@uref{http://www.research.ibm.com/massive/mobag.ps}}
+
+@ignore
+@c Chuck says to take all of this out.
+@cindex Tcl/Tk
+A good instance of this paradigm is
+@cite{Agent Tcl},@footnote{@uref{http://agent.cs.dartmouth.edu/software/agent2.0/}}
+an extension of the Tcl language. After introducing a typical
+development environment, the aforementioned paper shows a nice little
+example application that we will try to rebuild in @command{gawk}. The
+@command{who} agent takes a list of servers and wanders from one server
+to the next one, always looking to see who is logged in.
+Having reached the last
+one, it sends back a message with a list of all users it found on each
+machine.
+
+But before implementing something that might or might not be a mobile
+agent, let us clarify the concept and some important terms. The agent
+paradigm in general is such a young scientific discipline that it has
+not yet developed a widely-accepted terminology. Some authors try to
+give precise definitions, but their scope is often not wide enough
+to be generally accepted. Franklin and Graesser ask
+@cite{Is it an Agent or just a Program: A Taxonomy for Autonomous
+Agents}@footnote{@uref{http://www.msci.memphis.edu/~franklin/AgentProg.html}}
+and give even better answers than Caglayan and Harrison in their
+@cite{Agent Sourcebook}.@footnote{@uref{http://www.aminda.com/mazzu/sourcebook/}}
+
+@itemize @minus
+@item
+@i{An autonomous agent is a system situated within and a part of
+an environment that senses that environment and acts on it, over time, in
+pursuit of its own agenda and so as to effect what it senses in the future.}
+(Quoted from Franklin and Graesser.)
+@item
+A mobile agent is able to transport itself from one machine to another.
+@item
+The term @dfn{migration} often denotes this process of moving.
+But neither of the two sources above even mentions this term, while others
+use it regularly.
+@end itemize
+
+Before delving into the (rather demanding) details of
+implementation, let us give just one more quotation as a final
+motivation. Steven Farley published an excellent paper called
+@cite{Mobile Agent System Architecture},@footnote{This often
+cited text originally appeared as a conference paper here:
+@uref{http://www.sigs.com/publications/docs/java/9705/farley.html}
+Many bibliographies on the Internet point to this dead link. Meanwhile,
+the paper appeared as a contribution to a book called More Java Gems here:
+@uref{http://uk.cambridge.org/computerscience/object/catalogue/0521774772/default.htm}}
+in which he asks ``Why use an agent architecture?''
+
+@quotation
+If client-server systems are the currently established norm and distributed
+object systems such as CORBA are defining the future standards, why bother
+with agents? Agent architectures have certain advantages over these other
+types. Three of the most important advantages are:
+@cindex CORBA
+
+@enumerate
+@item
+An agent performs much processing at the server where local bandwidth
+is high, thus reducing the amount of network bandwidth consumed and increasing
+overall performance. In contrast, a CORBA client object with the equivalent
+functionality of a given agent must make repeated remote method calls to
+the server object because CORBA objects cannot move across the network
+at runtime.
+
+@item
+An agent operates independently of the application from which the
+agent was invoked. The agent operates asynchronously, meaning that the
+client application does not need to wait for the results. This is especially
+important for mobile users who are not always connected to the network.
+
+@item
+The use of agents allows for the injection of new functionality into
+a system at run time. An agent system essentially contains its own automatic
+software distribution mechanism. Since CORBA has no built-in support for
+mobile code, new functionality generally has to be installed manually.
+
+@end enumerate
+
+Of course a non-agent system can exhibit these same features with some
+work. But the mobile code paradigm supports the transfer of executable
+code to a remote location for asynchronous execution from the start. An
+agent architecture should be considered for systems where the above features
+are primary requirements.
+@end quotation
+@end ignore
+
+When trying to migrate a process from one system to another,
+a server process is needed on the receiving side. Depending on the kind
+of server process, several ways of implementation come to mind.
+How the process is implemented depends upon the kind of server process:
+
+@itemize @bullet
+@item
+HTTP can be used as the protocol for delivery of the migrating
+process. In this case, we use a common web
+server as the receiving server process. A universal CGI script
+mediates between migrating process and web server.
+Each server willing to accept migrating agents makes this universal
+service available. HTTP supplies the @code{POST} method to transfer
+some data to a file on the web server. When a CGI script is called
+remotely with the @code{POST} method instead of the usual @code{GET} method,
+data is transmitted from the client process to the standard input
+of the server's CGI script. So, to implement a mobile agent,
+we must not only write the agent program to start on the client
+side, but also the CGI script to receive the agent on the server side.
+
+@cindex CGI (Common Gateway Interface)
+@cindex apache
+@item
+The @code{PUT} method can also be used for migration. HTTP does not
+require a CGI script for migration via @code{PUT}. However, with common web
+servers there is no advantage to this solution, because web servers such as
+Apache
+require explicit activation of a special @code{PUT} script.
+
+@item
+@cite{Agent Tcl} pursues a different course; it relies on a dedicated server
+process with a dedicated protocol specialized for receiving mobile agents.
+@end itemize
+
+Our agent example abuses a common web server as a migration tool. So, it needs a
+universal CGI script on the receiving side (the web server). The receiving script is
+activated with a @code{POST} request when placed into a location like
+@file{/httpd/cgi-bin/PostAgent.sh}. Make sure that the server system uses a
+version of @command{gawk} that supports network access (Version 3.1 or later;
+verify with @samp{gawk --version}).
+
+@example
+@c file eg/network/PostAgent.sh
+#!/bin/sh
+MobAg=/tmp/MobileAgent.$$
+# direct script to mobile agent file
+cat > $MobAg
+# execute agent concurrently
+gawk -f $MobAg $MobAg > /dev/null &
+# HTTP header, terminator and body
+gawk 'BEGIN @{ print "\r\nAgent started" @}'
+rm $MobAg # delete script file of agent
+@c endfile
+@end example
+
+By making its process id (@code{$$}) part of the unique @value{FN}, the
+script avoids conflicts between concurrent instances of the script.
+First, all lines
+from standard input (the mobile agent's source code) are copied into
+this unique file. Then, the agent is started as a concurrent process
+and a short message reporting this fact is sent to the submitting client.
+Finally, the script file of the mobile agent is removed because it is
+no longer needed. Although it is a short script, there are several noteworthy
+points:
+
+@table @asis
+@item Security
+@emph{There is none}. In fact, the CGI script should never
+be made available on a server that is part of the Internet because everyone
+would be allowed to execute arbitrary commands with it. This behavior is
+acceptable only when performing rapid prototyping.
+
+@item Self-Reference
+Each migrating instance of an agent is started
+in a way that enables it to read its own source code from standard input
+and use the code for subsequent
+migrations. This is necessary because it needs to treat the agent's code
+as data to transmit. @command{gawk} is not the ideal language for such
+a job. Lisp and Tcl are more suitable because they do not make a distinction
+between program code and data.
+
+@item Independence
+After migration, the agent is not linked to its
+former home in any way. By reporting @samp{Agent started}, it waves
+``Goodbye'' to its origin. The originator may choose to terminate or not.
+@end table
+
+@cindex Lisp
+The originating agent itself is started just like any other command-line
+script, and reports the results on standard output. By letting the name
+of the original host migrate with the agent, the agent that migrates
+to a host far away from its origin can report the result back home.
+Having arrived at the end of the journey, the agent establishes
+a connection and reports the results. This is the reason for
+determining the name of the host with @samp{uname -n} and storing it
+in @code{MyOrigin} for later use. We may also set variables with the
+@option{-v} option from the command line. This interactivity is only
+of importance in the context of starting a mobile agent; therefore this
+@code{BEGIN} pattern and its action do not take part in migration:
+
+@smallexample
+@c file eg/network/mobag.awk
+BEGIN @{
+ if (ARGC != 2) @{
+ print "MOBAG - a simple mobile agent"
+ print "CALL:\n gawk -f mobag.awk mobag.awk"
+ print "IN:\n the name of this script as a command-line parameter"
+ print "PARAM:\n -v MyOrigin=myhost.com"
+ print "OUT:\n the result on stdout"
+ print "JK 29.03.1998 01.04.1998"
+ exit
+ @}
+ if (MyOrigin == "") @{
+ "uname -n" | getline MyOrigin
+ close("uname -n")
+ @}
+@}
+@c endfile
+@end smallexample
+
+Since @command{gawk} cannot manipulate and transmit parts of the program
+directly, the source code is read and stored in strings.
+Therefore, the program scans itself for
+the beginning and the ending of functions.
+Each line in between is appended to the code string until the end of
+the function has been reached. A special case is this part of the program
+itself. It is not a function.
+Placing a similar framework around it causes it to be treated
+like a function. Notice that this mechanism works for all the
+functions of the source code, but it cannot guarantee that the order
+of the functions is preserved during migration:
+
+@smallexample
+@c file eg/network/mobag.awk
+#ReadMySelf
+/^function / @{ FUNC = $2 @}
+/^END/ || /^#ReadMySelf/ @{ FUNC = $1 @}
+FUNC != "" @{ MOBFUN[FUNC] = MOBFUN[FUNC] RS $0 @}
+(FUNC != "") && (/^@}/ || /^#EndOfMySelf/) \
+ @{ FUNC = "" @}
+#EndOfMySelf
+@c endfile
+@end smallexample
+
+The web server code in
+@ref{Interacting Service, ,A Web Service with Interaction},
+was first developed as a site-independent core. Likewise, the
+@command{gawk}-based mobile agent
+starts with an agent-independent core, to which can be appended
+application-dependent functions. What follows is the only
+application-independent function needed for the mobile agent:
+
+@smallexample
+@c file eg/network/mobag.awk
+function migrate(Destination, MobCode, Label) @{
+ MOBVAR["Label"] = Label
+ MOBVAR["Destination"] = Destination
+ RS = ORS = "\r\n"
+ HttpService = "/inet/tcp/0/" Destination
+ for (i in MOBFUN)
+ MobCode = (MobCode "\n" MOBFUN[i])
+ MobCode = MobCode "\n\nBEGIN @{"
+ for (i in MOBVAR)
+ MobCode = (MobCode "\n MOBVAR[\"" i "\"] = \"" MOBVAR[i] "\"")
+ MobCode = MobCode "\n@}\n"
+ print "POST /cgi-bin/PostAgent.sh HTTP/1.0" |& HttpService
+ print "Content-length:", length(MobCode) ORS |& HttpService
+ printf "%s", MobCode |& HttpService
+ while ((HttpService |& getline) > 0)
+ print $0
+ close(HttpService)
+@}
+@c endfile
+@end smallexample
+
+The @code{migrate} function prepares the
+aforementioned strings containing the program code and transmits them to a
+server. A consequence of this modular approach is that the @code{migrate}
+function takes some parameters that aren't needed in this application,
+but that will be in future ones. Its mandatory parameter @code{Destination} holds the
+name (or IP address) of the server that the agent wants as a host for its
+code. The optional parameter @code{MobCode} may contain some @command{gawk}
+code that is inserted during migration in front of all other code.
+The optional parameter @code{Label} may contain
+a string that tells the agent what to do in program execution after
+arrival at its new home site. One of the serious obstacles in implementing
+a framework for mobile agents is that it does not suffice to migrate the
+code. It is also necessary to migrate the state of execution of the agent. In
+contrast to @cite{Agent Tcl}, this program does not try to migrate the complete set
+of variables. The following conventions are used:
+
+@itemize @bullet
+@item
+Each variable in an agent program is local to the current host and does
+@emph{not} migrate.
+
+@item
+The array @code{MOBFUN} shown above is an exception. It is handled
+by the function @code{migrate} and does migrate with the application.
+
+@item
+The other exception is the array @code{MOBVAR}. Each variable that
+takes part in migration has to be an element of this array.
+@code{migrate} also takes care of this.
+@end itemize
+
+Now it's clear what happens to the @code{Label} parameter of the
+function @code{migrate}. It is copied into @code{MOBVAR["Label"]} and
+travels alongside the other data. Since travelling takes place via HTTP,
+records must be separated with @code{"\r\n"} in @code{RS} and
+@code{ORS} as usual. The code assembly for migration takes place in
+three steps:
+
+@itemize @bullet
+@item
+Iterate over @code{MOBFUN} to collect all functions verbatim.
+
+@item
+Prepare a @code{BEGIN} pattern and put assignments to mobile
+variables into the action part.
+
+@item
+Transmission itself resembles GETURL: the header with the request
+and the @code{Content-length} is followed by the body. In case there is
+any reply over the network, it is read completely and echoed to
+standard output to avoid irritating the server.
+@end itemize
+
+The application-independent framework is now almost complete. What follows
+is the @code{END} pattern that is executed when the mobile agent has
+finished reading its own code. First, it checks whether it is already
+running on a remote host or not. In case initialization has not yet taken
+place, it starts @code{MyInit}. Otherwise (later, on a remote host), it
+starts @code{MyJob}:
+
+@smallexample
+@c file eg/network/mobag.awk
+END @{
+ if (ARGC != 2) exit # stop when called with wrong parameters
+ if (MyOrigin != "") # is this the originating host?
+ MyInit() # if so, initialize the application
+ else # we are on a host with migrated data
+ MyJob() # so we do our job
+@}
+@c endfile
+@end smallexample
+
+All that's left to extend the framework into a complete application
+is to write two application-specific functions: @code{MyInit} and
+@code{MyJob}. Keep in mind that the former is executed once on the
+originating host, while the latter is executed after each migration:
+
+@smallexample
+@c file eg/network/mobag.awk
+function MyInit() @{
+ MOBVAR["MyOrigin"] = MyOrigin
+ MOBVAR["Machines"] = "localhost/80 max/80 moritz/80 castor/80"
+ split(MOBVAR["Machines"], Machines) # which host is the first?
+ migrate(Machines[1], "", "") # go to the first host
+ while (("/inet/tcp/8080/0/0" |& getline) > 0) # wait for result
+ print $0 # print result
+ close("/inet/tcp/8080/0/0")
+@}
+@c endfile
+@end smallexample
+
+As mentioned earlier, this agent takes the name of its origin
+(@code{MyOrigin}) with it. Then, it takes the name of its first
+destination and goes there for further work. Notice that this name has
+the port number of the web server appended to the name of the server,
+because the function @code{migrate} needs it this way to create
+the @code{HttpService} variable. Finally, it waits for the result to arrive.
+The @code{MyJob} function runs on the remote host:
+
+@smallexample
+@c file eg/network/mobag.awk
+function MyJob() @{
+ # forget this host
+ sub(MOBVAR["Destination"], "", MOBVAR["Machines"])
+ MOBVAR["Result"]=MOBVAR["Result"] SUBSEP SUBSEP MOBVAR["Destination"] ":"
+ while (("who" | getline) > 0) # who is logged in?
+ MOBVAR["Result"] = MOBVAR["Result"] SUBSEP $0
+ close("who")
+ if (index(MOBVAR["Machines"], "/") > 0) @{ # any more machines to visit?
+ split(MOBVAR["Machines"], Machines) # which host is next?
+ migrate(Machines[1], "", "") # go there
+ @} else @{ # no more machines
+ gsub(SUBSEP, "\n", MOBVAR["Result"]) # send result to origin
+ print MOBVAR["Result"] |& "/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080"
+ close("/inet/tcp/0/" MOBVAR["MyOrigin"] "/8080")
+ @}
+@}
+@c endfile
+@end smallexample
+
+After migrating, the first thing to do in @code{MyJob} is to delete
+the name of the current host from the list of hosts to visit. Now, it
+is time to start the real work by appending the host's name to the
+result string, and reading line by line who is logged in on this host.
+A very annoying circumstance is the fact that the elements of
+@code{MOBVAR} cannot hold the newline character (@code{"\n"}). If they
+did, migration of this string did not work because the string didn't
+obey the syntax rule for a string in @command{gawk}.
+@code{SUBSEP} is used as a temporary replacement.
+If the list of hosts to visit holds
+at least one more entry, the agent migrates to that place to go on
+working there. Otherwise, we replace the @code{SUBSEP}s
+with a newline character in the resulting string, and report it to
+the originating host, whose name is stored in @code{MOBVAR["MyOrigin"]}.
+
+@node STOXPRED, PROTBASE, MOBAGWHO, Some Applications and Techniques
+@section STOXPRED: Stock Market Prediction As A Service
+@cindex STOXPRED program
+@cindex Yahoo!
+@quotation
+@i{Far out in the uncharted backwaters of the unfashionable end of
+the Western Spiral arm of the Galaxy lies a small unregarded yellow sun.}
+
+@i{Orbiting this at a distance of roughly ninety-two million miles is an
+utterly insignificant little blue-green planet whose ape-descendent life
+forms are so amazingly primitive that they still think digital watches are
+a pretty neat idea.}
+
+@i{This planet has --- or rather had --- a problem, which was this:
+most of the people living on it were unhappy for pretty much of the time.
+Many solutions were suggested for this problem, but most of these were
+largely concerned with the movements of small green pieces of paper,
+which is odd because it wasn't the small green pieces of paper that
+were unhappy.} @*
+Douglas Adams, @cite{The Hitch Hiker's Guide to the Galaxy}
+@end quotation
+
+@cindex @command{cron} utility
+Valuable services on the Internet are usually @emph{not} implemented
+as mobile agents. There are much simpler ways of implementing services.
+All Unix systems provide, for example, the @command{cron} service.
+Unix system users can write a list of tasks to be done each day, each
+week, twice a day, or just once. The list is entered into a file named
+@file{crontab}. For example, to distribute a newsletter on a daily
+basis this way, use @command{cron} for calling a script each day early
+in the morning.
+
+@example
+# run at 8 am on weekdays, distribute the newsletter
+0 8 * * 1-5 $HOME/bin/daily.job >> $HOME/log/newsletter 2>&1
+@end example
+
+The script first looks for interesting information on the Internet,
+assembles it in a nice form and sends the results via email to
+the customers.
+
+The following is an example of a primitive
+newsletter on stock market prediction. It is a report which first
+tries to predict the change of each share in the Dow Jones Industrial
+Index for the particular day. Then it mentions some especially
+promising shares as well as some shares which look remarkably bad
+on that day. The report ends with the usual disclaimer which tells
+every child @emph{not} to try this at home and hurt anybody.
+@cindex Dow Jones Industrial Index
+
+@smallexample
+Good morning Uncle Scrooge,
+
+This is your daily stock market report for Monday, October 16, 2000.
+Here are the predictions for today:
+
+ AA neutral
+ GE up
+ JNJ down
+ MSFT neutral
+ @dots{}
+ UTX up
+ DD down
+ IBM up
+ MO down
+ WMT up
+ DIS up
+ INTC up
+ MRK down
+ XOM down
+ EK down
+ IP down
+
+The most promising shares for today are these:
+
+ INTC http://biz.yahoo.com/n/i/intc.html
+
+The stock shares to avoid today are these:
+
+ EK http://biz.yahoo.com/n/e/ek.html
+ IP http://biz.yahoo.com/n/i/ip.html
+ DD http://biz.yahoo.com/n/d/dd.html
+ @dots{}
+@end smallexample
+
+@ignore
+@c Chuck suggests removing this paragraph
+If you are not into stock market prediction but want to earn money
+with a more humane service, you might prefer to send out horoscopes
+to your customers. Or, once every refrigerator in every household on this side
+of the Chinese Wall is connected to the Internet, such a service could
+inspect the contents of your customer's refrigerators each day and
+advise them on nutrition. Big Brother is watching them.
+@end ignore
+
+The script as a whole is rather long. In order to ease the pain of
+studying other people's source code, we have broken the script
+up into meaningful parts which are invoked one after the other.
+The basic structure of the script is as follows:
+
+@example
+@c file eg/network/stoxpred.awk
+BEGIN @{
+ Init()
+ ReadQuotes()
+ CleanUp()
+ Prediction()
+ Report()
+ SendMail()
+@}
+@c endfile
+@end example
+
+The earlier parts store data into variables and arrays which are
+subsequently used by later parts of the script. The @code{Init} function
+first checks if the script is invoked correctly (without any parameters).
+If not, it informs the user of the correct usage. What follows are preparations
+for the retrieval of the historical quote data. The names of the 30 stock
+shares are stored in an array @code{name} along with the current date
+in @code{day}, @code{month}, and @code{year}.
+
+All users who are separated
+from the Internet by a firewall and have to direct their Internet accesses
+to a proxy must supply the name of the proxy to this script with the
+@samp{-v Proxy=@var{name}} option. For most users, the default proxy and
+port number should suffice.
+
+@example
+@c file eg/network/stoxpred.awk
+function Init() @{
+ if (ARGC != 1) @{
+ print "STOXPRED - daily stock share prediction"
+ print "IN:\n no parameters, nothing on stdin"
+ print "PARAM:\n -v Proxy=MyProxy -v ProxyPort=80"
+ print "OUT:\n commented predictions as email"
+ print "JK 09.10.2000"
+ exit
+ @}
+ # Remember ticker symbols from Dow Jones Industrial Index
+ StockCount = split("AA GE JNJ MSFT AXP GM JPM PG BA HD KO \
+ SBC C HON MCD T CAT HWP MMM UTX DD IBM MO WMT DIS INTC \
+ MRK XOM EK IP", name);
+ # Remember the current date as the end of the time series
+ day = strftime("%d")
+ month = strftime("%m")
+ year = strftime("%Y")
+ if (Proxy == "") Proxy = "chart.yahoo.com"
+ if (ProxyPort == 0) ProxyPort = 80
+ YahooData = "/inet/tcp/0/" Proxy "/" ProxyPort
+@}
+@c endfile
+@end example
+
+@cindex CSV format
+There are two really interesting parts in the script. One is the
+function which reads the historical stock quotes from an Internet
+server. The other is the one that does the actual prediction. In
+the following function we see how the quotes are read from the
+Yahoo server. The data which comes from the server is in
+CSV format (comma-separated values):
+
+@example
+@c file eg/network/stoxdata.txt
+Date,Open,High,Low,Close,Volume
+9-Oct-00,22.75,22.75,21.375,22.375,7888500
+6-Oct-00,23.8125,24.9375,21.5625,22,10701100
+5-Oct-00,24.4375,24.625,23.125,23.50,5810300
+@c endfile
+@end example
+
+Lines contain values of the same time instant, whereas columns are
+separated by commas and contain the kind of data that is described
+in the header (first) line. At first, @command{gawk} is instructed to
+separate columns by commas (@samp{FS = ","}). In the loop that follows,
+a connection to the Yahoo server is first opened, then a download takes
+place, and finally the connection is closed. All this happens once for
+each ticker symbol. In the body of this loop, an Internet address is
+built up as a string according to the rules of the Yahoo server. The
+starting and ending date are chosen to be exactly the same, but one year
+apart in the past. All the action is initiated within the @code{printf}
+command which transmits the request for data to the Yahoo server.
+
+In the inner loop, the server's data is first read and then scanned
+line by line. Only lines which have six columns and the name of a month
+in the first column contain relevant data. This data is stored
+in the two-dimensional array @code{quote}; one dimension
+being time, the other being the ticker symbol. During retrieval of the
+first stock's data, the calendar names of the time instances are stored
+in the array @code{day} because we need them later.
+
+@smallexample
+@c file eg/network/stoxpred.awk
+function ReadQuotes() @{
+ # Retrieve historical data for each ticker symbol
+ FS = ","
+ for (stock = 1; stock <= StockCount; stock++) @{
+ URL = "http://chart.yahoo.com/table.csv?s=" name[stock] \
+ "&a=" month "&b=" day "&c=" year-1 \
+ "&d=" month "&e=" day "&f=" year \
+ "g=d&q=q&y=0&z=" name[stock] "&x=.csv"
+ printf("GET " URL " HTTP/1.0\r\n\r\n") |& YahooData
+ while ((YahooData |& getline) > 0) @{
+ if (NF == 6 && $1 ~ /Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/) @{
+ if (stock == 1)
+ days[++daycount] = $1;
+ quote[$1, stock] = $5
+ @}
+ @}
+ close(YahooData)
+ @}
+ FS = " "
+@}
+@c endfile
+@end smallexample
+
+Now that we @emph{have} the data, it can be checked once again to make sure
+that no individual stock is missing or invalid, and that all the stock quotes are
+aligned correctly. Furthermore, we renumber the time instances. The
+most recent day gets day number 1 and all other days get consecutive
+numbers. All quotes are rounded toward the nearest whole number in US Dollars.
+
+@smallexample
+@c file eg/network/stoxpred.awk
+function CleanUp() @{
+ # clean up time series; eliminate incomplete data sets
+ for (d = 1; d <= daycount; d++) @{
+ for (stock = 1; stock <= StockCount; stock++)
+ if (! ((days[d], stock) in quote))
+ stock = StockCount + 10
+ if (stock > StockCount + 1)
+ continue
+ datacount++
+ for (stock = 1; stock <= StockCount; stock++)
+ data[datacount, stock] = int(0.5 + quote[days[d], stock])
+ @}
+ delete quote
+ delete days
+@}
+@c endfile
+@end smallexample
+
+Now we have arrived at the second really interesting part of the whole affair.
+What we present here is a very primitive prediction algorithm:
+@emph{If a stock fell yesterday, assume it will also fall today; if
+it rose yesterday, assume it will rise today}. (Feel free to replace this
+algorithm with a smarter one.) If a stock changed in the same direction
+on two consecutive days, this is an indication which should be highlighted.
+Two-day advances are stored in @code{hot} and two-day declines in
+@code{avoid}.
+
+The rest of the function is a sanity check. It counts the number of
+correct predictions in relation to the total number of predictions
+one could have made in the year before.
+
+@smallexample
+@c file eg/network/stoxpred.awk
+function Prediction() @{
+ # Predict each ticker symbol by prolonging yesterday's trend
+ for (stock = 1; stock <= StockCount; stock++) @{
+ if (data[1, stock] > data[2, stock]) @{
+ predict[stock] = "up"
+ @} else if (data[1, stock] < data[2, stock]) @{
+ predict[stock] = "down"
+ @} else @{
+ predict[stock] = "neutral"
+ @}
+ if ((data[1, stock] > data[2, stock]) && (data[2, stock] > data[3, stock]))
+ hot[stock] = 1
+ if ((data[1, stock] < data[2, stock]) && (data[2, stock] < data[3, stock]))
+ avoid[stock] = 1
+ @}
+ # Do a plausibility check: how many predictions proved correct?
+ for (s = 1; s <= StockCount; s++) @{
+ for (d = 1; d <= datacount-2; d++) @{
+ if (data[d+1, s] > data[d+2, s]) @{
+ UpCount++
+ @} else if (data[d+1, s] < data[d+2, s]) @{
+ DownCount++
+ @} else @{
+ NeutralCount++
+ @}
+ if (((data[d, s] > data[d+1, s]) && (data[d+1, s] > data[d+2, s])) ||
+ ((data[d, s] < data[d+1, s]) && (data[d+1, s] < data[d+2, s])) ||
+ ((data[d, s] == data[d+1, s]) && (data[d+1, s] == data[d+2, s])))
+ CorrectCount++
+ @}
+ @}
+@}
+@c endfile
+@end smallexample
+
+At this point the hard work has been done: the array @code{predict}
+contains the predictions for all the ticker symbols. It is up to the
+function @code{Report} to find some nice words to introduce the
+desired information.
+
+@smallexample
+@c file eg/network/stoxpred.awk
+function Report() @{
+ # Generate report
+ report = "\nThis is your daily "
+ report = report "stock market report for "strftime("%A, %B %d, %Y")".\n"
+ report = report "Here are the predictions for today:\n\n"
+ for (stock = 1; stock <= StockCount; stock++)
+ report = report "\t" name[stock] "\t" predict[stock] "\n"
+ for (stock in hot) @{
+ if (HotCount++ == 0)
+ report = report "\nThe most promising shares for today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ @}
+ for (stock in avoid) @{
+ if (AvoidCount++ == 0)
+ report = report "\nThe stock shares to avoid today are these:\n\n"
+ report = report "\t" name[stock] "\t\thttp://biz.yahoo.com/n/" \
+ tolower(substr(name[stock], 1, 1)) "/" tolower(name[stock]) ".html\n"
+ @}
+ report = report "\nThis sums up to " HotCount+0 " winners and " AvoidCount+0
+ report = report " losers. When using this kind\nof prediction scheme for"
+ report = report " the 12 months which lie behind us,\nwe get " UpCount
+ report = report " 'ups' and " DownCount " 'downs' and " NeutralCount
+ report = report " 'neutrals'. Of all\nthese " UpCount+DownCount+NeutralCount
+ report = report " predictions " CorrectCount " proved correct next day.\n"
+ report = report "A success rate of "\
+ int(100*CorrectCount/(UpCount+DownCount+NeutralCount)) "%.\n"
+ report = report "Random choice would have produced a 33% success rate.\n"
+ report = report "Disclaimer: Like every other prediction of the stock\n"
+ report = report "market, this report is, of course, complete nonsense.\n"
+ report = report "If you are stupid enough to believe these predictions\n"
+ report = report "you should visit a doctor who can treat your ailment."
+@}
+@c endfile
+@end smallexample
+
+The function @code{SendMail} goes through the list of customers and opens
+a pipe to the @code{mail} command for each of them. Each one receives an
+email message with a proper subject heading and is addressed with his full name.
+
+@smallexample
+@c file eg/network/stoxpred.awk
+function SendMail() @{
+ # send report to customers
+ customer["uncle.scrooge@@ducktown.gov"] = "Uncle Scrooge"
+ customer["more@@utopia.org" ] = "Sir Thomas More"
+ customer["spinoza@@denhaag.nl" ] = "Baruch de Spinoza"
+ customer["marx@@highgate.uk" ] = "Karl Marx"
+ customer["keynes@@the.long.run" ] = "John Maynard Keynes"
+ customer["bierce@@devil.hell.org" ] = "Ambrose Bierce"
+ customer["laplace@@paris.fr" ] = "Pierre Simon de Laplace"
+ for (c in customer) @{
+ MailPipe = "mail -s 'Daily Stock Prediction Newsletter'" c
+ print "Good morning " customer[c] "," | MailPipe
+ print report "\n.\n" | MailPipe
+ close(MailPipe)
+ @}
+@}
+@c endfile
+@end smallexample
+
+Be patient when running the script by hand.
+Retrieving the data for all the ticker symbols and sending the emails
+may take several minutes to complete, depending upon network traffic
+and the speed of the available Internet link.
+The quality of the prediction algorithm is likely to be disappointing.
+Try to find a better one.
+Should you find one with a success rate of more than 50%, please tell
+us about it! It is only for the sake of curiosity, of course. @code{:-)}
+
+@ignore
+@c chuck says to remove this
+Let us give you one final indication as to what one can expect from
+a prediction of stock data, which is sometimes said to contain much
+randomness. One theory says that all relevant information to be taken
+into account when estimating the price of a stock is contained in the
+stock quotes. Every bit of useful information has influenced the
+fair price. Therefore (the theory says) temporary changes (i.e., fluctuations
+within a minute) have to be purely random. But what is the cause of
+short-term changes in stock prices?
+
+Stock prices are fixed when supply and demand meet each other.
+What people are willing to pay reflects human expectations.
+Human expectations are not necessarily random. On the Internet,
+you can find an elucidating paper about predictability and human
+expectations:
+@uref{http://it.ucsd.edu/IT/Newsletter/archives/meir/05meir.html,
+@cite{Reflections on ``Universal Prediction of Individual Sequences''}}
+The authors (Feder, Merhav, Gutman) introduce the reader to the subject
+by telling a thrilling anecdote.
+@cindex Shannon, Claude
+@quotation
+In the early 50's, at Bell Laboratories, David Hagelbarger built a
+simple ``mind reading'' machine, whose purpose was to play the ``penny
+matching'' game. In this game, a player chooses head or tail, while a
+``mind reading'' machine tries to predict and match his choice.
+Surprisingly, as Robert Lucky tells in his book ``Silicon Dreams'',
+Hagelbarger's simple, 8-state machine, was able to match the ``pennies''
+of its human opponent 5,218 times over the course of 9,795 plays.
+Random guessing would lead to such a high success rate with a probability
+less than one out of 10 billion! Shannon, who was interested in prediction,
+information, and thinking machines, closely followed Hagelbarger's
+machine, and eventually built his own stripped-down version of the machine,
+having the same states, but one that used a simpler strategy at each state.
+As the legend goes, in a duel between the two machines, Shannon's machine
+won by a slight margin! No one knows if this was due to a superior algorithm
+or just a chance happening associated with the specific sequence at that game.
+In any event, the success of both these machines against ``untrained'' human
+opponents was explained by the fact that the human opponents cannot draw
+completely random
+bits.
+@end quotation
+@end ignore
+
+@node PROTBASE, , STOXPRED, Some Applications and Techniques
+@section PROTBASE: Searching Through A Protein Database
+@cindex PROTBASE
+@cindex NCBI, National Center for Biotechnology Information
+@cindex BLAST, Basic Local Alignment Search Tool
+@cindex Hoare, C.A.R.
+@quotation
+@i{Hoare's Law of Large Problems: Inside every large problem is a small
+ problem struggling to get out.}
+@end quotation
+
+Yahoo's database of stock market data is just one among the many large
+databases on the Internet. Another one is located at NCBI
+(National Center for Biotechnology
+Information). Established in 1988 as a national resource for molecular
+biology information, NCBI creates public databases, conducts research
+in computational biology, develops software tools for analyzing genome
+data, and disseminates biomedical information. In this section, we
+look at one of NCBI's public services, which is called BLAST
+(Basic Local Alignment Search Tool).
+
+You probably know that the information necessary for reproducing living
+cells is encoded in the genetic material of the cells. The genetic material
+is a very long chain of four base nucleotides. It is the order of
+appearance (the sequence) of nucleotides which contains the information
+about the substance to be produced. Scientists in biotechnology often
+find a specific fragment, determine the nucleotide sequence, and need
+to know where the sequence at hand comes from. This is where the large
+databases enter the game. At NCBI, databases store the knowledge
+about which sequences have ever been found and where they have been found.
+When the scientist sends his sequence to the BLAST service, the server
+looks for regions of genetic material in its database which
+look the most similar to the delivered nucleotide sequence. After a
+search time of some seconds or minutes the server sends an answer to
+the scientist. In order to make access simple, NCBI chose to offer
+their database service through popular Internet protocols. There are
+four basic ways to use the so-called BLAST services:
+
+@itemize @bullet
+@item
+The easiest way to use BLAST is through the web. Users may simply point
+their browsers at the NCBI home page
+and link to the BLAST pages.
+NCBI provides a stable URL that may be used to perform BLAST searches
+without interactive use of a web browser. This is what we will do later
+in this section.
+A demonstration client
+and a @file{README} file demonstrate how to access this URL.
+
+@item
+Currently,
+@command{blastcl3} is the standard network BLAST client.
+You can download @command{blastcl3} from the
+anonymous FTP location.
+
+@item
+BLAST 2.0 can be run locally as a full executable and can be used to run
+BLAST searches against private local databases, or downloaded copies of the
+NCBI databases. BLAST 2.0 executables may be found on the NCBI
+anonymous FTP server.
+
+@item
+The NCBI BLAST Email server is the best option for people without convenient
+access to the web. A similarity search can be performed by sending a properly
+formatted mail message containing the nucleotide or protein query sequence to
+@email{blast@@ncbi.nlm.nih.gov}. The query sequence is compared against the
+specified database using the BLAST algorithm and the results are returned in
+an email message. For more information on formulating email BLAST searches,
+you can send a message consisting of the word ``HELP'' to the same address,
+@email{blast@@ncbi.nlm.nih.gov}.
+@end itemize
+
+Our starting point is the demonstration client mentioned in the first option.
+The @file{README} file that comes along with the client explains the whole
+process in a nutshell. In the rest of this section, we first show
+what such requests look like. Then we show how to use @command{gawk} to
+implement a client in about 10 lines of code. Finally, we show how to
+interpret the result returned from the service.
+
+Sequences are expected to be represented in the standard
+IUB/IUPAC amino acid and nucleic acid codes,
+with these exceptions: lower-case letters are accepted and are mapped
+into upper-case; a single hyphen or dash can be used to represent a gap
+of indeterminate length; and in amino acid sequences, @samp{U} and @samp{*}
+are acceptable letters (see below). Before submitting a request, any numerical
+digits in the query sequence should either be removed or replaced by
+appropriate letter codes (e.g., @samp{N} for unknown nucleic acid residue
+or @samp{X} for unknown amino acid residue).
+The nucleic acid codes supported are:
+
+@example
+A --> adenosine M --> A C (amino)
+C --> cytidine S --> G C (strong)
+G --> guanine W --> A T (weak)
+T --> thymidine B --> G T C
+U --> uridine D --> G A T
+R --> G A (purine) H --> A C T
+Y --> T C (pyrimidine) V --> G C A
+K --> G T (keto) N --> A G C T (any)
+ - gap of indeterminate length
+@end example
+
+Now you know the alphabet of nucleotide sequences. The last two lines
+of the following example query show you such a sequence, which is obviously
+made up only of elements of the alphabet just described. Store this example
+query into a file named @file{protbase.request}. You are now ready to send
+it to the server with the demonstration client.
+
+@example
+@c file eg/network/protbase.request
+PROGRAM blastn
+DATALIB month
+EXPECT 0.75
+BEGIN
+>GAWK310 the gawking gene GNU AWK
+tgcttggctgaggagccataggacgagagcttcctggtgaagtgtgtttcttgaaatcat
+caccaccatggacagcaaa
+@c endfile
+@end example
+
+@cindex FASTA/Pearson format
+The actual search request begins with the mandatory parameter @samp{PROGRAM}
+in the first column followed by the value @samp{blastn} (the name of the
+program) for searching nucleic acids. The next line contains the mandatory
+search parameter @samp{DATALIB} with the value @samp{month} for the newest
+nucleic acid sequences. The third line contains an optional @samp{EXPECT}
+parameter and the value desired for it. The fourth line contains the
+mandatory @samp{BEGIN} directive, followed by the query sequence in
+FASTA/Pearson format.
+Each line of information must be less than 80 characters in length.
+
+The ``month'' database contains all new or revised sequences released in the
+last 30 days and is useful for searching against new sequences.
+There are five different blast programs, @command{blastn} being the one that
+compares a nucleotide query sequence against a nucleotide sequence database.
+
+The last server directive that must appear in every request is the
+@samp{BEGIN} directive. The query sequence should immediately follow the
+@samp{BEGIN} directive and must appear in FASTA/Pearson format.
+A sequence in
+FASTA/Pearson format begins with a single-line description.
+The description line, which is required, is distinguished from the lines of
+sequence data that follow it by having a greater-than (@samp{>}) symbol
+in the first column. For the purposes of the BLAST server, the text of
+the description is arbitrary.
+
+If you prefer to use a client written in @command{gawk}, just store the following
+10 lines of code into a file named @file{protbase.awk} and use this client
+instead. Invoke it with @samp{gawk -f protbase.awk protbase.request}.
+Then wait a minute and watch the result coming in. In order to replicate
+the demonstration client's behaviour as closely as possible, this client
+does not use a proxy server. We could also have extended the client program
+in @ref{GETURL, ,Retrieving Web Pages}, to implement the client request from
+@file{protbase.awk} as a special case.
+
+@smallexample
+@c file eg/network/protbase.awk
+@{ request = request "\n" $0 @}
+
+END @{
+ BLASTService = "/inet/tcp/0/www.ncbi.nlm.nih.gov/80"
+ printf "POST /cgi-bin/BLAST/nph-blast_report HTTP/1.0\n" |& BLASTService
+ printf "Content-Length: " length(request) "\n\n" |& BLASTService
+ printf request |& BLASTService
+ while ((BLASTService |& getline) > 0)
+ print $0
+ close(BLASTService)
+@}
+@c endfile
+@end smallexample
+
+The demonstration client from NCBI is 214 lines long (written in C) and
+it is not immediately obvious what it does. Our client is so short that
+it @emph{is} obvious what it does. First it loops over all lines of the
+query and stores the whole query into a variable. Then the script
+establishes an Internet connection to the NCBI server and transmits the
+query by framing it with a proper HTTP request. Finally it receives
+and prints the complete result coming from the server.
+
+Now, let us look at the result. It begins with an HTTP header, which you
+can ignore. Then there are some comments about the query having been
+filtered to avoid spuriously high scores. After this, there is a reference
+to the paper that describes the software being used for searching the data
+base. After a repitition of the original query's description we find the
+list of significant alignments:
+
+@smallexample
+@c file eg/network/protbase.result
+Sequences producing significant alignments: (bits) Value
+
+gb|AC021182.14|AC021182 Homo sapiens chromosome 7 clone RP11-733... 38 0.20
+gb|AC021056.12|AC021056 Homo sapiens chromosome 3 clone RP11-115... 38 0.20
+emb|AL160278.10|AL160278 Homo sapiens chromosome 9 clone RP11-57... 38 0.20
+emb|AL391139.11|AL391139 Homo sapiens chromosome X clone RP11-35... 38 0.20
+emb|AL365192.6|AL365192 Homo sapiens chromosome 6 clone RP3-421H... 38 0.20
+emb|AL138812.9|AL138812 Homo sapiens chromosome 11 clone RP1-276... 38 0.20
+gb|AC073881.3|AC073881 Homo sapiens chromosome 15 clone CTD-2169... 38 0.20
+@c endfile
+@end smallexample
+
+This means that the query sequence was found in seven human chromosomes.
+But the value 0.20 (20%) means that the probability of an accidental match
+is rather high (20%) in all cases and should be taken into account.
+You may wonder what the first column means. It is a key to the specific
+database in which this occurence was found. The unique sequence identifiers
+reported in the search results can be used as sequence retrieval keys
+via the NCBI server. The syntax of sequence header lines used by the NCBI
+BLAST server depends on the database from which each sequence was obtained.
+The table below lists the identifiers for the databases from which the
+sequences were derived.
+
+@ifinfo
+@example
+Database Name Identifier Syntax
+============================ ========================
+GenBank gb|accession|locus
+EMBL Data Library emb|accession|locus
+DDBJ, DNA Database of Japan dbj|accession|locus
+NBRF PIR pir||entry
+Protein Research Foundation prf||name
+SWISS-PROT sp|accession|entry name
+Brookhaven Protein Data Bank pdb|entry|chain
+Kabat's Sequences of Immuno@dots{} gnl|kabat|identifier
+Patents pat|country|number
+GenInfo Backbone Id bbs|number
+@end example
+@end ifinfo
+
+@ifnotinfo
+@multitable {Kabat's Sequences of Immuno@dots{}} {@code{@w{sp|accession|entry name}}}
+@item GenBank @tab @code{gb|accession|locus}
+@item EMBL Data Library @tab @code{emb|accession|locus}
+@item DDBJ, DNA Database of Japan @tab @code{dbj|accession|locus}
+@item NBRF PIR @tab @code{pir||entry}
+@item Protein Research Foundation @tab @code{prf||name}
+@item SWISS-PROT @tab @code{@w{sp|accession|entry name}}
+@item Brookhaven Protein Data Bank @tab @code{pdb|entry|chain}
+@item Kabat's Sequences of Immuno@dots{} @tab @code{gnl|kabat|identifier}
+@item Patents @tab @code{pat|country|number}
+@item GenInfo Backbone Id @tab @code{bbs|number}
+@end multitable
+@end ifnotinfo
+
+
+For example, an identifier might be @samp{gb|AC021182.14|AC021182}, where the
+@samp{gb} tag indicates that the identifier refers to a GenBank sequence,
+@samp{AC021182.14} is its GenBank ACCESSION, and @samp{AC021182} is the GenBank LOCUS.
+The identifier contains no spaces, so that a space indicates the end of the
+identifier.
+
+Let us continue in the result listing. Each of the seven alignments mentioned
+above is subsequently described in detail. We will have a closer look at
+the first of them.
+
+@smallexample
+>gb|AC021182.14|AC021182 Homo sapiens chromosome 7 clone RP11-733N23, WORKING DRAFT SEQUENCE, 4
+ unordered pieces
+ Length = 176383
+
+ Score = 38.2 bits (19), Expect = 0.20
+ Identities = 19/19 (100%)
+ Strand = Plus / Plus
+
+Query: 35 tggtgaagtgtgtttcttg 53
+ |||||||||||||||||||
+Sbjct: 69786 tggtgaagtgtgtttcttg 69804
+@end smallexample
+
+This alignment was located on the human chromosome 7. The fragment on which
+part of the query was found had a total length of 176383. Only 19 of the
+nucleotides matched and the matching sequence ran from character 35 to 53
+in the query sequence and from 69786 to 69804 in the fragment on chromosome 7.
+If you are still reading at this point, you are probably interested in finding
+out more about Computational Biology and you might appreciate the following
+hints.
+
+@cindex Computational Biology
+@cindex Bioinformatics
+@enumerate
+@item
+There is a book called @cite{Introduction to Computational Biology}
+by Michael S. Waterman, which is worth reading if you are seriously
+interested. You can find a good
+book review
+on the Internet.
+
+@item
+While Waterman's book can explain to you the algorithms employed internally
+in the database search engines, most practicioners prefer to approach
+the subject differently. The applied side of Computational Biology is
+called Bioinformatics, and emphasizes the tools available for day-to-day
+work as well as how to actually @emph{use} them. One of the very few affordable
+books on Bioinformatics is
+@cite{Developing Bioinformatics Computer Skills}.
+
+@item
+The sequences @emph{gawk} and @emph{gnuawk} are in widespread use in
+the genetic material of virtually every earthly living being. Let us
+take this as a clear indication that the divine creator has intended
+@code{gawk} to prevail over other scripting languages such as @code{perl},
+@code{tcl}, or @code{python} which are not even proper sequences. (:-)
+@end enumerate
+
+@node Links, GNU Free Documentation License, Some Applications and Techniques, Top
+@chapter Related Links
+
+This section lists the URLs for various items discussed in this @value{CHAPTER}.
+They are presented in the order in which they appear.
+
+@table @asis
+
+@item @cite{Internet Programming with Python}
+@uref{http://www.fsbassociates.com/books/python.htm}
+
+@item @cite{Advanced Perl Programming}
+@uref{http://www.oreilly.com/catalog/advperl}
+
+@item @cite{Web Client Programming with Perl}
+@uref{http://www.oreilly.com/catalog/webclient}
+
+@item Richard Stevens's home page and book
+@uref{http://www.kohala.com/~rstevens}
+
+@item The SPAK home page
+@uref{http://www.userfriendly.net/linux/RPM/contrib/libc6/i386/spak-0.6b-1.i386.html}
+
+@item Volume III of @cite{Internetworking with TCP/IP}, by Comer and Stevens
+@uref{http://www.cs.purdue.edu/homes/dec/tcpip3s.cont.html}
+
+@item XBM Graphics File Format
+@uref{http://www.wotsit.org/download.asp?f=xbm}
+
+@item GNUPlot
+@uref{http://www.cs.dartmouth.edu/gnuplot_info.html}
+
+@item Mark Humphrys' Eliza page
+@uref{http://www.compapp.dcu.ie/~humphrys/eliza.html}
+
+@item Yahoo! Eliza Information
+@uref{http://dir.yahoo.com/Recreation/Games/Computer_Games/Internet_Games/Web_Games/Artificial_Intelligence}
+
+@item Java versions of Eliza
+@uref{http://www.tjhsst.edu/Psych/ch1/eliza.html}
+
+@item Java versions of Eliza with source code
+@uref{http://home.adelphia.net/~lifeisgood/eliza/eliza.htm}
+
+@item Eliza Programs with Explanations
+@uref{http://chayden.net/chayden/eliza/Eliza.shtml}
+
+@item Loebner Contest
+@uref{http://acm.org/~loebner/loebner-prize.htmlx}
+
+@item Tck/Tk Information
+@uref{http://www.scriptics.com/}
+
+@item Intel 80x86 Processors
+@uref{http://developer.intel.com/design/platform/embedpc/what_is.htm}
+
+@item AMD Elan Processors
+@uref{http://www.amd.com/products/epd/processors/4.32bitcont/32bitcont/index.html}
+
+@item XINU
+@uref{http://willow.canberra.edu.au/~chrisc/xinu.html }
+
+@item GNU/Linux
+@uref{http://uclinux.lineo.com/}
+
+@item Embedded PCs
+@uref{http://dir.yahoo.com/Business_and_Economy/Business_to_Business/Computers/Hardware/Embedded_Control/}
+
+@item MiniSQL
+@uref{http://www.hughes.com.au/library/}
+
+@item Market Share Surveys
+@uref{http://www.netcraft.com/survey}
+
+@item @cite{Numerical Recipes in C: The Art of Scientific Computing}
+@uref{http://www.nr.com}
+
+@item VRML
+@uref{http://www.vrml.org}
+
+@item The VRML FAQ
+@uref{http://www.vrml.org/technicalinfo/specifications/specifications.htm#FAQ}
+
+@item The UMBC Agent Web
+@uref{http://www.cs.umbc.edu/agents }
+
+@item Apache Web Server
+@uref{http://www.apache.org}
+
+@item National Center for Biotechnology Information (NCBI)
+@uref{http://www.ncbi.nlm.nih.gov}
+
+@item Basic Local Alignment Search Tool (BLAST)
+@uref{http://www.ncbi.nlm.nih.gov/BLAST/blast_overview.html}
+
+@item NCBI Home Page
+@uref{http://www.ncbi.nlm.nih.gov}
+
+@item BLAST Pages
+@uref{http://www.ncbi.nlm.nih.gov/BLAST}
+
+@item BLAST Demonstration Client
+@uref{ftp://ncbi.nlm.nih.gov/blast/blasturl/}
+
+@item BLAST anonymous FTP location
+@uref{ftp://ncbi.nlm.nih.gov/blast/network/netblast/}
+
+@item BLAST 2.0 Executables
+@uref{ftp://ncbi.nlm.nih.gov/blast/executables/}
+
+@item IUB/IUPAC Amino Acid and Nucleic Acid Codes
+@uref{http://www.uthscsa.edu/geninfo/blastmail.html#item6}
+
+@item FASTA/Pearson Format
+@uref{http://www.ncbi.nlm.nih.gov/BLAST/fasta.html}
+
+@item Fasta/Pearson Sequence in Java
+@uref{http://www.kazusa.or.jp/java/codon_table_java/}
+
+@item Book Review of @cite{Introduction to Computational Biology}
+@uref{http://www.acm.org/crossroads/xrds5-1/introcb.html}
+
+@item @cite{Developing Bioinformatics Computer Skills}
+@uref{http://www.oreilly.com/catalog/bioskills/}
+
+@end table
+
+@node GNU Free Documentation License
+@unnumbered GNU Free Documentation License
+
+@cindex FDL (Free Documentation License)
+@cindex Free Documentation License (FDL)
+@cindex GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warrany Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@c fakenode --- for prepinfo
+@unnumberedsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
+
+@node Index, , GNU Free Documentation License, Top
+@comment node-name, next, previous, up
+
+@unnumbered Index
+@printindex cp
+@bye
+
+Conventions:
+1. Functions, built-in or otherwise, do NOT have () after them.
+2. Gawk built-in vars and functions are in @code. Also program vars and
+ functions.
+3. HTTP method names are in @code.
+4. Protocols such as echo, ftp, etc are in @samp.
+5. URLs are in @url.
+6. All RFC's in the index. Put a space between `RFC' and the number.
--- /dev/null
+.TH IGAWK 1 "Nov 3 1999" "Free Software Foundation" "Utility Commands"
+.SH NAME
+igawk \- gawk with include files
+.SH SYNOPSIS
+.B igawk
+[ all
+.I gawk
+options ]
+.B \-f
+.I program-file
+[
+.B \-\^\-
+] file .\^.\^.
+.br
+.B igawk
+[ all
+.I gawk
+options ]
+[
+.B \-\^\-
+]
+.I program-text
+file .\^.\^.
+.SH DESCRIPTION
+.I Igawk
+is a simple shell script that adds the ability to have ``include files'' to
+.IR gawk (1).
+.PP
+AWK programs for
+.I igawk
+are the same as for
+.IR gawk ,
+except that, in addition, you may have lines like
+.RS
+.sp
+.ft B
+@include getopt.awk
+.ft R
+.sp
+.RE
+in your program to include the file
+.B getopt.awk
+from either the current directory or one of the other directories
+in the search path.
+.SH OPTIONS
+See
+.IR gawk (1)
+for a full description of the AWK language and the options that
+.I gawk
+supports.
+.SH EXAMPLES
+.nf
+.ft B
+cat << EOF > test.awk
+@include getopt.awk
+.sp
+BEGIN {
+ while (getopt(ARGC, ARGV, "am:q") != \-1)
+ \&.\^.\^.
+}
+EOF
+.sp
+igawk \-f test.awk
+.ft R
+.fi
+.SH SEE ALSO
+.IR gawk (1)
+.PP
+.IR "Effective AWK Programming" ,
+Edition 1.0, published by the Free Software Foundation, 1995.
+.SH AUTHOR
+Arnold Robbins
+.RB ( arnold@skeeve.com ).
--- /dev/null
+%!
+%%Creator: arnold@skeeve (Aharon Robbins)
+%%Title: rflashlight.small.xpic (xpic)
+%%CreationDate: Tue Dec 12 09:51:27 2000
+%%Pages: 1
+%%BoundingBox: 0 0 72 28.8
+% (in inches) at 0 0, width 1, height 0.4
+%%EndComments
+% Prolog for xpic to PostScript converter
+% Author: Mark Moraes
+% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp
+% %d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
+% %s F - change font to fontname
+% %d S - change size (font size in points)
+% (%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
+% (%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
+% (%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
+% %d %d l - lineto
+% %d %d m - moveto
+% %d %d s - spline segment
+% x - flush line, spline
+% <wid> <ht> <x> <y> b - box
+% <wid> <ht> <x> <y> e - ellipse
+% %d ss - setscale
+% %d W - change linewidth
+% getpagesize - gets the values of PAGEHEIGHT and PAGEWIDTH
+% %d %d flip - translate by %d, PAGEHEIGHT - %d (this
+% transforms to X windows coordinates)
+save 50 dict begin /xpic exch def
+/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
+% Set defaults
+/fontname /Times-Roman def
+/ptsize 12 def
+% halign has the values for MIDLINE, TOPLINE, BOTLINE
+/halign 3 array def
+/s {rcurveto} def
+/x {stroke} def
+/l {lineto} def
+/m {moveto} def
+/b {
+ /ury exch def /urx exch def /lly exch def /llx exch def
+ llx lly moveto urx lly lineto urx ury lineto
+ llx ury lineto llx lly lineto stroke
+} def
+/mtrx matrix def
+/e {
+ /yc exch def /xc exch def /yrad exch def /xrad exch def
+ xc xrad add yc moveto
+ /savematrix mtrx currentmatrix def
+ xc yc translate
+ xrad yrad scale
+ 0 0 1 0 360 arc
+ savematrix setmatrix stroke
+} def
+% The next three take the text string, and moveto the right horiz. position
+% leaving the string on the stack.
+/lj {} def
+/rj {dup stringwidth pop neg 0 rmoveto} def
+/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
+% And this is invoked after one of the three above, and
+% computes the vert. pos, and then displays the string.
+/t {halign exch get 0 exch rmoveto show newpath} def
+% Store an array of patterns in /styles - a pattern is an array consisting
+% of an array and an offset. Corresp to xpic patterns
+% solid, dotted, short-dashed, long-dashed, dot-dashed
+/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
+ 5 array astore def
+% change style to arg.
+/D {stroke styles exch get aload pop setdash newpath} def
+/W {stroke 0.5 mul setlinewidth newpath} def
+% fontbox takes a fontname off the stack, and returns an array
+% containing the values of the bottom line of the bounding box, the
+% mid line of the bounding box, and the top line of the bounding box
+% of that font, taken from the baseline, scaled to a font of size 1
+/fontbox {
+ findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
+ /ytop exch def pop /ybot exch def pop
+ /ymid ytop ybot sub 2 div def
+ 0 ybot fm dtransform exch pop % botline
+ dup neg exch % midline - this works better than (ytop-ybot)/2!
+ 0 ytop fm dtransform exch pop exch %topline
+ % now in the order midline, topline, botline.
+ 3 array astore
+} def
+% select font
+/F {
+ dup /fontname exch def fontbox
+ /thisfontbox exch def SF
+} def
+% set point size
+/S {/ptsize exch def SF} def
+% actually set font
+/SF {
+ fontname findfont ptsize curscale div scalefont setfont
+ thisfontbox aload pop
+ 1 1 3 {
+ pop ptsize mul curscale div neg 3 1 roll
+ } for
+ halign astore pop
+} def
+% sets the scale to 72 / n, where n is on the stack, and stores the value
+% in curscale for font scaling
+/curscale 1 def
+/getpagesize{newpath clippath pathbbox /pageheight exch def
+ /pagewidth exch def pop pop newpath} def
+/flip{pageheight exch sub translate} def
+/ss {/curscale exch 72 exch div dup dup scale def} def
+/land {90 rotate} def
+StartXpic
+%%EndProlog
+80 ss
+0.5 W
+0 D
+80 32 m
+64 24 l
+x
+32 24 m
+56 32 l
+x
+32 8 m
+56 0 l
+x
+8 16 56 16 e
+0 24 32 8 b
+64 16 m
+80 16 l
+x
+64 8 m
+80 0 l
+x
+%%Trailer
+showpage
+% Trailer for xpic to PostScript converter
+% $Header: x2ps.tra,v 1.2 89/07/02 15:59:53 moraes Exp $
+xpic end restore
--- /dev/null
+.\" SSC Reference card macros
+.\"
+.\" Copyright (C) 1996, Specialized System Consultants Inc. (SSC)
+.\"
+.\" These macros are free software; you can redistribute them and/or modify
+.\" them under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" These macros are distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+.\"
+.\" Generic SSC "card" macros
+.\" based on lots of other macros
+.\" Last update: 4-25-91 ph
+.\" attempting to get margins in the boxes Aug 3 09:43:48 PDT 1994
+.ll 3i \" length of text line
+.lt 3.2i \" length of title line
+.de BT \" bottom of page trap
+.sp |8.2i \" go to where we put footer
+.ie \\n(CL=1 \{\
+. nr CL 2
+.tl ''\\*(CD\\n+(PN'' \" footer is just page number
+. po 4i \" go to second column
+.TP \" print header if any
+\}
+.el \{\
+. nr CL 1
+.tl ''\\*(CD\\n+(PN'' \" footer is just page number
+. po .5i \" go to first column
+. bp \" force a new page (which will force header)
+. TP
+\}
+..
+.de TP \" top of page
+.\" .sp |.2i
+.sp |0
+.\" put page header stuff here
+.\" for example: .tl ''WOW!''
+.\".sp
+..
+.\" .wh 8.1i BT \" set bottom of column trap
+.nf \" don't fill lines
+.nh \" no hyphenation
+.nr CL 1 \" start with column = 1
+.po .5i \" offset for first column
+.vs 9 \" line spacing
+.ps 8 \" point size
+.de ST \" set tabs to normal places
+.ta .2i .78i 1.2i 1.7i \" set tabs
+..
+.ig
+ From: bryang@chinet.chi.il.us (Bryan Glennon)
+ Box macro. Do a .mk z where the box is to start, and a .eb
+ where it is to end. Optional argument is a title to be centered
+ within the top box line.
+
+ Usage:
+
+ .mk z
+ Text, etc to be boxed...
+ .eb "Optional title goes here"
+
+ ~or~
+
+ .mk z
+ Text, etc to be boxed...
+ .eb
+
+
+ Some explanation:
+ The macro name is eb <.de eb>. First thing we do is to go up on line
+ <.sp -1> and turn off fill mode <.nf>. Now it gets interesting: the
+ .ie is the if/else construct. We check the number of arguments provided
+ to the macro <\\n(.$> and if it is greater than 0 (meaning we have a title),
+ we do the rest of the .ie line, as follows:
+
+ \h'-.5n' - move left one-half of an n
+ \L'|\\nzu-1' - draw a vertical line <\L> to the
+ absolute position (|) given by \\nzu-1,
+ which is the position set with the .mk
+ command into register z <\\nz> in base
+ units <u> minus 1.
+ \l'(\\n(.lu+1n-\w'\\$1'u/2u)\(ul' - Draw a horizontal line <\l> with length
+ equal to the current line length
+ <\\n(.l> in base units <u> plus the
+ space required for an 'n' <1n>, minus
+ the width <\w> of the title string
+ <\\$1> in base units <u> divided by 2
+ <in base units <u>>. Draw the line
+ using the underline character, <\(ul>.
+ \v'.3m'\|\\$1\|\v'-.3m' - Move down the page 3/10 of an m,
+ <\v'.3m'>, output a 1/6 of an m space
+ <\|>, output the title <\\$1>, another
+ 1/6 of an m space <\|>, and then move
+ up the page 3/10 of an m <\v'-.3m'>.
+ \l'...\(ul' - Draw the second part of the line, just
+ like the corresponding left half done
+ before.
+ \L'-|\\nzu+1' - Draw a verticle line <\L> going down
+ the absolute distance <-|> from where
+ the macro was given to where the start
+ point was marked <\\nz> in base units
+ <u> plus one line <+1>
+ \l'|0u-.5n\(ul' - Draw a horizontal line to the absolute
+ position (|0) when the macro was
+ invoked, minus half an n <-.5n> using
+ the underline character <\(ul>.
+
+ The .el beings the else part, which is identical to the above, except
+ the string dosen't get printed. This makes the printing of the top
+ line much easier: just draw a line <\l> with width equal to the
+ current line plus the witdh of an n <\\n(.l+1n> using the underline
+ character <.\(ul>.
+..
+.de ES \" start "text in a box"
+.mk z
+.in +.5n
+.ll -.5n
+.sp 1.3
+..
+.de EB \" end "text in a box" -- optional box title as argument
+.sp -.6
+.nf
+.in -.5n
+.ll +.5n
+.ie \\n(.$\
+\L'|\\nzu'\
+\l'(\\n(.lu-\w'\\$1'u)/2u-.33m\(ul'\
+\v'.3m'\|\\$1\|\v'-.3m'\
+\l'(\\n(.lu-\w'\\$1'u)/2u\(ul'\
+\L'-|\\nzu'\
+\l'|0u\(ul'
+.el \h'-.5n'\L'|\\nzu-1'\l'\\n(.lu+1n\(ul'\L'-|\\nzu+1'\l'|0u-.5n\(ul'
+.in 0
+..
+.de SL \" draw single line (works in non-fill mode only)
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+..
+.de Hl \" draw horizontal line
+.br
+.ti 0
+\l'\\n(.lu-\\n(.iu'
+.br
+..
+.de DL \" draw double line (works in non-fill mode only)
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+..
+.ST
+.nr PN 0 1 \" sets starting page number and auto-increment
+.\" must define page header (if any) before here
+.TP
+.ds 3) \|\v'3p'\s+5\z\(sq\s0\v'-3p'\h'1.25p'\v'-.5p'3\v'.5p'\h'2p'
+.\" old one .ds 2) \h'-1.5p'\v'1p'\s+4\z\(ci\s0\v'-1p'\h'3.25p'2
+.ds 2) \|\v'-2.4p'\D'c.095id'\h'-5.15p'\v'2.4p'2\h'1.9p'
+.ds dC \v'1p'\s+5\(bu\s0\v'-1p'\" for development commands
+.ds tC \s+2\(dm\s0\" (for DWB) should be a triangle
+.ds tP \s+2\(dm\s0\" (for other text processing) should be a triangle
+.\" various trademark symbols
+.ds Tm \v'-0.5m'\s8TM\s0\v'0.5m'
+.ds Ts \v'-0.5m'\s4TM\s0\v'0.5m'
+.ig ++
+.\" mount Serifa fonts
+.fp 5 SR
+.fp 6 SB
+.fp 4 Si
+.++
+.\" other assorted junk
+.lg 0
+.\" Fl requires extended version of troff
+.de Fl \" draw fat horizontal line
+.br
+.ti 0
+.ruw 1.5p
+\l'\\n(.lu-\\n(.iu'
+.br
+.ruw
+..
+.de Bx \" box for keys in text
+\\$3\&\|\&\c
+\s-3\(br\|\fH\v'.18n'\\$1\v'-.18n\fP\|\(br\l'|0\(rn'\l'|0\(ul'\&\s0\|\\$2
+..
+.de Fn \" function name - left justified, gray background
+.\" bold with gray for function name
+.ns
+.br
+\
+.ns
+.br
+\!! gsave ( ) stringwidth neg 0 rmoveto
+\!! /Serifa-Bold findfont 8 scalefont setfont
+\!! (\\$1) dup stringwidth pop 6 gsave dup 0 exch rlineto neg exch 0 rlineto
+\!! 0 exch rlineto closepath .9 setgray fill grestore show
+\!! grestore
+.nf
+.rs
+..
+.rs
--- /dev/null
+.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
+.\" This file is for troff which does not know what to do
+.\" with literal Poscript and cannot use the macros from 'colors'.
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ds CR
+.ds CG
+.ds CL
+.ds CB
+.ds CD
+.ds CX
--- /dev/null
+%!
+%%Creator: arnold@skeeve (Aharon Robbins)
+%%Title: flashlight.small.xpic (xpic)
+%%CreationDate: Tue Oct 24 14:41:28 2000
+%%Pages: 1
+%%BoundingBox: 0 0 72 28.8
+% (in inches) at 0 0, width 1, height 0.4
+%%EndComments
+% Prolog for xpic to PostScript converter
+% Author: Mark Moraes
+% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp
+% %d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
+% %s F - change font to fontname
+% %d S - change size (font size in points)
+% (%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
+% (%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
+% (%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
+% %d %d l - lineto
+% %d %d m - moveto
+% %d %d s - spline segment
+% x - flush line, spline
+% <wid> <ht> <x> <y> b - box
+% <wid> <ht> <x> <y> e - ellipse
+% %d ss - setscale
+% %d W - change linewidth
+% getpagesize - gets the values of PAGEHEIGHT and PAGEWIDTH
+% %d %d flip - translate by %d, PAGEHEIGHT - %d (this
+% transforms to X windows coordinates)
+save 50 dict begin /xpic exch def
+/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
+% Set defaults
+/fontname /Times-Roman def
+/ptsize 12 def
+% halign has the values for MIDLINE, TOPLINE, BOTLINE
+/halign 3 array def
+/s {rcurveto} def
+/x {stroke} def
+/l {lineto} def
+/m {moveto} def
+/b {
+ /ury exch def /urx exch def /lly exch def /llx exch def
+ llx lly moveto urx lly lineto urx ury lineto
+ llx ury lineto llx lly lineto stroke
+} def
+/mtrx matrix def
+/e {
+ /yc exch def /xc exch def /yrad exch def /xrad exch def
+ xc xrad add yc moveto
+ /savematrix mtrx currentmatrix def
+ xc yc translate
+ xrad yrad scale
+ 0 0 1 0 360 arc
+ savematrix setmatrix stroke
+} def
+% The next three take the text string, and moveto the right horiz. position
+% leaving the string on the stack.
+/lj {} def
+/rj {dup stringwidth pop neg 0 rmoveto} def
+/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
+% And this is invoked after one of the three above, and
+% computes the vert. pos, and then displays the string.
+/t {halign exch get 0 exch rmoveto show newpath} def
+% Store an array of patterns in /styles - a pattern is an array consisting
+% of an array and an offset. Corresp to xpic patterns
+% solid, dotted, short-dashed, long-dashed, dot-dashed
+/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
+ 5 array astore def
+% change style to arg.
+/D {stroke styles exch get aload pop setdash newpath} def
+/W {stroke 0.5 mul setlinewidth newpath} def
+% fontbox takes a fontname off the stack, and returns an array
+% containing the values of the bottom line of the bounding box, the
+% mid line of the bounding box, and the top line of the bounding box
+% of that font, taken from the baseline, scaled to a font of size 1
+/fontbox {
+ findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
+ /ytop exch def pop /ybot exch def pop
+ /ymid ytop ybot sub 2 div def
+ 0 ybot fm dtransform exch pop % botline
+ dup neg exch % midline - this works better than (ytop-ybot)/2!
+ 0 ytop fm dtransform exch pop exch %topline
+ % now in the order midline, topline, botline.
+ 3 array astore
+} def
+% select font
+/F {
+ dup /fontname exch def fontbox
+ /thisfontbox exch def SF
+} def
+% set point size
+/S {/ptsize exch def SF} def
+% actually set font
+/SF {
+ fontname findfont ptsize curscale div scalefont setfont
+ thisfontbox aload pop
+ 1 1 3 {
+ pop ptsize mul curscale div neg 3 1 roll
+ } for
+ halign astore pop
+} def
+% sets the scale to 72 / n, where n is on the stack, and stores the value
+% in curscale for font scaling
+/curscale 1 def
+/getpagesize{newpath clippath pathbbox /pageheight exch def
+ /pagewidth exch def pop pop newpath} def
+/flip{pageheight exch sub translate} def
+/ss {/curscale exch 72 exch div dup dup scale def} def
+/land {90 rotate} def
+StartXpic
+%%EndProlog
+80 ss
+0.5 W
+0 D
+8 16 24 16 e
+24 32 m
+48 24 l
+x
+24 0 m
+48 8 l
+x
+48 24 m
+0 0 0 -5.33333 0 -16 s
+x
+48 24 80 8 b
+0 8 m
+0 8 l
+x
+0 0 m
+16 8 l
+x
+0 16 m
+16 16 l
+x
+16 24 m
+0 32 l
+x
+%%Trailer
+showpage
+% Trailer for xpic to PostScript converter
+% $Header: x2ps.tra,v 1.2 89/07/02 15:59:53 moraes Exp $
+xpic end restore
--- /dev/null
+%!PS-Adobe-3.0
+% SSC Reference card typesetter outline / cut marks
+%
+% Copyright (C) 1996, Specialized System Consultants Inc. (SSC)
+%
+% This file is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2 of the License, or
+% (at your option) any later version.
+%
+% This file is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+%
+%! page cut marks and stuff for Pocket References - 10-26-88 - ph
+%! modified to move the cut marks onto the page
+%! center a string
+/inch {72 mul} def
+/cshow % stk: string
+ % center string in space (space us variable)
+ {
+ dup stringwidth pop % get length of string
+ space exch sub 2 div % compute initial space needed
+ 0 rmoveto % move over
+ show
+ } def
+
+/flashme
+{ /space 612 def
+ 0 0 0 setrgbcolor % always print this stuff
+
+ /Helvetica findfont 12 scalefont setfont
+ gsave
+% for groff (I hope)
+ -6 -6 translate
+ 0.2 setlinewidth
+
+ 0.25 inch 10.5 inch moveto
+ 0.5 inch 10.5 inch lineto
+ .75 inch 10.75 inch moveto
+ .75 inch 11 inch lineto
+ stroke
+
+ 0.25 inch 2 inch moveto
+ 0.5 inch 2 inch lineto
+ .75 inch 1.75 inch moveto
+ .75 inch 1.50 inch lineto
+ stroke
+ 4.25 inch 11 inch moveto
+ 4.25 inch 10.75 inch lineto
+ stroke
+
+ 4.25 inch 1.75 inch moveto
+ 4.25 inch 1.5 inch lineto
+ stroke
+
+ 7.75 inch 1.5 inch moveto
+ 7.75 inch 1.75 inch lineto
+ 8 inch 2 inch moveto
+ 8.25 inch 2 inch lineto
+ stroke
+
+ 7.75 inch 11 inch moveto
+ 7.75 inch 10.75 inch lineto
+ 8 inch 10.5 inch moveto
+ 8.25 inch 10.5 inch lineto
+ stroke
+ grestore
+ } def
+
+% actually do something
+
--- /dev/null
+%!PS-Adobe-2.0
+%%Creator: gnuplot 3.7 patchlevel 0.1
+%%CreationDate: Sun Jan 7 14:23:12 2001
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 554 770
+%%Orientation: Portrait
+%%Pages: (atend)
+%%EndComments
+/gnudict 256 dict def
+gnudict begin
+/Color true def
+/Solid false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/vshift -46 def
+/dl {10 mul} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow { currentpoint stroke M
+ 0 vshift R show } def
+/Rshow { currentpoint stroke M
+ dup stringwidth pop neg vshift R show } def
+/Cshow { currentpoint stroke M
+ dup stringwidth pop -2 div vshift R show } def
+/UP { dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+ /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def } def
+/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }
+ {pop pop pop Solid {pop []} if 0 setdash} ifelse } def
+/BL { stroke gnulinewidth 2 mul setlinewidth } def
+/AL { stroke gnulinewidth 2 div setlinewidth } def
+/UL { gnulinewidth mul /userlinewidth exch def } def
+/PL { stroke userlinewidth setlinewidth } def
+/LTb { BL [] 0 0 0 DL } def
+/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def
+/LT0 { PL [] 1 0 0 DL } def
+/LT1 { PL [4 dl 2 dl] 0 1 0 DL } def
+/LT2 { PL [2 dl 3 dl] 0 0 1 DL } def
+/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def
+/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def
+/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def
+/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def
+/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def
+/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def
+/Pnt { stroke [] 0 setdash
+ gsave 1 setlinecap M 0 0 V stroke grestore } def
+/Dia { stroke [] 0 setdash 2 copy vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath stroke
+ Pnt } def
+/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V
+ currentpoint stroke M
+ hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath stroke
+ Pnt } def
+/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M
+ hpt2 vpt2 neg V currentpoint stroke M
+ hpt2 neg 0 R hpt2 vpt2 V stroke } def
+/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath stroke
+ Pnt } def
+/Star { 2 copy Pls Crs } def
+/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath fill } def
+/TriUF { stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath fill } def
+/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath stroke
+ Pnt } def
+/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF { stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath fill } def
+/Pent { stroke [] 0 setdash 2 copy gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath stroke grestore Pnt } def
+/PentF { stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath fill grestore } def
+/Circle { stroke [] 0 setdash 2 copy
+ hpt 0 360 arc stroke Pnt } def
+/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def
+/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def
+/C1 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C2 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 180 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C3 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 180 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C4 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 180 270 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C5 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc
+ 2 copy moveto
+ 2 copy vpt 180 270 arc closepath fill
+ vpt 0 360 arc } bind def
+/C6 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 270 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C7 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 270 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C8 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 270 360 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C9 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 270 450 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 90 180 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C11 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 180 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 270 360 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C12 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 180 360 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C13 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 180 360 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/C14 { BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 360 arc closepath fill
+ vpt 0 360 arc } bind def
+/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+ vpt 0 360 arc closepath } bind def
+/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+ neg 0 rlineto closepath } bind def
+/Square { dup Rec } bind def
+/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def
+/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def
+/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def
+/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def
+/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def
+/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def
+/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill
+ exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def
+/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def
+/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+ 2 copy vpt Square fill
+ Bsquare } bind def
+/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def
+/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def
+/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+ Bsquare } bind def
+/S11 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+ Bsquare } bind def
+/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def
+/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+ 2 copy vpt Square fill Bsquare } bind def
+/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+ 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def
+/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def
+/D0 { gsave translate 45 rotate 0 0 S0 stroke grestore } bind def
+/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def
+/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def
+/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def
+/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def
+/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def
+/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def
+/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def
+/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def
+/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def
+/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def
+/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def
+/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def
+/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def
+/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def
+/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def
+/DiaE { stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath stroke } def
+/BoxE { stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath stroke } def
+/TriUE { stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath stroke } def
+/TriDE { stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath stroke } def
+/PentE { stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath stroke grestore } def
+/CircE { stroke [] 0 setdash
+ hpt 0 360 arc stroke } def
+/Opaque { gsave closepath 1 setgray fill grestore 0 setgray closepath } def
+/DiaW { stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V Opaque stroke } def
+/BoxW { stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V Opaque stroke } def
+/TriUW { stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V Opaque stroke } def
+/TriDW { stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V Opaque stroke } def
+/PentW { stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ Opaque stroke grestore } def
+/CircW { stroke [] 0 setdash
+ hpt 0 360 arc Opaque stroke } def
+/BoxFill { gsave Rec 1 setgray fill grestore } def
+end
+%%EndProlog
+%%Page: 1 1
+gnudict begin
+gsave
+50 50 translate
+0.100 0.100 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+1.000 UL
+LTb
+574 280 M
+63 0 V
+4165 0 R
+-63 0 V
+490 280 M
+(-0.3) Rshow
+574 1245 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(-0.2) Rshow
+574 2209 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(-0.1) Rshow
+574 3174 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(0) Rshow
+574 4138 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(0.1) Rshow
+574 5103 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(0.2) Rshow
+574 6067 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(0.3) Rshow
+574 7032 M
+63 0 V
+4165 0 R
+-63 0 V
+-4249 0 R
+(0.4) Rshow
+574 280 M
+0 63 V
+0 6689 R
+0 -63 V
+574 140 M
+(-10) Cshow
+1631 280 M
+0 63 V
+0 6689 R
+0 -63 V
+0 -6829 R
+(-5) Cshow
+2688 280 M
+0 63 V
+0 6689 R
+0 -63 V
+0 -6829 R
+(0) Cshow
+3745 280 M
+0 63 V
+0 6689 R
+0 -63 V
+0 -6829 R
+(5) Cshow
+4802 280 M
+0 63 V
+0 6689 R
+0 -63 V
+0 -6829 R
+(10) Cshow
+1.000 UL
+LTb
+574 280 M
+4228 0 V
+0 6752 V
+-4228 0 V
+574 280 L
+2688 2209 M
+(p\(m1=m2\) =0.0863798346775753) Lshow
+2688 1245 M
+(p\(v1=v2\) =0.31647637745891) Lshow
+1.000 UL
+LT0
+4151 6899 M
+(sample 1) Rshow
+4235 6899 M
+399 0 V
+574 3174 M
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 1 V
+43 2 V
+43 4 V
+42 8 V
+43 13 V
+43 24 V
+42 41 V
+43 65 V
+43 101 V
+43 146 V
+42 205 V
+43 271 V
+43 340 V
+42 404 V
+43 450 V
+43 470 V
+43 452 V
+42 390 V
+43 288 V
+43 153 V
+42 0 V
+43 -153 V
+43 -288 V
+42 -390 V
+43 -452 V
+43 -470 V
+43 -450 V
+42 -404 V
+43 -340 V
+43 -271 V
+42 -205 V
+43 -146 V
+43 -101 V
+43 -65 V
+42 -41 V
+43 -24 V
+43 -13 V
+42 -8 V
+43 -4 V
+43 -2 V
+42 -1 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+1.000 UL
+LT1
+4151 6759 M
+(sample 2) Rshow
+4235 6759 M
+399 0 V
+574 3174 M
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 1 V
+43 1 V
+43 1 V
+42 3 V
+43 4 V
+43 6 V
+42 9 V
+43 13 V
+43 19 V
+42 27 V
+43 37 V
+43 51 V
+43 66 V
+42 85 V
+43 106 V
+43 130 V
+42 155 V
+43 179 V
+43 201 V
+43 219 V
+42 231 V
+43 236 V
+43 229 V
+42 214 V
+43 187 V
+43 149 V
+42 104 V
+43 52 V
+43 -3 V
+43 -57 V
+42 -109 V
+43 -154 V
+43 -189 V
+42 -216 V
+43 -231 V
+43 -235 V
+43 -231 V
+42 -217 V
+43 -199 V
+43 -177 V
+42 -152 V
+43 -127 V
+43 -104 V
+42 -83 V
+43 -65 V
+43 -49 V
+43 -36 V
+42 -26 V
+43 -19 V
+43 -12 V
+42 -9 V
+43 -6 V
+43 -3 V
+43 -3 V
+42 -1 V
+43 -1 V
+43 -1 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+43 0 V
+43 0 V
+42 0 V
+43 0 V
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
+%%Pages: 1
--- /dev/null
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2005-01-30.17}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
+% Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this texinfo.tex file; see the file COPYING. If not, write
+% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+% Boston, MA 02110-1301, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+% ftp://tug.org/tex/texinfo.tex
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\questChar = `\?
+\chardef\semiChar = `\;
+\chardef\underChar = `\_
+
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \escapechar = `\\ % use backslash in output files.
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingxxx.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 2\baselineskip
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \normalturnoffactive
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\next{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % We cannot use \next here, as it holds the macro to run;
+ % thus we reuse \temp.
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \next.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ out of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux file.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+ \kern-.15em
+ \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=3000 }
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @include file insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable
+ \def\temp{\input #1 }%
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\next\centerH
+ \else
+ \let\next\centerV
+ \fi
+ \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+ {%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+ }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode\underChar = \active
+ \gdef\mathunderscore{%
+ \catcode\underChar=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care. Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+ \leavevmode
+ \hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil
+ .\hfil.\hfil.%
+ \hskip 0pt plus 0.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=3000
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+%
+\ifpdf
+ \input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}%
+ \def\dopdfimage#1#2#3{%
+ \def\imagewidth{#2}%
+ \def\imageheight{#3}%
+ % without \immediate, pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifx\empty\imagewidth\else width \imagewidth \fi
+ \ifx\empty\imageheight\else height \imageheight \fi
+ \ifnum\pdftexversion<13
+ #1.pdf%
+ \else
+ {#1.pdf}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code in a section title
+ % aren't expanded.
+ \atdummies
+ \normalturnoffactive
+ \pdfdest name{#1} xyz%
+ }}
+ \def\pdfmkpgn#1{#1}
+ \let\linkcolor = \Blue % was Cyan, but that seems light?
+ \def\endlink{\Black\pdfendlink}
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node
+ % text, which might be empty if this toc entry had no
+ % corresponding node. #4 is the page number.
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worthwhile, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Thanh's hack / proper braces in bookmarks
+ \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+ \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+ %
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \input \jobname.toc
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % xx to do this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Right
+ % now, I guess we'll just let the pdf reader have its way.
+ \indexnofonts
+ \turnoffactive
+ \input \jobname.toc
+ \endgroup
+ }
+ %
+ \def\makelinks #1,{%
+ \def\params{#1}\def\E{END}%
+ \ifx\params\E
+ \let\nextmakelinks=\relax
+ \else
+ \let\nextmakelinks=\makelinks
+ \ifnum\lnkcount>0,\fi
+ \picknum{#1}%
+ \startlink attr{/Border [0 0 0]}
+ goto name{\pdfmkpgn{\the\pgn}}%
+ \linkcolor #1%
+ \advance\lnkcount by 1%
+ \endlink
+ \fi
+ \nextmakelinks
+ }
+ \def\picknum#1{\expandafter\pn#1}
+ \def\pn#1{%
+ \def\p{#1}%
+ \ifx\p\lbrace
+ \let\nextpn=\ppn
+ \else
+ \let\nextpn=\ppnn
+ \def\first{#1}
+ \fi
+ \nextpn
+ }
+ \def\ppn#1{\pgn=#1\gobble}
+ \def\ppnn{\pgn=\first}
+ \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,}
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \ifx\p\space\else\addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \fi
+ \nextsp}
+ \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ \def\pdfurl#1{%
+ \begingroup
+ \normalturnoffactive\def\@{@}%
+ \makevalueexpandable
+ \leavevmode\Red
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \linkcolor #1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\linkcolor = \relax
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+% Default leading.
+\newdimen\textleading \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts \rm
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+ \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\frenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ }
+\catcode`@=\other
+
+\def\t#1{%
+ {\tt \rawbackslash \frenchspacing #1}%
+ \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+ \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \frenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active
+ \catcode`\_=\active
+ %
+ \global\def\code{\begingroup
+ \catcode`\-=\active \let-\codedash
+ \catcode`\_=\active \let_\codeunder
+ \codex
+ }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\arg{#1}%
+ \ifx\arg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\arg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\arg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle option `\arg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url. Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\frenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+ \let\tt=\authortt}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\authorfont \leftline{#1}}%
+ \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -\baselineskip
+ \global\advance\vsize by -\baselineskip
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ \def\itemcontents{#1}%
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1', which must be on a line
+ % by itself.
+ \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \obeylines %
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ % Need these in case \tex is in effect and \{ is a \delimiter again.
+ % But can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters.
+ \let\{ = \mylbrace
+ \let\} = \myrbrace
+ %
+ % \definedummyword defines \#1 as \realbackslash #1\space, thus
+ % effectively preventing its expansion. This is used only for control
+ % words, not control letters, because the \space would be incorrect
+ % for control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword##1{%
+ \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
+ }%
+ \def\definedummyletter##1{%
+ \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
+ }%
+ \let\definedummyaccent\definedummyletter
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux file, @ is the escape character. So we want to redefine
+% everything using @ instead of \realbackslash. When everything uses
+% @, this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % (See comments in \indexdummies.)
+ \def\definedummyword##1{%
+ \expandafter\def\csname ##1\endcsname{@##1\space}%
+ }%
+ \def\definedummyletter##1{%
+ \expandafter\def\csname ##1\endcsname{@##1}%
+ }%
+ \let\definedummyaccent\definedummyletter
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% Called from \indexdummies and \atdummies. \definedummyword and
+% \definedummyletter must be defined first.
+%
+\def\commondummies{%
+ %
+ \normalturnoffactive
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter{_}%
+ %
+ % Non-English letters.
+ \definedummyword{AA}%
+ \definedummyword{AE}%
+ \definedummyword{L}%
+ \definedummyword{OE}%
+ \definedummyword{O}%
+ \definedummyword{aa}%
+ \definedummyword{ae}%
+ \definedummyword{l}%
+ \definedummyword{oe}%
+ \definedummyword{o}%
+ \definedummyword{ss}%
+ \definedummyword{exclamdown}%
+ \definedummyword{questiondown}%
+ \definedummyword{ordf}%
+ \definedummyword{ordm}%
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword{bf}%
+ \definedummyword{gtr}%
+ \definedummyword{hat}%
+ \definedummyword{less}%
+ \definedummyword{sf}%
+ \definedummyword{sl}%
+ \definedummyword{tclose}%
+ \definedummyword{tt}%
+ %
+ \definedummyword{LaTeX}%
+ \definedummyword{TeX}%
+ %
+ % Assorted special characters.
+ \definedummyword{bullet}%
+ \definedummyword{comma}%
+ \definedummyword{copyright}%
+ \definedummyword{registeredsymbol}%
+ \definedummyword{dots}%
+ \definedummyword{enddots}%
+ \definedummyword{equiv}%
+ \definedummyword{error}%
+ \definedummyword{euro}%
+ \definedummyword{expansion}%
+ \definedummyword{minus}%
+ \definedummyword{pounds}%
+ \definedummyword{point}%
+ \definedummyword{print}%
+ \definedummyword{result}%
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+ %
+ % Normal spaces, not active ones.
+ \unsepspaces
+ %
+ % No macro expansion.
+ \turnoffmacros
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+% Better have this without active chars.
+{
+ \catcode`\~=\other
+ \gdef\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter{!}%
+ \definedummyaccent{"}%
+ \definedummyaccent{'}%
+ \definedummyletter{*}%
+ \definedummyaccent{,}%
+ \definedummyletter{.}%
+ \definedummyletter{/}%
+ \definedummyletter{:}%
+ \definedummyaccent{=}%
+ \definedummyletter{?}%
+ \definedummyaccent{^}%
+ \definedummyaccent{`}%
+ \definedummyaccent{~}%
+ \definedummyword{u}%
+ \definedummyword{v}%
+ \definedummyword{H}%
+ \definedummyword{dotaccent}%
+ \definedummyword{ringaccent}%
+ \definedummyword{tieaccent}%
+ \definedummyword{ubaraccent}%
+ \definedummyword{udotaccent}%
+ \definedummyword{dotless}%
+ %
+ % Texinfo font commands.
+ \definedummyword{b}%
+ \definedummyword{i}%
+ \definedummyword{r}%
+ \definedummyword{sc}%
+ \definedummyword{t}%
+ %
+ % Commands that take arguments.
+ \definedummyword{acronym}%
+ \definedummyword{cite}%
+ \definedummyword{code}%
+ \definedummyword{command}%
+ \definedummyword{dfn}%
+ \definedummyword{emph}%
+ \definedummyword{env}%
+ \definedummyword{file}%
+ \definedummyword{kbd}%
+ \definedummyword{key}%
+ \definedummyword{math}%
+ \definedummyword{option}%
+ \definedummyword{samp}%
+ \definedummyword{strong}%
+ \definedummyword{tie}%
+ \definedummyword{uref}%
+ \definedummyword{url}%
+ \definedummyword{var}%
+ \definedummyword{verb}%
+ \definedummyword{w}%
+ }
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{%
+ \expandafter\let\csname ##1\endcsname\asis
+ }%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{%
+ \expandafter\def\csname ##1\endcsname{}%
+ }%
+ % Hopefully, all control words can become @asis.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ % how to handle braces?
+ \def\_{\normalunderscore}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\o{o}%
+ \def\ss{ss}%
+ \def\exclamdown{!}%
+ \def\questiondown{?}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\registeredsymbol{R}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\minus{-}%
+ \def\pounds{pounds}%
+ \def\point{.}%
+ \def\print{-|}%
+ \def\result{=>}%
+ %
+ % Don't write macro names.
+ \emptyusermacros
+}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \ifvmode
+ \dosubindsanitize
+ \else
+ \dosubindwrite
+ \fi
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \escapechar=`\\
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write will make \lastskip zero. The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \skip0 = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \count255 = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\skip0 glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\skip0
+ \fi
+ %
+ \dosubindwrite
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ %
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\count255>9999 \penalty\count255 \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\skip0
+ \fi
+}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unmlevel
+ \chardef\unmlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unmlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unmlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ \message{\putwordChapter\space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ \pchapsepmacro
+ {%
+ \chapfonts \rm
+ %
+ % Have to define \thissection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \gdef\thischapter{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \gdef\thischapter{}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rm
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\thissection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \thissection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\thissection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\thissection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chfplain.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chfplain.
+ \donoderef{#3}%
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.)
+ \vskip-\parskip
+ %
+ % This is purely so the last item on the list is a known \penalty >
+ % 10000. This is so \startdefun can avoid allowing breakpoints after
+ % section headings. Otherwise, it would insert a valid breakpoint between:
+ %
+ % @section sec-whatever
+ % @deffn def-whatever
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ \toks0 = {#2}%
+ \toks2 = \expandafter{\lastnode}%
+ \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}%
+ {\the\toks2}{\noexpand\folio}}}%
+ \temp
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \def\thischapter{}%
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ % We can't do this, because then an actual ^ in a section
+ % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
+ %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \input \jobname.toc
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \input \jobname.toc
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \escapechar=`\\
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ % @cartouche defines \nonarrowing to inhibit narrowing
+ % at next level down.
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+ \makedispenv{#1}{#3}
+ \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+ \nonfillstart
+ \tt
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\undefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+ \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \catcode`\`=\active
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen0=\wd0 % the width so far, or since the previous tab
+ \divide\dimen0 by\tabw
+ \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+ \advance\dimen0 by\tabw % advance to next multiple of \tabw
+ \wd0=\dimen0 \box0 \starttabbox
+ }%
+ }
+\endgroup
+\def\setupverbatim{%
+ \nonfillstart
+ \advance\leftskip by -\defbodyindent
+ % Easiest (and conventionally used) font for verbatim
+ \tt
+ \def\par{\leavevmode\egroup\box0\endgraf}%
+ \catcode`\`=\active
+ \tabexpand
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \defargscommonending, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ \ifnum\lastpenalty=10002 \penalty2000 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty 10002 % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % How we'll format the type name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape.
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ % (plain.tex says that \dimen1 should be used only as global.)
+ \parshape 2 0in \dimen0 \defargsindent \dimen2
+ %
+ % Put the type name to the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% return value type
+ \ifx\temp\empty\else \tclose{\temp} \fi
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\ }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+ \errmessage{Unbalanced parentheses in @def}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \errmessage{Unbalanced square braces in @def}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{%
+ \begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ % ... and \example
+ \spaceisspace
+ %
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ %
+ % I've verified that it is necessary both for e-TeX and for ordinary TeX
+ % --kasal, 29nov03
+ \scantokens{#1\endinput}%
+ \endgroup
+}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+\def\macrolist{} % List of all defined macros in the form
+ % \do\macro1\do\macro2...
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0%
+ \else
+ \expandafter\parsemargdef \argl;%
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ % Add the macroname to \macrolist
+ \toks0 = \expandafter{\macrolist\do}%
+ \xdef\macrolist{\the\toks0
+ \expandafter\noexpand\csname\the\macname\endcsname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\do\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx#1\relax
+ % remove this
+ \else
+ \noexpand\do \noexpand #1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+ \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1%
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \fi
+ \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \next}
+
+% We want to disable all macros during \shipout so that they are not
+% expanded by \write.
+\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
+ \edef\next{\macrolist}\expandafter\endgroup\next}
+
+% For \indexnofonts, we need to get rid of all macros, leaving only the
+% arguments (if present). Of course this is not nearly correct, but it
+% is the best we can do for now. makeinfo does not expand macros in the
+% argument to @deffn, which ends up writing an index entry, and texindex
+% isn't prepared for an index sort entry that starts with \.
+%
+% Since macro invocations are followed by braces, we can just redefine them
+% to take a single TeX argument. The case of a macro invocation that
+% goes to end-of-line is not handled.
+%
+\def\emptyusermacros{\begingroup
+ \def\do##1{\let\noexpand##1=\noexpand\asis}%
+ \edef\next{\macrolist}\expandafter\endgroup\next}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \turnoffactive
+ \otherbackslash
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\thissection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \writexrdef{pg}{\folio}% will be written later, during \shipout
+ }%
+ \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual\unskip}%
+ \setbox0=\hbox{\printedrefname\unskip}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+ % Use the node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1 > 0pt
+ % It is in another manual, so we don't have it.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ \leavevmode
+ \getfilename{#4}%
+ {\turnoffactive \otherbackslash
+ \ifnum\filenamelength>0
+ \startlink attr{/Border [0 0 0]}%
+ goto file{\the\filename.pdf} name{#1}%
+ \else
+ \startlink attr{/Border [0 0 0]}%
+ goto name{\pdfmkpgn{#1}}%
+ \fi
+ }%
+ \linkcolor
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd0 = 0pt
+ \refx{#1-snt}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd1 > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive \otherbackslash
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via a macro so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR#1\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readauxfile
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\readauxfile{\begingroup
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+ %
+ \input \jobname.aux
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\undefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \nobreak\bigskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \line\bgroup\hss
+ \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode \hss \egroup \bigbreak \fi % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \thissection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\thissection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies \turnoffactive \otherbackslash
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename. If done too late, it may not override everything
+% properly. Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
+% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8)
+% physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{46\baselineskip}{6in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.5 (or so) format.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{51\baselineskip}{160mm}
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @gdef@rawbackslash{@let\=@backslashcurfont}
+ @gdef@otherbackslash{@let\=@realbackslash}
+}
+
+% \realbackslash is an actual character `\' with catcode other.
+{\catcode`\\=\other @gdef@realbackslash{\}}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\backslashcurfont}}
+
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{%
+ @let"=@normaldoublequote
+ @let\=@realbackslash
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus
+ @let$=@normaldollar %$ font-lock fix
+ @unsepspaces
+}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'. (Thus, \ is not expandable when this is in
+% effect.)
+%
+@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also back turn on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
--- /dev/null
+/*
+ * eval.c - gawk parse tree interpreter
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+extern double pow P((double x, double y));
+extern double modf P((double x, double *yp));
+extern double fmod P((double x, double y));
+
+static inline void make_scalar P((NODE *tree));
+static int eval_condition P((NODE *tree));
+static NODE *op_assign P((NODE *tree));
+static NODE *func_call P((NODE *tree));
+static NODE *match_op P((NODE *tree));
+static void pop_forloop P((void));
+static inline void pop_all_forloops P((void));
+static void push_forloop P((const char *varname, NODE **elems, size_t nelems));
+static void push_args P((int count, NODE *arglist, NODE **oldstack,
+ const char *func_name, char **varnames));
+static inline void pop_fcall_stack P((void));
+static void pop_fcall P((void));
+static int comp_func P((const void *p1, const void *p2));
+
+#if __GNUC__ < 2
+NODE *_t; /* used as a temporary in macros */
+#endif
+#ifdef MSDOS
+double _msc51bug; /* to get around a bug in MSC 5.1 */
+#endif
+NODE *ret_node;
+int OFSlen;
+int ORSlen;
+int OFMTidx;
+int CONVFMTidx;
+
+/* Profiling stuff */
+#ifdef PROFILING
+#define INCREMENT(n) n++
+#else
+#define INCREMENT(n) /* nothing */
+#endif
+
+/* Macros and variables to save and restore function and loop bindings */
+/*
+ * the val variable allows return/continue/break-out-of-context to be
+ * caught and diagnosed
+ */
+#define PUSH_BINDING(stack, x, val) (memcpy((char *)(stack), (const char *)(x), sizeof(jmp_buf)), val++)
+#define RESTORE_BINDING(stack, x, val) (memcpy((char *)(x), (const char *)(stack), sizeof(jmp_buf)), val--)
+
+static jmp_buf loop_tag; /* always the current binding */
+static int loop_tag_valid = FALSE; /* nonzero when loop_tag valid */
+static int func_tag_valid = FALSE;
+static jmp_buf func_tag;
+extern int exiting, exit_val;
+
+/* This rather ugly macro is for VMS C */
+#ifdef C
+#undef C
+#endif
+#define C(c) ((char)c)
+/*
+ * This table is used by the regexp routines to do case independant
+ * matching. Basically, every ascii character maps to itself, except
+ * uppercase letters map to lower case ones. This table has 256
+ * entries, for ISO 8859-1. Note also that if the system this
+ * is compiled on doesn't use 7-bit ascii, casetable[] should not be
+ * defined to the linker, so gawk should not load.
+ *
+ * Do NOT make this array static, it is used in several spots, not
+ * just in this file.
+ *
+ * 6/2004:
+ * This table is also used for IGNORECASE for == and !=, and index().
+ * Although with GLIBC, we could use tolower() everywhere and RE_ICASE
+ * for the regex matcher, precomputing this table once gives us a
+ * performance improvement. I also think it's better for portability
+ * to non-GLIBC systems. All the world is not (yet :-) GNU/Linux.
+ */
+#if 'a' == 97 /* it's ascii */
+char casetable[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ /* ' ' '!' '"' '#' '$' '%' '&' ''' */
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ /* '(' ')' '*' '+' ',' '-' '.' '/' */
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ /* '0' '1' '2' '3' '4' '5' '6' '7' */
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ /* '8' '9' ':' ';' '<' '=' '>' '?' */
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ /* '@' 'A' 'B' 'C' 'D' 'E' 'F' 'G' */
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ /* 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' */
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ /* 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' */
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ /* 'X' 'Y' 'Z' '[' '\' ']' '^' '_' */
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ /* '`' 'a' 'b' 'c' 'd' 'e' 'f' 'g' */
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ /* 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' */
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ /* 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' */
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ /* 'x' 'y' 'z' '{' '|' '}' '~' */
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+
+ /* Latin 1: */
+ C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
+ C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
+ C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
+ C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
+ C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
+ C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
+ C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
+ C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
+};
+#else
+#include "You lose. You will need a translation table for your character set."
+#endif
+
+#undef C
+
+/* load_casetable --- for a non-ASCII locale, redo the table */
+
+void
+load_casetable(void)
+{
+#if defined(LC_CTYPE)
+ int i;
+ char *cp;
+ static int loaded = FALSE;
+
+ if (loaded || do_traditional)
+ return;
+
+ loaded = TRUE;
+ cp = setlocale(LC_CTYPE, NULL);
+
+ /* this is not per standard, but it's pretty safe */
+ if (cp == NULL || strcmp(cp, "C") == 0 || strcmp(cp, "POSIX") == 0)
+ return;
+
+ for (i = 0200; i <= 0377; i++) {
+ if (isalpha(i) && islower(i) && i != toupper(i))
+ casetable[i] = toupper(i);
+ }
+#endif
+}
+
+/*
+ * This table maps node types to strings for debugging.
+ * KEEP IN SYNC WITH awk.h!!!!
+ */
+static const char *const nodetypes[] = {
+ "Node_illegal",
+ "Node_times",
+ "Node_quotient",
+ "Node_mod",
+ "Node_plus",
+ "Node_minus",
+ "Node_cond_pair",
+ "Node_subscript",
+ "Node_concat",
+ "Node_exp",
+ "Node_preincrement",
+ "Node_predecrement",
+ "Node_postincrement",
+ "Node_postdecrement",
+ "Node_unary_minus",
+ "Node_field_spec",
+ "Node_assign",
+ "Node_assign_times",
+ "Node_assign_quotient",
+ "Node_assign_mod",
+ "Node_assign_plus",
+ "Node_assign_minus",
+ "Node_assign_exp",
+ "Node_assign_concat",
+ "Node_and",
+ "Node_or",
+ "Node_equal",
+ "Node_notequal",
+ "Node_less",
+ "Node_greater",
+ "Node_leq",
+ "Node_geq",
+ "Node_match",
+ "Node_nomatch",
+ "Node_not",
+ "Node_rule_list",
+ "Node_rule_node",
+ "Node_statement_list",
+ "Node_switch_body",
+ "Node_case_list",
+ "Node_if_branches",
+ "Node_expression_list",
+ "Node_param_list",
+ "Node_K_if",
+ "Node_K_switch",
+ "Node_K_case",
+ "Node_K_default",
+ "Node_K_while",
+ "Node_K_for",
+ "Node_K_arrayfor",
+ "Node_K_break",
+ "Node_K_continue",
+ "Node_K_print",
+ "Node_K_print_rec",
+ "Node_K_printf",
+ "Node_K_next",
+ "Node_K_exit",
+ "Node_K_do",
+ "Node_K_return",
+ "Node_K_delete",
+ "Node_K_delete_loop",
+ "Node_K_getline",
+ "Node_K_function",
+ "Node_K_nextfile",
+ "Node_redirect_output",
+ "Node_redirect_append",
+ "Node_redirect_pipe",
+ "Node_redirect_pipein",
+ "Node_redirect_input",
+ "Node_redirect_twoway",
+ "Node_var_new",
+ "Node_var",
+ "Node_var_array",
+ "Node_val",
+ "Node_builtin",
+ "Node_line_range",
+ "Node_in_array",
+ "Node_func",
+ "Node_func_call",
+ "Node_cond_exp",
+ "Node_regex",
+ "Node_dynregex",
+ "Node_hashnode",
+ "Node_ahash",
+ "Node_array_ref",
+ "Node_BINMODE",
+ "Node_CONVFMT",
+ "Node_FIELDWIDTHS",
+ "Node_FNR",
+ "Node_FS",
+ "Node_IGNORECASE",
+ "Node_LINT",
+ "Node_NF",
+ "Node_NR",
+ "Node_OFMT",
+ "Node_OFS",
+ "Node_ORS",
+ "Node_RS",
+ "Node_SUBSEP",
+ "Node_TEXTDOMAIN",
+ "Node_final --- this should never appear",
+ NULL
+};
+
+/* nodetype2str --- convert a node type into a printable value */
+
+const char *
+nodetype2str(NODETYPE type)
+{
+ static char buf[40];
+
+ if (type >= Node_illegal && type <= Node_final)
+ return nodetypes[(int) type];
+
+ sprintf(buf, _("unknown nodetype %d"), (int) type);
+ return buf;
+}
+
+/* flags2str --- make a flags value readable */
+
+const char *
+flags2str(int flagval)
+{
+ static const struct flagtab values[] = {
+ { MALLOC, "MALLOC" },
+ { TEMP, "TEMP" },
+ { PERM, "PERM" },
+ { STRING, "STRING" },
+ { STRCUR, "STRCUR" },
+ { NUMCUR, "NUMCUR" },
+ { NUMBER, "NUMBER" },
+ { MAYBE_NUM, "MAYBE_NUM" },
+ { ARRAYMAXED, "ARRAYMAXED" },
+ { FUNC, "FUNC" },
+ { FIELD, "FIELD" },
+ { INTLSTR, "INTLSTR" },
+#ifdef WSTRCUR
+ { WSTRCUR, "WSTRCUR" },
+#endif
+ { 0, NULL },
+ };
+
+ return genflags2str(flagval, values);
+}
+
+/* genflags2str --- general routine to convert a flag value to a string */
+
+const char *
+genflags2str(int flagval, const struct flagtab *tab)
+{
+ static char buffer[BUFSIZ];
+ char *sp;
+ int i, space_left, space_needed;
+
+ sp = buffer;
+ space_left = BUFSIZ;
+ for (i = 0; tab[i].name != NULL; i++) {
+ if ((flagval & tab[i].val) != 0) {
+ /*
+ * note the trick, we want 1 or 0 for whether we need
+ * the '|' character.
+ */
+ space_needed = (strlen(tab[i].name) + (sp != buffer));
+ if (space_left < space_needed)
+ fatal(_("buffer overflow in genflags2str"));
+
+ if (sp != buffer) {
+ *sp++ = '|';
+ space_left--;
+ }
+ strcpy(sp, tab[i].name);
+ /* note ordering! */
+ space_left -= strlen(sp);
+ sp += strlen(sp);
+ }
+ }
+
+ return buffer;
+}
+
+/*
+ * make_scalar --- make sure that tree is a scalar.
+ *
+ * tree is in a scalar context. If it is a variable, accomplish
+ * what's needed; otherwise, do nothing.
+ *
+ * Notice that nodes of type Node_var_new have undefined value in var_value
+ * (a.k.a. lnode)---even though awkgram.y:variable() initializes it,
+ * push_args() doesn't. Thus we have to initialize it.
+ */
+
+static inline void
+make_scalar(NODE *tree)
+{
+ switch (tree->type) {
+ case Node_var_array:
+ fatal(_("attempt to use array `%s' in a scalar context"),
+ array_vname(tree));
+
+ case Node_array_ref:
+ switch (tree->orig_array->type) {
+ case Node_var_array:
+ fatal(_("attempt to use array `%s' in a scalar context"),
+ array_vname(tree));
+ case Node_var_new:
+ tree->orig_array->type = Node_var;
+ tree->orig_array->var_value = Nnull_string;
+ break;
+ case Node_var:
+ break;
+ default:
+ cant_happen();
+ }
+ /* fall through */
+ case Node_var_new:
+ tree->type = Node_var;
+ tree->var_value = Nnull_string;
+ default:
+ /* shut up GCC */
+ break;
+ }
+}
+
+/*
+ * interpret:
+ * Tree is a bunch of rules to run. Returns zero if it hit an exit()
+ * statement
+ */
+int
+interpret(register NODE *volatile tree)
+{
+ jmp_buf volatile loop_tag_stack; /* shallow binding stack for loop_tag */
+ static jmp_buf rule_tag; /* tag the rule currently being run, for NEXT
+ * and EXIT statements. It is static because
+ * there are no nested rules */
+ register NODE *volatile t = NULL; /* temporary */
+ NODE **volatile lhs; /* lhs == Left Hand Side for assigns, etc */
+ NODE *volatile stable_tree;
+ int volatile traverse = TRUE; /* True => loop thru tree (Node_rule_list) */
+
+ /* avoid false source indications */
+ source = NULL;
+ sourceline = 0;
+
+ if (tree == NULL)
+ return 1;
+ sourceline = tree->source_line;
+ source = tree->source_file;
+ switch (tree->type) {
+ case Node_rule_node:
+ traverse = FALSE; /* False => one for-loop iteration only */
+ /* FALL THROUGH */
+ case Node_rule_list:
+ for (t = tree; t != NULL; t = t->rnode) {
+ if (traverse)
+ tree = t->lnode;
+ sourceline = tree->source_line;
+ source = tree->source_file;
+ INCREMENT(tree->exec_count);
+ switch (setjmp(rule_tag)) {
+ case 0: /* normal non-jump */
+ /* test pattern, if any */
+ if (tree->lnode == NULL ||
+ eval_condition(tree->lnode)) {
+ /* using the lnode exec_count is kludgey */
+ if (tree->lnode != NULL)
+ INCREMENT(tree->lnode->exec_count);
+ (void) interpret(tree->rnode);
+ }
+ break;
+ case TAG_CONTINUE: /* NEXT statement */
+ pop_all_forloops();
+ pop_fcall_stack();
+ return 1;
+ case TAG_BREAK: /* EXIT statement */
+ pop_all_forloops();
+ pop_fcall_stack();
+ return 0;
+ default:
+ cant_happen();
+ }
+ if (! traverse) /* case Node_rule_node */
+ break; /* don't loop */
+ }
+ break;
+
+ case Node_statement_list:
+ for (t = tree; t != NULL; t = t->rnode)
+ (void) interpret(t->lnode);
+ break;
+
+ case Node_K_if:
+ INCREMENT(tree->exec_count);
+ if (eval_condition(tree->lnode)) {
+ INCREMENT(tree->rnode->exec_count);
+ (void) interpret(tree->rnode->lnode);
+ } else {
+ (void) interpret(tree->rnode->rnode);
+ }
+ break;
+
+ case Node_K_switch:
+ {
+ NODE *switch_value;
+ NODE *switch_body;
+ NODE *case_list;
+ NODE *default_list;
+ NODE *case_stmt;
+
+ int match_found = FALSE;
+
+ PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ INCREMENT(tree->exec_count);
+ stable_tree = tree;
+
+ switch_value = tree_eval(stable_tree->lnode);
+ switch_body = stable_tree->rnode;
+ case_list = switch_body->lnode;
+ default_list = switch_body->rnode;
+
+ for (; case_list != NULL; case_list = case_list->rnode) {
+ case_stmt = case_list->lnode;
+
+ /*
+ * Once a match is found, all cases will be processed as they fall through,
+ * so continue to execute statements until a break is reached.
+ */
+ if (! match_found) {
+ if (case_stmt->type == Node_K_default)
+ ; /* do nothing */
+ else if (case_stmt->lnode->type == Node_regex) {
+ NODE *t1;
+ Regexp *rp;
+ /* see comments in match_op() code about this. */
+ int kludge_need_start = 0;
+
+ t1 = force_string(switch_value);
+ rp = re_update(case_stmt->lnode);
+
+ if (avoid_dfa(tree, t1->stptr, t1->stlen))
+ kludge_need_start = RE_NEED_START;
+ match_found = (research(rp, t1->stptr, 0, t1->stlen, kludge_need_start) >= 0);
+ if (t1 != switch_value)
+ free_temp(t1);
+ } else
+ match_found = (cmp_nodes(switch_value, case_stmt->lnode) == 0);
+ }
+
+ /* If a match was found, execute the statements associated with the case. */
+ if (match_found) {
+ INCREMENT(case_stmt->exec_count);
+ switch (setjmp(loop_tag)) {
+ case 0: /* Normal non-jump */
+ (void) interpret(case_stmt->rnode);
+ break;
+ case TAG_CONTINUE: /* continue statement */
+ free_temp(switch_value);
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ longjmp(loop_tag, TAG_CONTINUE);
+ break;
+ case TAG_BREAK: /* break statement */
+ free_temp(switch_value);
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ return 1;
+ default:
+ cant_happen();
+ }
+ }
+
+ }
+
+ free_temp(switch_value);
+
+ /*
+ * If a default section was found, execute the statements associated with it
+ * and execute any trailing case statements if the default falls through.
+ */
+ if (! match_found && default_list != NULL) {
+ for (case_list = default_list;
+ case_list != NULL; case_list = case_list->rnode) {
+ case_stmt = case_list->lnode;
+
+ INCREMENT(case_stmt->exec_count);
+ switch (setjmp(loop_tag)) {
+ case 0: /* Normal non-jump */
+ (void) interpret(case_stmt->rnode);
+ break;
+ case TAG_CONTINUE: /* continue statement */
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ longjmp(loop_tag, TAG_CONTINUE);
+ break;
+ case TAG_BREAK: /* break statement */
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ return 1;
+ default:
+ cant_happen();
+ }
+ }
+ }
+
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ }
+ break;
+
+ case Node_K_while:
+ PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+
+ stable_tree = tree;
+ while (eval_condition(stable_tree->lnode)) {
+ INCREMENT(stable_tree->exec_count);
+ switch (setjmp(loop_tag)) {
+ case 0: /* normal non-jump */
+ (void) interpret(stable_tree->rnode);
+ break;
+ case TAG_CONTINUE: /* continue statement */
+ break;
+ case TAG_BREAK: /* break statement */
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ return 1;
+ default:
+ cant_happen();
+ }
+ }
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ break;
+
+ case Node_K_do:
+ PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ stable_tree = tree;
+ do {
+ INCREMENT(stable_tree->exec_count);
+ switch (setjmp(loop_tag)) {
+ case 0: /* normal non-jump */
+ (void) interpret(stable_tree->rnode);
+ break;
+ case TAG_CONTINUE: /* continue statement */
+ break;
+ case TAG_BREAK: /* break statement */
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ return 1;
+ default:
+ cant_happen();
+ }
+ } while (eval_condition(stable_tree->lnode));
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ break;
+
+ case Node_K_for:
+ PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ (void) interpret(tree->forloop->init);
+ stable_tree = tree;
+ while (eval_condition(stable_tree->forloop->cond)) {
+ INCREMENT(stable_tree->exec_count);
+ switch (setjmp(loop_tag)) {
+ case 0: /* normal non-jump */
+ (void) interpret(stable_tree->lnode);
+ /* fall through */
+ case TAG_CONTINUE: /* continue statement */
+ (void) interpret(stable_tree->forloop->incr);
+ break;
+ case TAG_BREAK: /* break statement */
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ return 1;
+ default:
+ cant_happen();
+ }
+ }
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ break;
+
+ case Node_K_arrayfor:
+ {
+ Func_ptr after_assign = NULL;
+ NODE **list = NULL;
+ NODE *volatile array;
+ NODE *volatile save_array;
+ volatile size_t i, num_elems;
+ size_t j;
+ volatile int retval = 0;
+ int sort_indices = whiny_users;
+
+#define hakvar forloop->init
+#define arrvar forloop->incr
+ /* get the array */
+ save_array = tree->arrvar;
+ array = get_array(save_array);
+
+ /* sanity: do nothing if empty */
+ if (array->var_array == NULL || array->table_size == 0)
+ break; /* from switch */
+
+ /* allocate space for array */
+ num_elems = array->table_size;
+ emalloc(list, NODE **, num_elems * sizeof(NODE *), "for_loop");
+
+ /* populate it */
+ for (i = j = 0; i < array->array_size; i++) {
+ NODE *t = array->var_array[i];
+
+ if (t == NULL)
+ continue;
+
+ for (; t != NULL; t = t->ahnext) {
+ list[j++] = dupnode(t);
+ assert(list[j-1] == t);
+ }
+ }
+
+
+ if (sort_indices)
+ qsort(list, num_elems, sizeof(NODE *), comp_func); /* shazzam! */
+
+ /* now we can run the loop */
+ push_forloop(array->vname, list, num_elems);
+ PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+
+ lhs = get_lhs(tree->hakvar, &after_assign, FALSE);
+ stable_tree = tree;
+ for (i = 0; i < num_elems; i++) {
+ INCREMENT(stable_tree->exec_count);
+ unref(*((NODE **) lhs));
+ *lhs = make_string(list[i]->ahname_str, list[i]->ahname_len);
+ if (after_assign)
+ (*after_assign)();
+ switch (setjmp(loop_tag)) {
+ case 0:
+ (void) interpret(stable_tree->lnode);
+ case TAG_CONTINUE:
+ break;
+
+ case TAG_BREAK:
+ retval = 1;
+ goto done;
+
+ default:
+ cant_happen();
+ }
+ }
+
+ done:
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ pop_forloop();
+
+ if (do_lint && num_elems != array->table_size)
+ lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
+ array_vname(save_array), (long) num_elems, (long) array->table_size);
+
+ if (retval == 1)
+ return 1;
+ break;
+ }
+#undef hakvar
+#undef arrvar
+
+ case Node_K_break:
+ INCREMENT(tree->exec_count);
+ if (! loop_tag_valid) {
+ /*
+ * Old AT&T nawk treats break outside of loops like
+ * next. New ones catch it at parse time. Allow it if
+ * do_traditional is on, and complain if lint.
+ */
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("`break' outside a loop is not portable"));
+ warned = TRUE;
+ }
+ if (! do_traditional || do_posix)
+ fatal(_("`break' outside a loop is not allowed"));
+ longjmp(rule_tag, TAG_CONTINUE);
+ } else
+ longjmp(loop_tag, TAG_BREAK);
+ break;
+
+ case Node_K_continue:
+ INCREMENT(tree->exec_count);
+ if (! loop_tag_valid) {
+ /*
+ * Old AT&T nawk treats continue outside of loops like
+ * next. New ones catch it at parse time. Allow it if
+ * do_traditional is on, and complain if lint.
+ */
+ static int warned = FALSE;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("`continue' outside a loop is not portable"));
+ warned = TRUE;
+ }
+ if (! do_traditional || do_posix)
+ fatal(_("`continue' outside a loop is not allowed"));
+ longjmp(rule_tag, TAG_CONTINUE);
+ } else
+ longjmp(loop_tag, TAG_CONTINUE);
+ break;
+
+ case Node_K_print:
+ INCREMENT(tree->exec_count);
+ do_print(tree);
+ break;
+
+ case Node_K_print_rec:
+ INCREMENT(tree->exec_count);
+ do_print_rec(tree);
+ break;
+
+ case Node_K_printf:
+ INCREMENT(tree->exec_count);
+ do_printf(tree);
+ break;
+
+ case Node_K_delete:
+ INCREMENT(tree->exec_count);
+ do_delete(tree->lnode, tree->rnode);
+ break;
+
+ case Node_K_delete_loop:
+ INCREMENT(tree->exec_count);
+ do_delete_loop(tree->lnode, tree->rnode);
+ break;
+
+ case Node_K_next:
+ INCREMENT(tree->exec_count);
+ if (in_begin_rule)
+ fatal(_("`next' cannot be called from a BEGIN rule"));
+ else if (in_end_rule)
+ fatal(_("`next' cannot be called from an END rule"));
+
+ /* could add a lint check here for in a loop or function */
+ longjmp(rule_tag, TAG_CONTINUE);
+ break;
+
+ case Node_K_nextfile:
+ INCREMENT(tree->exec_count);
+ if (in_begin_rule)
+ fatal(_("`nextfile' cannot be called from a BEGIN rule"));
+ else if (in_end_rule)
+ fatal(_("`nextfile' cannot be called from an END rule"));
+
+ /* could add a lint check here for in a loop or function */
+ /*
+ * Have to do this cleanup here, since we don't longjump
+ * back to the main awk rule loop (rule_tag).
+ */
+ pop_all_forloops();
+ pop_fcall_stack();
+
+ do_nextfile();
+ break;
+
+ case Node_K_exit:
+ INCREMENT(tree->exec_count);
+ /*
+ * In A,K,&W, p. 49, it says that an exit statement "...
+ * causes the program to behave as if the end of input had
+ * occurred; no more input is read, and the END actions, if
+ * any are executed." This implies that the rest of the rules
+ * are not done. So we immediately break out of the main loop.
+ */
+ exiting = TRUE;
+ if (tree->lnode != NULL) {
+ t = tree_eval(tree->lnode);
+ exit_val = (int) force_number(t);
+ free_temp(t);
+ }
+ longjmp(rule_tag, TAG_BREAK);
+ break;
+
+ case Node_K_return:
+ INCREMENT(tree->exec_count);
+ t = tree_eval(tree->lnode);
+ if ((t->flags & (PERM|TEMP)) != 0)
+ ret_node = t;
+ else {
+ ret_node = copynode(t); /* don't do a dupnode here */
+ ret_node->flags |= TEMP;
+ }
+ longjmp(func_tag, TAG_RETURN);
+ break;
+
+ default:
+ /*
+ * Appears to be an expression statement. Throw away the
+ * value.
+ */
+ if (do_lint && (tree->type == Node_var || tree->type == Node_var_new))
+ lintwarn(_("statement has no effect"));
+ INCREMENT(tree->exec_count);
+ t = tree_eval(tree);
+ if (t) /* stopme() returns NULL */
+ free_temp(t);
+ break;
+ }
+ return 1;
+}
+
+/*
+ * calc_exp_posint --- calculate x^n for positive integral n,
+ * using exponentiation by squaring without recursion.
+ */
+
+static AWKNUM
+calc_exp_posint(AWKNUM x, long n)
+{
+ AWKNUM mult = 1;
+
+ while (n > 1) {
+ if ((n % 2) == 1)
+ mult *= x;
+ x *= x;
+ n /= 2;
+ }
+ return mult * x;
+}
+
+/* calc_exp --- calculate x1^x2 */
+
+static AWKNUM
+calc_exp(AWKNUM x1, AWKNUM x2)
+{
+ long lx;
+
+ if ((lx = x2) == x2) { /* integer exponent */
+ if (lx == 0)
+ return 1;
+ return (lx > 0) ? calc_exp_posint(x1, lx)
+ : 1.0 / calc_exp_posint(x1, -lx);
+ }
+ return (AWKNUM) pow((double) x1, (double) x2);
+}
+
+/* r_tree_eval --- evaluate a subtree */
+
+NODE *
+r_tree_eval(register NODE *tree, int iscond)
+{
+ register NODE *r, *t1, *t2; /* return value & temporary subtrees */
+ register NODE **lhs;
+ register int di;
+ AWKNUM x, x1, x2;
+#ifdef _CRAY
+ long lx2;
+#endif
+
+#ifndef TREE_EVAL_MACRO
+ if (tree == NULL)
+ cant_happen();
+ if (tree->type == Node_val) {
+ if (tree->stref <= 0)
+ cant_happen();
+ return ((tree->flags & INTLSTR) != 0
+ ? r_force_string(tree)
+ : tree);
+ } else if (tree->type == Node_var) {
+ if (tree->var_value->stref <= 0)
+ cant_happen();
+ if (! var_uninitialized(tree))
+ return tree->var_value;
+ }
+#endif
+
+ if (tree->type == Node_param_list) {
+ if ((tree->flags & FUNC) != 0)
+ fatal(_("can't use function name `%s' as variable or array"),
+ tree->vname);
+
+ tree = stack_ptr[tree->param_cnt];
+
+ if (tree == NULL) {
+ if (do_lint)
+ lintwarn(_("reference to uninitialized argument `%s'"),
+ tree->vname);
+ return Nnull_string;
+ }
+
+ if (do_lint && var_uninitialized(tree))
+ lintwarn(_("reference to uninitialized argument `%s'"),
+ tree->vname);
+ }
+
+ make_scalar(tree);
+
+ switch (tree->type) {
+ case Node_var:
+ if (do_lint && var_uninitialized(tree))
+ lintwarn(_("reference to uninitialized variable `%s'"),
+ tree->vname);
+ return tree->var_value;
+
+ case Node_and:
+ return tmp_number((AWKNUM) (eval_condition(tree->lnode)
+ && eval_condition(tree->rnode)));
+
+ case Node_or:
+ return tmp_number((AWKNUM) (eval_condition(tree->lnode)
+ || eval_condition(tree->rnode)));
+
+ case Node_not:
+ return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
+
+ /* Builtins */
+ case Node_builtin:
+ return (*tree->builtin)(tree->subnode);
+
+ case Node_K_getline:
+ return do_getline(tree);
+
+ case Node_in_array:
+ return tmp_number((AWKNUM) (in_array(tree->lnode, tree->rnode) != NULL));
+
+ case Node_func_call:
+ return func_call(tree);
+
+ /* unary operations */
+ case Node_NR:
+ case Node_FNR:
+ case Node_NF:
+ case Node_FIELDWIDTHS:
+ case Node_FS:
+ case Node_RS:
+ case Node_field_spec:
+ case Node_subscript:
+ case Node_IGNORECASE:
+ case Node_OFS:
+ case Node_ORS:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_BINMODE:
+ case Node_LINT:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ lhs = get_lhs(tree, (Func_ptr *) NULL, TRUE);
+ return *lhs;
+
+ case Node_unary_minus:
+ t1 = tree_eval(tree->subnode);
+ x = -force_number(t1);
+ free_temp(t1);
+ return tmp_number(x);
+
+ case Node_cond_exp:
+ if (eval_condition(tree->lnode))
+ return tree_eval(tree->rnode->lnode);
+ return tree_eval(tree->rnode->rnode);
+
+ case Node_match:
+ case Node_nomatch:
+ case Node_regex:
+ case Node_dynregex:
+ return match_op(tree);
+
+ case Node_concat:
+ {
+ NODE **treelist;
+ NODE **strlist;
+ NODE *save_tree;
+ register NODE **treep;
+ register NODE **strp;
+ register size_t len;
+ register size_t supposed_len;
+ char *str;
+ register char *dest;
+ int alloc_count, str_count;
+ int i;
+
+ /*
+ * This is an efficiency hack for multiple adjacent string
+ * concatenations, to avoid recursion and string copies.
+ *
+ * Node_concat trees grow downward to the left, so
+ * descend to lowest (first) node, accumulating nodes
+ * to evaluate to strings as we go.
+ */
+
+ /*
+ * But first, no arbitrary limits. Count the number of
+ * nodes and malloc the treelist and strlist arrays.
+ * There will be alloc_count + 1 items to concatenate. We
+ * also leave room for an extra pointer at the end to
+ * use as a sentinel. Thus, start alloc_count at 2.
+ */
+ save_tree = tree;
+ for (alloc_count = 2; tree != NULL && tree->type == Node_concat;
+ tree = tree->lnode)
+ alloc_count++;
+ tree = save_tree;
+ emalloc(treelist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
+ emalloc(strlist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
+
+ /* Now, here we go. */
+ treep = treelist;
+ while (tree != NULL && tree->type == Node_concat) {
+ *treep++ = tree->rnode;
+ tree = tree->lnode;
+ }
+ *treep = tree;
+ /*
+ * Now, evaluate to strings in LIFO order, accumulating
+ * the string length, so we can do a single malloc at the
+ * end.
+ *
+ * Evaluate the expressions first, then get their
+ * lengthes, in case one of the expressions has a
+ * side effect that changes one of the others.
+ * See test/nasty.awk.
+ *
+ * dupnode the results a la do_print, to give us
+ * more predicable behavior; compare gawk 3.0.6 to
+ * nawk/mawk on test/nasty.awk.
+ */
+ strp = strlist;
+ supposed_len = len = 0;
+ while (treep >= treelist) {
+ NODE *n;
+
+ /* Here lies the wumpus's brother. R.I.P. */
+ n = force_string(tree_eval(*treep--));
+ *strp = dupnode(n);
+ free_temp(n);
+ supposed_len += (*strp)->stlen;
+ strp++;
+ }
+ *strp = NULL;
+
+ str_count = strp - strlist;
+ strp = strlist;
+ for (i = 0; i < str_count; i++) {
+ len += (*strp)->stlen;
+ strp++;
+ }
+ if (do_lint && supposed_len != len)
+ lintwarn(_("concatenation: side effects in one expression have changed the length of another!"));
+ emalloc(str, char *, len+2, "tree_eval");
+ str[len] = str[len+1] = '\0'; /* for good measure */
+ dest = str;
+ strp = strlist;
+ while (*strp != NULL) {
+ memcpy(dest, (*strp)->stptr, (*strp)->stlen);
+ dest += (*strp)->stlen;
+ unref(*strp);
+ strp++;
+ }
+ r = make_str_node(str, len, ALREADY_MALLOCED);
+ r->flags |= TEMP;
+
+ free(strlist);
+ free(treelist);
+ }
+ return r;
+
+ /* assignments */
+ case Node_assign_concat:
+ {
+ Func_ptr after_assign = NULL;
+ NODE *l, *r;
+
+ /*
+ * Note that something lovely like this:
+ *
+ * BEGIN { a = "a"; a = a (a = "b"); print a }
+ *
+ * is not defined. It could print `ab' or `bb'.
+ * Gawk 3.1.3 prints `ab', so we do that too, simply
+ * by evaluating the LHS first. Ugh.
+ *
+ * Thanks to mary1john@earthlink.net for pointing
+ * out this issue.
+ */
+ lhs = get_lhs(tree->lnode, &after_assign, FALSE);
+ *lhs = force_string(*lhs);
+ l = *lhs;
+ r = force_string(tree_eval(tree->rnode));
+
+ /*
+ * Don't clobber string constants!
+ *
+ * Also check stref; see test/strcat1.awk,
+ * the test for l->stref == 1 can't be an
+ * assertion.
+ *
+ * Thanks again to mary1john@earthlink.net for pointing
+ * out this issue.
+ */
+ if (l != r && (l->flags & PERM) == 0 && l->stref == 1) {
+ size_t nlen = l->stlen + r->stlen + 2;
+
+ erealloc(l->stptr, char *, nlen, "interpret");
+ memcpy(l->stptr + l->stlen, r->stptr, r->stlen);
+ l->stlen += r->stlen;
+ l->stptr[l->stlen] = '\0';
+ } else {
+ char *nval;
+ size_t nlen = l->stlen + r->stlen + 2;
+
+ emalloc(nval, char *, nlen, "interpret");
+ memcpy(nval, l->stptr, l->stlen);
+ memcpy(nval + l->stlen, r->stptr, r->stlen);
+ unref(*lhs);
+ *lhs = make_str_node(nval, l->stlen + r->stlen, ALREADY_MALLOCED);
+ }
+ free_temp(r);
+
+ if (after_assign)
+ (*after_assign)();
+ return *lhs;
+ }
+ case Node_assign:
+ {
+ Func_ptr after_assign = NULL;
+
+ if (do_lint && iscond)
+ lintwarn(_("assignment used in conditional context"));
+ r = tree_eval(tree->rnode);
+ lhs = get_lhs(tree->lnode, &after_assign, FALSE);
+
+ assign_val(lhs, r);
+ if (after_assign)
+ (*after_assign)();
+ return *lhs;
+ }
+
+ /* other assignment types are easier because they are numeric */
+ case Node_preincrement:
+ case Node_predecrement:
+ case Node_postincrement:
+ case Node_postdecrement:
+ case Node_assign_exp:
+ case Node_assign_times:
+ case Node_assign_quotient:
+ case Node_assign_mod:
+ case Node_assign_plus:
+ case Node_assign_minus:
+ return op_assign(tree);
+ default:
+ break; /* handled below */
+ }
+
+ /*
+ * Evaluate subtrees in order to do binary operation, then keep going.
+ * Use dupnode to make sure that these values don't disappear out
+ * from under us during recursive subexpression evaluation.
+ */
+ t1 = dupnode(tree_eval(tree->lnode));
+ t2 = dupnode(tree_eval(tree->rnode));
+
+ switch (tree->type) {
+ case Node_geq:
+ case Node_leq:
+ case Node_greater:
+ case Node_less:
+ case Node_notequal:
+ case Node_equal:
+ di = cmp_nodes(t1, t2);
+ unref(t1);
+ unref(t2);
+ switch (tree->type) {
+ case Node_equal:
+ return tmp_number((AWKNUM) (di == 0));
+ case Node_notequal:
+ return tmp_number((AWKNUM) (di != 0));
+ case Node_less:
+ return tmp_number((AWKNUM) (di < 0));
+ case Node_greater:
+ return tmp_number((AWKNUM) (di > 0));
+ case Node_leq:
+ return tmp_number((AWKNUM) (di <= 0));
+ case Node_geq:
+ return tmp_number((AWKNUM) (di >= 0));
+ default:
+ cant_happen();
+ }
+ break;
+ default:
+ break; /* handled below */
+ }
+
+ x1 = force_number(t1);
+ x2 = force_number(t2);
+ unref(t1);
+ unref(t2);
+ switch (tree->type) {
+ case Node_exp:
+ return tmp_number(calc_exp(x1, x2));
+
+ case Node_times:
+ return tmp_number(x1 * x2);
+
+ case Node_quotient:
+ if (x2 == 0)
+ fatal(_("division by zero attempted"));
+#ifdef _CRAY
+ /* special case for integer division, put in for Cray */
+ lx2 = x2;
+ if (lx2 == 0)
+ return tmp_number(x1 / x2);
+ lx = (long) x1 / lx2;
+ if (lx * x2 == x1)
+ return tmp_number((AWKNUM) lx);
+ else
+#endif
+ return tmp_number(x1 / x2);
+
+ case Node_mod:
+ if (x2 == 0)
+ fatal(_("division by zero attempted in `%%'"));
+#ifdef HAVE_FMOD
+ return tmp_number(fmod(x1, x2));
+#else /* ! HAVE_FMOD */
+ (void) modf(x1 / x2, &x);
+ return tmp_number(x1 - x * x2);
+#endif /* ! HAVE_FMOD */
+
+ case Node_plus:
+ return tmp_number(x1 + x2);
+
+ case Node_minus:
+ return tmp_number(x1 - x2);
+
+ default:
+ fatal(_("illegal type (%s) in tree_eval"), nodetype2str(tree->type));
+ }
+ return (NODE *) 0;
+}
+
+/* eval_condition --- is TREE true or false? Returns 0==false, non-zero==true */
+
+static int
+eval_condition(register NODE *tree)
+{
+ register NODE *t1;
+ register int ret;
+
+ if (tree == NULL) /* Null trees are the easiest kinds */
+ return TRUE;
+ if (tree->type == Node_line_range) {
+ /*
+ * Node_line_range is kind of like Node_match, EXCEPT: the
+ * lnode field (more properly, the condpair field) is a node
+ * of a Node_cond_pair; whether we evaluate the lnode of that
+ * node or the rnode depends on the triggered word. More
+ * precisely: if we are not yet triggered, we tree_eval the
+ * lnode; if that returns true, we set the triggered word.
+ * If we are triggered (not ELSE IF, note), we tree_eval the
+ * rnode, clear triggered if it succeeds, and perform our
+ * action (regardless of success or failure). We want to be
+ * able to begin and end on a single input record, so this
+ * isn't an ELSE IF, as noted above.
+ */
+ if (! tree->triggered) {
+ if (! eval_condition(tree->condpair->lnode))
+ return FALSE;
+ else
+ tree->triggered = TRUE;
+ }
+ /* Else we are triggered */
+ if (eval_condition(tree->condpair->rnode))
+ tree->triggered = FALSE;
+ return TRUE;
+ }
+
+ /*
+ * Could just be J.random expression. in which case, null and 0 are
+ * false, anything else is true
+ */
+
+ t1 = m_tree_eval(tree, TRUE);
+ if (t1->flags & MAYBE_NUM)
+ (void) force_number(t1);
+ if (t1->flags & NUMBER)
+ ret = (t1->numbr != 0.0);
+ else
+ ret = (t1->stlen != 0);
+ free_temp(t1);
+ return ret;
+}
+
+/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
+
+int
+cmp_nodes(register NODE *t1, register NODE *t2)
+{
+ register int ret;
+ register size_t len1, len2;
+ register int l;
+ int ldiff;
+
+ if (t1 == t2)
+ return 0;
+ if (t1->flags & MAYBE_NUM)
+ (void) force_number(t1);
+ if (t2->flags & MAYBE_NUM)
+ (void) force_number(t2);
+ if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
+ if (t1->numbr == t2->numbr)
+ return 0;
+ /* don't subtract, in case one or both are infinite */
+ else if (t1->numbr < t2->numbr)
+ return -1;
+ else
+ return 1;
+ }
+ (void) force_string(t1);
+ (void) force_string(t2);
+ len1 = t1->stlen;
+ len2 = t2->stlen;
+ ldiff = len1 - len2;
+ if (len1 == 0 || len2 == 0)
+ return ldiff;
+ l = (ldiff <= 0 ? len1 : len2);
+ if (IGNORECASE) {
+ const unsigned char *cp1 = (const unsigned char *) t1->stptr;
+ const unsigned char *cp2 = (const unsigned char *) t2->stptr;
+
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ mbstate_t mbs;
+ memset(&mbs, 0, sizeof(mbstate_t));
+ ret = strncasecmpmbs((const char *) cp1, mbs,
+ (const char *) cp2, mbs, l);
+ } else
+#endif
+ /* Could use tolower() here; see discussion above. */
+ for (ret = 0; l-- > 0 && ret == 0; cp1++, cp2++)
+ ret = casetable[*cp1] - casetable[*cp2];
+ } else
+ ret = memcmp(t1->stptr, t2->stptr, l);
+ return (ret == 0 ? ldiff : ret);
+}
+
+/* op_assign --- do +=, -=, etc. */
+
+static NODE *
+op_assign(register NODE *tree)
+{
+ AWKNUM rval, lval;
+ NODE **lhs;
+ NODE *tmp;
+ Func_ptr after_assign = NULL;
+ int post = FALSE;
+
+ /*
+ * For += etc, do the rhs first, since it can rearrange things,
+ * and *then* get the lhs.
+ */
+ if (tree->rnode != NULL) {
+ tmp = tree_eval(tree->rnode);
+ rval = force_number(tmp);
+ free_temp(tmp);
+ } else
+ rval = (AWKNUM) 1.0;
+
+ lhs = get_lhs(tree->lnode, &after_assign, TRUE);
+ lval = force_number(*lhs);
+ unref(*lhs);
+
+ switch(tree->type) {
+ case Node_postincrement:
+ post = TRUE;
+ /* fall through */
+ case Node_preincrement:
+ case Node_assign_plus:
+ *lhs = make_number(lval + rval);
+ break;
+
+ case Node_postdecrement:
+ post = TRUE;
+ /* fall through */
+ case Node_predecrement:
+ case Node_assign_minus:
+ *lhs = make_number(lval - rval);
+ break;
+
+ case Node_assign_exp:
+ *lhs = make_number(calc_exp(lval, rval));
+ break;
+
+ case Node_assign_times:
+ *lhs = make_number(lval * rval);
+ break;
+
+ case Node_assign_quotient:
+ if (rval == (AWKNUM) 0)
+ fatal(_("division by zero attempted in `/='"));
+ {
+#ifdef _CRAY
+ long ltemp;
+
+ /* special case for integer division, put in for Cray */
+ ltemp = rval;
+ if (ltemp == 0) {
+ *lhs = make_number(lval / rval);
+ break;
+ }
+ ltemp = (long) lval / ltemp;
+ if (ltemp * lval == rval)
+ *lhs = make_number((AWKNUM) ltemp);
+ else
+#endif /* _CRAY */
+ *lhs = make_number(lval / rval);
+ }
+ break;
+
+ case Node_assign_mod:
+ if (rval == (AWKNUM) 0)
+ fatal(_("division by zero attempted in `%%='"));
+#ifdef HAVE_FMOD
+ *lhs = make_number(fmod(lval, rval));
+#else /* ! HAVE_FMOD */
+ {
+ AWKNUM t1, t2;
+
+ (void) modf(lval / rval, &t1);
+ t2 = lval - rval * t1;
+ *lhs = make_number(t2);
+ }
+#endif /* ! HAVE_FMOD */
+ break;
+
+ default:
+ cant_happen();
+ }
+
+ if (after_assign)
+ (*after_assign)();
+
+ /* for postincrement or postdecrement, return the old value */
+ return (post ? tmp_number(lval) : *lhs);
+}
+
+/*
+ * Avoiding memory leaks is difficult. In paticular, any of `next',
+ * `nextfile', `break' or `continue' (when not in a loop), can longjmp
+ * out to the outermost level. This leaks memory if it happens in a
+ * called function. It also leaks memory if it happens in a
+ * `for (iggy in foo)' loop, since such loops malloc an array of the
+ * current array indices to loop over, which provides stability.
+ *
+ * The following code takes care of these problems. First comes the
+ * array-loop management code. This can be a stack of arrays being looped
+ * on at any one time. This stack serves for both mainline code and
+ * function body code. As each loop starts and finishes, it pushes its
+ * info onto this stack and off of it; whether the loop is in a function
+ * body or not isn't relevant.
+ *
+ * Since the list of indices is created using dupnode(), when popping
+ * this stack it should be safe to unref() things, and then memory
+ * will get finally released when the function call stack is popped.
+ * This means that the loop_stack should be popped first upon a `next'.
+ */
+
+static struct loop_info {
+ const char *varname; /* variable name, for debugging */
+ NODE **elems; /* list of indices */
+ size_t nelems; /* how many there are */
+} *loop_stack = NULL;
+size_t nloops = 0; /* how many slots there are in the stack */
+size_t nloops_active = 0; /* how many loops are actively stacked */
+
+/* pop_forloop --- pop one for loop off the stack */
+
+static void
+pop_forloop()
+{
+ int i, curloop;
+ struct loop_info *loop;
+
+ assert(nloops_active > 0);
+
+ curloop = --nloops_active; /* 0-based indexing */
+ loop = & loop_stack[curloop];
+
+ for (i = 0; i < loop->nelems; i++)
+ unref(loop->elems[i]);
+
+ free(loop->elems);
+
+ loop->elems = NULL;
+ loop->varname = NULL;
+ loop->nelems = 0;
+}
+
+/* pop_forloops --- pop the for loops stack all the way */
+
+static inline void
+pop_all_forloops()
+{
+ while (nloops_active > 0)
+ pop_forloop(); /* decrements nloops_active for us */
+}
+
+/* push_forloop --- add a single for loop to the stack */
+
+static void
+push_forloop(const char *varname, NODE **elems, size_t nelems)
+{
+#define NLOOPS 4 /* seems like a good guess */
+ if (loop_stack == NULL) {
+ /* allocate stack, set vars */
+ nloops = NLOOPS;
+ emalloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
+ "push_forloop");
+ } else if (nloops_active == nloops) {
+ /* grow stack, set vars */
+ nloops *= 2;
+ erealloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
+ "push_forloop");
+ }
+
+ loop_stack[nloops_active].varname = varname;
+ loop_stack[nloops_active].elems = elems;
+ loop_stack[nloops_active].nelems = nelems;
+ nloops_active++;
+}
+
+/*
+ * 2/2004:
+ * N.B. The code that uses fcalls[] *always* uses indexing.
+ * This avoids severe problems in case fcalls gets realloc()'ed
+ * during recursive tree_eval()'s or whatever, so that we don't
+ * have to carefully reassign pointers into the array. The
+ * minor speed gain from using a pointer was offset too much
+ * by the hassles to get the code right and commented.
+ *
+ * Thanks and a tip of the hatlo to Brian Kernighan.
+ */
+
+static struct fcall {
+ const char *fname; /* function name */
+ size_t count; /* how many args */
+ NODE *arglist; /* list thereof */
+ NODE **prevstack; /* function stack frame of previous function */
+ NODE **stack; /* function stack frame of current function */
+} *fcalls = NULL;
+
+static long fcall_list_size = 0;
+static long curfcall = -1;
+
+/*
+ * get_curfunc_arg_count --- return number actual parameters
+ *
+ * This is for use by dynamically loaded C extension functions.
+ */
+size_t
+get_curfunc_arg_count(void)
+{
+ NODE *argp;
+ size_t argc;
+
+ assert(curfcall >= 0);
+
+ /* count the # of expressions in argument expression list */
+ for (argc = 0, argp = fcalls[curfcall].arglist;
+ argp != NULL; argp = argp->rnode)
+ argc++;
+
+ return argc;
+}
+
+/* pop_fcall --- pop off a single function call */
+
+static void
+pop_fcall()
+{
+ NODE *n, **sp;
+ int count;
+
+ assert(curfcall >= 0);
+ stack_ptr = fcalls[curfcall].prevstack;
+
+ sp = fcalls[curfcall].stack;
+
+ for (count = fcalls[curfcall].count; count > 0; count--) {
+ n = *sp++;
+ if (n->type == Node_var) /* local variable */
+ unref(n->var_value);
+ else if (n->type == Node_var_array) /* local array */
+ assoc_clear(n);
+ freenode(n);
+ }
+ if (fcalls[curfcall].stack) {
+ free((char *) fcalls[curfcall].stack);
+ fcalls[curfcall].stack = NULL;
+ }
+ curfcall--;
+}
+
+/* pop_fcall_stack --- pop off all function args, don't leak memory */
+
+static inline void
+pop_fcall_stack()
+{
+ while (curfcall >= 0)
+ pop_fcall();
+}
+
+/* push_args --- push function arguments onto the stack */
+
+static void
+push_args(int count,
+ NODE *argp,
+ NODE **oldstack,
+ const char *func_name,
+ char **varnames)
+{
+ NODE *arg, *r, **sp;
+ int i;
+
+ if (fcall_list_size == 0) { /* first time */
+ emalloc(fcalls, struct fcall *, 10 * sizeof(struct fcall),
+ "push_args");
+ fcall_list_size = 10;
+ }
+
+ if (++curfcall >= fcall_list_size) {
+ fcall_list_size *= 2;
+ erealloc(fcalls, struct fcall *,
+ fcall_list_size * sizeof(struct fcall), "push_args");
+ }
+
+ if (count > 0)
+ emalloc(fcalls[curfcall].stack, NODE **, count*sizeof(NODE *), "push_args");
+ else
+ fcalls[curfcall].stack = NULL;
+ fcalls[curfcall].count = count;
+ fcalls[curfcall].fname = func_name; /* not used, for debugging, just in case */
+ fcalls[curfcall].arglist = argp;
+ fcalls[curfcall].prevstack = oldstack;
+
+ sp = fcalls[curfcall].stack;
+
+ /* for each calling arg. add NODE * on stack */
+ for (i = 0; i < count; i++) {
+ getnode(r);
+ *sp++ = r;
+ if (argp == NULL) {
+ /* local variable */
+ r->type = Node_var_new;
+ r->var_value = Nnull_string;
+ r->vname = varnames[i];
+ r->rnode = NULL;
+ continue;
+ }
+ arg = argp->lnode;
+ /* call by reference for arrays; see below also */
+ if (arg->type == Node_param_list)
+ arg = fcalls[curfcall].prevstack[arg->param_cnt];
+
+ if (arg->type == Node_var_array || arg->type == Node_var_new) {
+ r->type = Node_array_ref;
+ r->orig_array = arg;
+ r->prev_array = arg;
+ } else if (arg->type == Node_array_ref) {
+ *r = *arg;
+ r->prev_array = arg;
+ } else {
+ NODE *n = tree_eval(arg);
+
+ r->type = Node_var;
+ r->lnode = dupnode(n);
+ r->rnode = (NODE *) NULL;
+ free_temp(n);
+ }
+ r->vname = varnames[i];
+ argp = argp->rnode;
+ }
+
+ if (argp != NULL) {
+ /* Left over calling args. */
+ warning(
+ _("function `%s' called with more arguments than declared"),
+ func_name);
+ /* Evaluate them, they may have side effects: */
+ do {
+ arg = argp->lnode;
+ if (arg->type == Node_param_list)
+ arg = fcalls[curfcall].prevstack[arg->param_cnt];
+ if (arg->type != Node_var_array &&
+ arg->type != Node_array_ref &&
+ arg->type != Node_var_new)
+ free_temp(tree_eval(arg));
+ } while ((argp = argp->rnode) != NULL);
+ }
+
+ stack_ptr = fcalls[curfcall].stack;
+}
+
+/* func_call --- call a function, call by reference for arrays */
+
+NODE **stack_ptr;
+
+static NODE *
+func_call(NODE *tree)
+{
+ register NODE *r;
+ NODE *name, *arg_list;
+ NODE *f;
+ jmp_buf volatile func_tag_stack;
+ jmp_buf volatile loop_tag_stack;
+ int volatile save_loop_tag_valid = FALSE;
+ NODE *save_ret_node;
+ extern NODE *ret_node;
+
+ /* tree->rnode is a Node_val giving function name */
+ /* tree->lnode is Node_expression_list of calling args. */
+ name = tree->rnode;
+ arg_list = tree->lnode;
+
+ /* retrieve function definition node */
+ if (tree->funcbody != NULL)
+ f = tree->funcbody;
+ else {
+ f = lookup(name->stptr);
+ if (f == NULL || f->type != Node_func)
+ fatal(_("function `%s' not defined"), name->stptr);
+
+ tree->funcbody = f; /* save for next call */
+ }
+
+#ifdef FUNC_TRACE
+ fprintf(stderr, "function `%s' called\n", name->stptr);
+#endif
+ push_args(f->lnode->param_cnt, arg_list, stack_ptr, name->stptr,
+ f->parmlist);
+
+ /*
+ * Execute function body, saving context, as a return statement
+ * will longjmp back here.
+ *
+ * Have to save and restore the loop_tag stuff so that a return
+ * inside a loop in a function body doesn't scrog any loops going
+ * on in the main program. We save the necessary info in variables
+ * local to this function so that function nesting works OK.
+ * We also only bother to save the loop stuff if we're in a loop
+ * when the function is called.
+ */
+ if (loop_tag_valid) {
+ int junk = 0;
+
+ save_loop_tag_valid = (volatile int) loop_tag_valid;
+ PUSH_BINDING(loop_tag_stack, loop_tag, junk);
+ loop_tag_valid = FALSE;
+ }
+ PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
+ save_ret_node = ret_node;
+ ret_node = Nnull_string; /* default return value */
+ INCREMENT(f->exec_count); /* count function calls */
+ if (setjmp(func_tag) == 0)
+ (void) interpret(f->rnode);
+
+ r = ret_node;
+ ret_node = (NODE *) save_ret_node;
+ RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
+ pop_fcall();
+
+ /* Restore the loop_tag stuff if necessary. */
+ if (save_loop_tag_valid) {
+ int junk = 0;
+
+ loop_tag_valid = (int) save_loop_tag_valid;
+ RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
+ }
+
+ return r;
+}
+
+#ifdef PROFILING
+/* dump_fcall_stack --- print a backtrace of the awk function calls */
+
+void
+dump_fcall_stack(FILE *fp)
+{
+ int i;
+
+ if (curfcall < 0)
+ return;
+
+ fprintf(fp, _("\n\t# Function Call Stack:\n\n"));
+ for (i = curfcall; i >= 0; i--)
+ fprintf(fp, "\t# %3d. %s\n", i+1, fcalls[i].fname);
+ fprintf(fp, _("\t# -- main --\n"));
+}
+#endif /* PROFILING */
+
+/*
+ * r_get_lhs:
+ * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
+ * value of the var, or where to store the var's new value
+ *
+ * For the special variables, don't unref their current value if it's
+ * the same as the internal copy; perhaps the current one is used in
+ * a concatenation or some other expression somewhere higher up in the
+ * call chain. Ouch.
+ */
+
+NODE **
+r_get_lhs(register NODE *ptr, Func_ptr *assign, int reference)
+{
+ register NODE **aptr = NULL;
+ register NODE *n;
+
+ if (assign)
+ *assign = NULL; /* for safety */
+ if (ptr->type == Node_param_list) {
+ if ((ptr->flags & FUNC) != 0)
+ fatal(_("can't use function name `%s' as variable or array"), ptr->vname);
+ ptr = stack_ptr[ptr->param_cnt];
+ }
+
+ make_scalar(ptr);
+
+ switch (ptr->type) {
+ case Node_var:
+ if (do_lint && reference && var_uninitialized(ptr))
+ lintwarn(_("reference to uninitialized variable `%s'"),
+ ptr->vname);
+
+ aptr = &(ptr->var_value);
+#ifdef GAWKDEBUG
+ if (ptr->var_value->stref <= 0)
+ cant_happen();
+#endif
+ break;
+
+ case Node_FIELDWIDTHS:
+ aptr = &(FIELDWIDTHS_node->var_value);
+ if (assign != NULL)
+ *assign = set_FIELDWIDTHS;
+ break;
+
+ case Node_RS:
+ aptr = &(RS_node->var_value);
+ if (assign != NULL)
+ *assign = set_RS;
+ break;
+
+ case Node_FS:
+ aptr = &(FS_node->var_value);
+ if (assign != NULL)
+ *assign = set_FS;
+ break;
+
+ case Node_FNR:
+ if (FNR_node->var_value->numbr != FNR) {
+ unref(FNR_node->var_value);
+ FNR_node->var_value = make_number((AWKNUM) FNR);
+ }
+ aptr = &(FNR_node->var_value);
+ if (assign != NULL)
+ *assign = set_FNR;
+ break;
+
+ case Node_NR:
+ if (NR_node->var_value->numbr != NR) {
+ unref(NR_node->var_value);
+ NR_node->var_value = make_number((AWKNUM) NR);
+ }
+ aptr = &(NR_node->var_value);
+ if (assign != NULL)
+ *assign = set_NR;
+ break;
+
+ case Node_NF:
+ if (NF == -1 || NF_node->var_value->numbr != NF) {
+ if (NF == -1)
+ (void) get_field(UNLIMITED-1, assign); /* parse record */
+ unref(NF_node->var_value);
+ NF_node->var_value = make_number((AWKNUM) NF);
+ }
+ aptr = &(NF_node->var_value);
+ if (assign != NULL)
+ *assign = set_NF;
+ break;
+
+ case Node_IGNORECASE:
+ aptr = &(IGNORECASE_node->var_value);
+ if (assign != NULL)
+ *assign = set_IGNORECASE;
+ break;
+
+ case Node_BINMODE:
+ aptr = &(BINMODE_node->var_value);
+ if (assign != NULL)
+ *assign = set_BINMODE;
+ break;
+
+ case Node_LINT:
+ aptr = &(LINT_node->var_value);
+ if (assign != NULL)
+ *assign = set_LINT;
+ break;
+
+ case Node_OFMT:
+ aptr = &(OFMT_node->var_value);
+ if (assign != NULL)
+ *assign = set_OFMT;
+ break;
+
+ case Node_CONVFMT:
+ aptr = &(CONVFMT_node->var_value);
+ if (assign != NULL)
+ *assign = set_CONVFMT;
+ break;
+
+ case Node_ORS:
+ aptr = &(ORS_node->var_value);
+ if (assign != NULL)
+ *assign = set_ORS;
+ break;
+
+ case Node_OFS:
+ aptr = &(OFS_node->var_value);
+ if (assign != NULL)
+ *assign = set_OFS;
+ break;
+
+ case Node_SUBSEP:
+ aptr = &(SUBSEP_node->var_value);
+ if (assign != NULL)
+ *assign = set_SUBSEP;
+ break;
+
+ case Node_TEXTDOMAIN:
+ aptr = &(TEXTDOMAIN_node->var_value);
+ if (assign != NULL)
+ *assign = set_TEXTDOMAIN;
+ break;
+
+ case Node_field_spec:
+ {
+ int field_num;
+
+ n = tree_eval(ptr->lnode);
+ if (do_lint) {
+ if ((n->flags & NUMBER) == 0) {
+ lintwarn(_("attempt to field reference from non-numeric value"));
+ if (n->stlen == 0)
+ lintwarn(_("attempt to reference from null string"));
+ }
+ }
+ field_num = (int) force_number(n);
+ free_temp(n);
+ if (field_num < 0)
+ fatal(_("attempt to access field %d"), field_num);
+ if (field_num == 0 && field0_valid) { /* short circuit */
+ aptr = &fields_arr[0];
+ if (assign != NULL)
+ *assign = reset_record;
+ } else
+ aptr = get_field(field_num, assign);
+ if (do_lint && reference && (*aptr == Null_field || *aptr == Nnull_string))
+ lintwarn(_("reference to uninitialized field `$%d'"),
+ field_num);
+ break;
+ }
+
+ case Node_subscript:
+ n = get_array(ptr->lnode);
+ aptr = assoc_lookup(n, concat_exp(ptr->rnode), reference);
+ break;
+
+ case Node_builtin:
+#if 1
+ /* in gawk for a while */
+ fatal(_("assignment is not allowed to result of builtin function"));
+#else
+ /*
+ * This is how Christos at Deshaw did it.
+ * Does this buy us anything?
+ */
+ if (ptr->builtin == NULL)
+ fatal(_("assignment is not allowed to result of builtin function"));
+ ptr->callresult = (*ptr->builtin)(ptr->subnode);
+ aptr = &ptr->callresult;
+ break;
+#endif
+
+ default:
+ fprintf(stderr, "type = %s\n", nodetype2str(ptr->type));
+ fflush(stderr);
+ cant_happen();
+ }
+ return aptr;
+}
+
+/* match_op --- do ~ and !~ */
+
+static NODE *
+match_op(register NODE *tree)
+{
+ register NODE *t1;
+ register Regexp *rp;
+ int i;
+ int match = TRUE;
+ int kludge_need_start = 0; /* FIXME: --- see below */
+
+ if (tree->type == Node_nomatch)
+ match = FALSE;
+ if (tree->type == Node_regex)
+ t1 = *get_field(0, (Func_ptr *) 0);
+ else {
+ t1 = force_string(tree_eval(tree->lnode));
+ tree = tree->rnode;
+ }
+ rp = re_update(tree);
+ /*
+ * FIXME:
+ *
+ * Any place where research() is called with a last parameter of
+ * zero, we need to use the avoid_dfa test. This appears here and
+ * in the code for Node_K_switch.
+ *
+ * A new or improved dfa that distinguishes beginning/end of
+ * string from beginning/end of line will allow us to get rid of
+ * this temporary hack.
+ *
+ * The avoid_dfa() function is in re.c; it is not very smart.
+ */
+ if (avoid_dfa(tree, t1->stptr, t1->stlen))
+ kludge_need_start = RE_NEED_START;
+ i = research(rp, t1->stptr, 0, t1->stlen, kludge_need_start);
+ i = (i == -1) ^ (match == TRUE);
+ free_temp(t1);
+ return tmp_number((AWKNUM) i);
+}
+
+/* set_IGNORECASE --- update IGNORECASE as appropriate */
+
+void
+set_IGNORECASE()
+{
+ static int warned = FALSE;
+
+ if ((do_lint || do_traditional) && ! warned) {
+ warned = TRUE;
+ lintwarn(_("`IGNORECASE' is a gawk extension"));
+ }
+ load_casetable();
+ if (do_traditional)
+ IGNORECASE = FALSE;
+ else if ((IGNORECASE_node->var_value->flags & (STRING|STRCUR)) != 0) {
+ if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
+ IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
+ else
+ IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
+ } else if ((IGNORECASE_node->var_value->flags & (NUMCUR|NUMBER)) != 0)
+ IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
+ else
+ IGNORECASE = FALSE; /* shouldn't happen */
+
+ set_RS(); /* set_RS() calls set_FS() if need be, for us */
+}
+
+/* set_BINMODE --- set translation mode (OS/2, DOS, others) */
+
+void
+set_BINMODE()
+{
+ static int warned = FALSE;
+ char *p, *cp, save;
+ NODE *v;
+ int digits = FALSE;
+
+ if ((do_lint || do_traditional) && ! warned) {
+ warned = TRUE;
+ lintwarn(_("`BINMODE' is a gawk extension"));
+ }
+ if (do_traditional)
+ BINMODE = 0;
+ else if ((BINMODE_node->var_value->flags & STRING) != 0) {
+ v = BINMODE_node->var_value;
+ p = v->stptr;
+ save = p[v->stlen];
+ p[v->stlen] = '\0';
+
+ for (cp = p; *cp != '\0'; cp++) {
+ if (ISDIGIT(*cp)) {
+ digits = TRUE;
+ break;
+ }
+ }
+
+ if (! digits || (BINMODE_node->var_value->flags & MAYBE_NUM) == 0) {
+ BINMODE = 0;
+ if (strcmp(p, "r") == 0)
+ BINMODE = 1;
+ else if (strcmp(p, "w") == 0)
+ BINMODE = 2;
+ else if (strcmp(p, "rw") == 0 || strcmp(p, "wr") == 0)
+ BINMODE = 3;
+
+ if (BINMODE == 0 && v->stlen != 0) {
+ /* arbitrary string, assume both */
+ BINMODE = 3;
+ warning("BINMODE: arbitrary string value treated as \"rw\"");
+ }
+ } else
+ BINMODE = (int) force_number(BINMODE_node->var_value);
+
+ p[v->stlen] = save;
+ } else if ((BINMODE_node->var_value->flags & NUMBER) != 0)
+ BINMODE = (int) force_number(BINMODE_node->var_value);
+ else
+ BINMODE = 0; /* shouldn't happen */
+}
+
+/* set_OFS --- update OFS related variables when OFS assigned to */
+
+void
+set_OFS()
+{
+ OFS = force_string(OFS_node->var_value)->stptr;
+ OFSlen = OFS_node->var_value->stlen;
+ OFS[OFSlen] = '\0';
+}
+
+/* set_ORS --- update ORS related variables when ORS assigned to */
+
+void
+set_ORS()
+{
+ ORS = force_string(ORS_node->var_value)->stptr;
+ ORSlen = ORS_node->var_value->stlen;
+ ORS[ORSlen] = '\0';
+}
+
+/* fmt_ok --- is the conversion format a valid one? */
+
+NODE **fmt_list = NULL;
+static int fmt_ok P((NODE *n));
+static int fmt_index P((NODE *n));
+
+static int
+fmt_ok(NODE *n)
+{
+ NODE *tmp = force_string(n);
+ const char *p = tmp->stptr;
+#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
+ static const char float_formats[] = "efgEG";
+#else
+ static const char float_formats[] = "efgEFG";
+#endif
+#if defined(HAVE_LOCALE_H)
+ static const char flags[] = " +-#'";
+#else
+ static const char flags[] = " +-#";
+#endif
+
+ if (*p++ != '%')
+ return 0;
+ while (*p && strchr(flags, *p) != NULL) /* flags */
+ p++;
+ while (*p && ISDIGIT(*p)) /* width - %*.*g is NOT allowed */
+ p++;
+ if (*p == '\0' || (*p != '.' && ! ISDIGIT(*p)))
+ return 0;
+ if (*p == '.')
+ p++;
+ while (*p && ISDIGIT(*p)) /* precision */
+ p++;
+ if (*p == '\0' || strchr(float_formats, *p) == NULL)
+ return 0;
+ if (*++p != '\0')
+ return 0;
+ return 1;
+}
+
+/* fmt_index --- track values of OFMT and CONVFMT to keep semantics correct */
+
+static int
+fmt_index(NODE *n)
+{
+ register int ix = 0;
+ static int fmt_num = 4;
+ static int fmt_hiwater = 0;
+
+ if (fmt_list == NULL)
+ emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
+ (void) force_string(n);
+ while (ix < fmt_hiwater) {
+ if (cmp_nodes(fmt_list[ix], n) == 0)
+ return ix;
+ ix++;
+ }
+ /* not found */
+ n->stptr[n->stlen] = '\0';
+ if (do_lint && ! fmt_ok(n))
+ lintwarn(_("bad `%sFMT' specification `%s'"),
+ n == CONVFMT_node->var_value ? "CONV"
+ : n == OFMT_node->var_value ? "O"
+ : "", n->stptr);
+
+ if (fmt_hiwater >= fmt_num) {
+ fmt_num *= 2;
+ erealloc(fmt_list, NODE **, fmt_num * sizeof(*fmt_list), "fmt_index");
+ }
+ fmt_list[fmt_hiwater] = dupnode(n);
+ return fmt_hiwater++;
+}
+
+/* set_OFMT --- track OFMT correctly */
+
+void
+set_OFMT()
+{
+ OFMTidx = fmt_index(OFMT_node->var_value);
+ OFMT = fmt_list[OFMTidx]->stptr;
+}
+
+/* set_CONVFMT --- track CONVFMT correctly */
+
+void
+set_CONVFMT()
+{
+ CONVFMTidx = fmt_index(CONVFMT_node->var_value);
+ CONVFMT = fmt_list[CONVFMTidx]->stptr;
+}
+
+/* set_LINT --- update LINT as appropriate */
+
+void
+set_LINT()
+{
+#ifndef NO_LINT
+ int old_lint = do_lint;
+
+ if ((LINT_node->var_value->flags & (STRING|STRCUR)) != 0) {
+ if ((LINT_node->var_value->flags & MAYBE_NUM) == 0) {
+ const char *lintval;
+ size_t lintlen;
+
+ do_lint = (force_string(LINT_node->var_value)->stlen > 0);
+ lintval = LINT_node->var_value->stptr;
+ lintlen = LINT_node->var_value->stlen;
+ if (do_lint) {
+ do_lint = LINT_ALL;
+ if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
+ lintfunc = r_fatal;
+ else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0)
+ do_lint = LINT_INVALID;
+ else
+ lintfunc = warning;
+ } else
+ lintfunc = warning;
+ } else {
+ if (force_number(LINT_node->var_value) != 0.0)
+ do_lint = LINT_ALL;
+ else
+ do_lint = FALSE;
+ lintfunc = warning;
+ }
+ } else if ((LINT_node->var_value->flags & (NUMCUR|NUMBER)) != 0) {
+ if (force_number(LINT_node->var_value) != 0.0)
+ do_lint = LINT_ALL;
+ else
+ do_lint = FALSE;
+ lintfunc = warning;
+ } else
+ do_lint = FALSE; /* shouldn't happen */
+
+ if (! do_lint)
+ lintfunc = warning;
+
+ /* explicitly use warning() here, in case lintfunc == r_fatal */
+ if (old_lint != do_lint && old_lint && do_lint == FALSE)
+ warning(_("turning off `--lint' due to assignment to `LINT'"));
+#endif /* ! NO_LINT */
+}
+
+/* set_TEXTDOMAIN --- update TEXTDOMAIN variable when TEXTDOMAIN assigned to */
+
+void
+set_TEXTDOMAIN()
+{
+ int len;
+
+ TEXTDOMAIN = force_string(TEXTDOMAIN_node->var_value)->stptr;
+ len = TEXTDOMAIN_node->var_value->stlen;
+ TEXTDOMAIN[len] = '\0';
+ /*
+ * Note: don't call textdomain(); this value is for
+ * the awk program, not for gawk itself.
+ */
+}
+
+/*
+ * assign_val --- do mechanics of assignment, for calling from multiple
+ * places.
+ */
+
+NODE *
+assign_val(NODE **lhs_p, NODE *rhs)
+{
+ if (rhs != *lhs_p) {
+ /*
+ * Since we know that the nodes are different,
+ * we can do the unref() before the dupnode().
+ */
+ unref(*lhs_p);
+ *lhs_p = dupnode(rhs);
+ }
+ return *lhs_p;
+}
+
+/* update_ERRNO_saved --- update the value of ERRNO based on argument */
+
+void
+update_ERRNO_saved(int errcode)
+{
+ char *cp;
+
+ cp = strerror(errcode);
+ cp = gettext(cp);
+ unref(ERRNO_node->var_value);
+ ERRNO_node->var_value = make_string(cp, strlen(cp));
+}
+
+/* update_ERRNO --- update the value of ERRNO based on errno */
+
+void
+update_ERRNO()
+{
+ update_ERRNO_saved(errno);
+}
+
+/* comp_func --- array index comparison function for qsort */
+
+static int
+comp_func(const void *p1, const void *p2)
+{
+ size_t len1, len2;
+ const char *str1, *str2;
+ const NODE *t1, *t2;
+ int cmp1;
+
+ t1 = *((const NODE *const *) p1);
+ t2 = *((const NODE *const *) p2);
+
+/*
+ t1 = force_string(t1);
+ t2 = force_string(t2);
+*/
+ len1 = t1->ahname_len;
+ str1 = t1->ahname_str;
+
+ len2 = t2->ahname_len;
+ str2 = t2->ahname_str;
+
+ /* Array indexes are strings, compare as such, always! */
+ cmp1 = memcmp(str1, str2, len1 < len2 ? len1 : len2);
+ /* if prefixes are equal, size matters */
+ return (cmp1 != 0 ? cmp1 :
+ len1 < len2 ? -1 : (len1 > len2));
+}
--- /dev/null
+/*
+ * eval_p.c - compile eval.c with profiling turned on.
+ */
+
+/*
+ * Copyright (C) 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define PROFILING 1
+#include "eval.c"
--- /dev/null
+/*
+ * ext.c - Builtin function that links external gawk functions and related
+ * utilities.
+ *
+ * Christos Zoulas, Thu Jun 29 17:40:41 EDT 1995
+ * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998
+ */
+
+/*
+ * Copyright (C) 1995 - 2001, 2003-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+#ifdef DYNAMIC
+
+#include <dlfcn.h>
+
+#ifdef __GNUC__
+static unsigned long long dummy; /* fake out gcc for dynamic loading? */
+#endif
+
+extern int errcount;
+
+/* do_ext --- load an extension */
+
+NODE *
+do_ext(NODE *tree)
+{
+ NODE *obj;
+ NODE *fun;
+ NODE *(*func) P((NODE *, void *));
+ void *dl;
+ int flags = RTLD_LAZY;
+
+#ifdef __GNUC__
+ AWKNUM junk;
+
+ junk = (AWKNUM) dummy;
+#endif
+
+ if (do_lint)
+ lintwarn(_("`extension' is a gawk extension"));
+
+ if (do_traditional || do_posix) {
+ errcount++;
+ error(_("`extension' is a gawk extension"));
+ }
+
+ obj = tree_eval(tree->lnode);
+ force_string(obj);
+
+#ifdef RTLD_GLOBAL
+ flags |= RTLD_GLOBAL;
+#endif
+ if ((dl = dlopen(obj->stptr, flags)) == NULL)
+ fatal(_("extension: cannot open `%s' (%s)\n"), obj->stptr,
+ dlerror());
+
+ fun = tree_eval(tree->rnode->lnode);
+ force_string(fun);
+
+ func = (NODE *(*) P((NODE *, void *))) dlsym(dl, fun->stptr);
+ if (func == NULL)
+ fatal(_("extension: library `%s': cannot call function `%s' (%s)\n"),
+ obj->stptr, fun->stptr, dlerror());
+ free_temp(obj);
+ free_temp(fun);
+
+ return (*func)(tree, dl);
+}
+
+/* make_builtin --- register name to be called as func with a builtin body */
+
+void
+make_builtin(char *name, NODE *(*func) P((NODE *)), int count)
+{
+ NODE *p, *b, *f;
+ char **vnames, *parm_names, *sp;
+ char c, buf[200];
+ int space_needed, i;
+
+ sp = name;
+ if (sp == NULL || *sp == '\0')
+ fatal(_("extension: missing function name"));
+
+ while ((c = *sp++) != '\0')
+ if ((sp == &name[1] && c != '_' && ! ISALPHA(c))
+ || (sp > &name[1] && ! is_identchar(c)))
+ fatal(_("extension: illegal character `%c' in function name `%s'"), c, name);
+
+ f = lookup(name);
+ if (f != NULL) {
+ if (f->type == Node_func) {
+ if (f->rnode->type != Node_builtin) /* user-defined function */
+ fatal(_("extension: can't redefine function `%s'"), name);
+ else {
+ /* multiple extension() calls etc. */
+ if (do_lint)
+ lintwarn(_("extension: function `%s' already defined"), name);
+ return;
+ }
+ } else {
+ if (check_special(name) >= 0)
+ fatal(_("extension: can't use gawk built-in `%s' as function name"), name);
+ /* variable name etc. */
+ fatal(_("extension: function name `%s' previously defined"), name);
+ }
+ }
+
+ /* count parameters, create artificial list of param names */
+ space_needed = 0;
+ for (i = 0; i < count; i++) {
+ sprintf(buf, "p%d", i);
+ space_needed += strlen(buf) + 1;
+ }
+ emalloc(parm_names, char *, space_needed, "make_builtin");
+ emalloc(vnames, char **, count * sizeof(char *), "make_builtin");
+ sp = parm_names;
+ for (i = 0; i < count; i++) {
+ sprintf(sp, "p%d",i);
+ vnames[i] = sp;
+ sp += strlen(sp) + 1;
+ }
+
+ getnode(p);
+ p->type = Node_param_list;
+ p->flags |= FUNC;
+ p->rnode = NULL;
+ p->param = name;
+ p->param_cnt = count;
+#if 0
+ /* setting these blows away the param_cnt. dang unions! */
+ p->source_line = __LINE__;
+ p->source_file = __FILE__;
+#endif
+
+ getnode(b);
+ b->type = Node_builtin;
+ b->builtin = func;
+ b->subnode = p;
+ b->source_line = __LINE__;
+ b->source_file = __FILE__;
+
+ f = node(p, Node_func, b);
+ f->parmlist = vnames;
+ install(name, f);
+}
+
+/* get_argument --- Get the n'th argument of a dynamically linked function */
+
+NODE *
+get_argument(NODE *tree, int i)
+{
+ extern NODE **stack_ptr;
+ int actual_args;
+
+ actual_args = get_curfunc_arg_count();
+ if (i < 0 || i >= tree->param_cnt || i >= actual_args)
+ return NULL;
+
+ tree = stack_ptr[i];
+ if (tree->type == Node_array_ref)
+ tree = tree->orig_array;
+ if (tree->type == Node_var_new || tree->type == Node_var_array)
+ return tree;
+
+ return tree->lnode;
+}
+
+/* get_actual_argument --- get a scalar or array, allowed to be optional */
+
+NODE *
+get_actual_argument(NODE *tree, unsigned int i, int optional, int want_array)
+{
+ /* optional : if TRUE and i th argument not present return NULL, else fatal. */
+
+ NODE *t;
+
+ t = get_argument(tree, i);
+
+ if (t == NULL) {
+ if (i >= tree->param_cnt) /* must be fatal */
+ fatal(_("function `%s' defined to take no more than %d argument(s)"),
+ tree->param, tree->param_cnt);
+ if (! optional)
+ fatal(_("function `%s': missing argument #%d"),
+ tree->param, i + 1);
+ return NULL;
+ }
+
+ if (t->type == Node_var_new)
+ return (want_array ? get_array(t) : tree_eval(t));
+
+ if (want_array) {
+ if (t->type != Node_var_array)
+ fatal(_("function `%s': argument #%d: attempt to use scalar as an array"),
+ tree->param, i + 1);
+ } else {
+ if (t->type != Node_val)
+ fatal(_("function `%s': argument #%d: attempt to use array as a scalar"),
+ tree->param, i + 1);
+ }
+ return t;
+}
+
+/* set_value --- set the return value of a dynamically linked function */
+
+void
+set_value(NODE *tree)
+{
+ extern NODE *ret_node;
+
+ if (tree)
+ ret_node = tree;
+ else
+ ret_node = Nnull_string;
+}
+#else
+
+/* do_ext --- dummy version if extensions not available */
+
+NODE *
+do_ext(NODE *tree)
+{
+ const char *emsg = _("Operation Not Supported");
+
+ unref(ERRNO_node->var_value);
+ ERRNO_node->var_value = make_string((char *) emsg, strlen(emsg));
+ return tmp_number((AWKNUM) -1);
+}
+#endif
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Sun Jun 26 09:03:32 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_stat): Check return value from readlink()
+ for error. Pass in `sizeof(buf) - 1' to leave room for trailing
+ zero byte. From: Glenn Zazulia <gnu@t1.zazu.com>.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Jun 21 17:02:37 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ More from John Haque.
+
+ * testarg.c, testarg.awk: New files.
+ * arrayparm.c (do_mkarray): Change call of `get_curfunc_parm_count'
+ to `get_curfunc_arg_count'.
+ * filefuncs.c (do_chdir, do_stat): Ditto.
+ * fork.c (do_fork, do_waitpid): Ditto.
+ * ordchr.c (do_ord, do_chr): Ditto.
+ * readfile.c (do_readfile): Ditto.
+ * steps: Updated.
+
+Mon Jun 14 14:01:16 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ ChangeLog started.
+
+ Changes from John Haque and ADR to rationalize extension functions.
+
+ * extension/filefuncs.c: Revised for new functionality. See
+ corresponding entry in main ChangeLog.
--- /dev/null
+# Makefile for gawk extensions Mar 2003\r
+\r
+# - for GNU C (mingw32) [Windows32 executable for Windows 9x/NT]\r
+# - for Microsoft C 7 [16bit ececutable for DOS]\r
+\r
+# see README.pc for comments\r
+\r
+#------------------------------------------------------------------------\r
+# Some makes do not define MAKE (and ndmake does not allow a define).\r
+# Define MAK to be your make command.\r
+#MAKE = dmake\r
+MAK = $(MAKE) $(MAKEFILE)\r
+#MAK = $(MAKE)\r
+#MAKEFILE = -f Makefile\r
+#MAK = make45 $(MAKEFILE)\r
+\r
+VCCFLAGS=-nologo -O2 -DWIN32 -DWIN32_EXTENSION -D__STDC__=0 -DGAWK -I.. -DHAVE_CONFIG_H -DDYNAMIC\r
+VCLDFLAGS=-LD ../gawk.lib\r
+VCCC=cl -nologo\r
+\r
+MWCFLAGS=-O -shared -DWIN32 -DWIN32_EXTENSION -DGAWK -I.. -DHAVE_CONFIG_H -DDYNAMIC\r
+MWLDFLAGS=-s -Wl,--enable-stdcall-fixup -L.. -lgawk\r
+MWCC=gcc\r
+\r
+# this DEFFILE will work provided the exported function is always called\r
+# dlload\r
+DEFFILE=pcext.def\r
+\r
+\r
+default:\r
+ @echo "Enter $(MAK) target "\r
+ @echo " where 'target' is chosen from " \r
+ @echo " mingw32 . Windows32 exe [Mingw32 GNU C] "\r
+ @echo " vcWin32 . Windows32 exe [Microsoft Visual C] "\r
+\r
+.SUFFIXES: .c .dll\r
+\r
+.c.dll:\r
+ $(CC) $(CFLAGS) $< -o$@ $(LDFLAGS) $(DEFFILE)\r
+\r
+\r
+# dl.c, fork.c, and filefuncs.c don't compile cleanly...\r
+all : readfile.dll ordchr.dll arrayparm.dll\r
+\r
+vcWin32:\r
+ $(MAK) CFLAGS="$(VCCFLAGS)" LDFLAGS="$(VCLDFLAGS)" CC="$(VCCC)" all\r
+\r
+mingw32:\r
+ $(MAK) CFLAGS="$(MWCFLAGS)" LDFLAGS="$(MWLDFLAGS)" CC="$(MWCC)" all\r
+\r
+clean:\r
+ -rm *.dll\r
+ -rm *.o\r
+ -rm *.obj\r
+ -rm *.lib\r
--- /dev/null
+/*
+ * arrayparm.c --- figure out how to make a parameter be an array
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * 10/2001
+ *
+ * Revised 7/2003
+ * Revised 6/2004
+ */
+
+/*
+ * Copyright (C) 2001, 2003, 2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/* do_mkarray --- turn a variable into an array */
+
+/*
+ * From awk, call
+ *
+ * mkarray(var, sub, val)
+ */
+
+static NODE *
+do_mkarray(tree)
+NODE *tree;
+{
+ int ret = -1;
+ NODE *var, *sub, *val;
+ NODE **elemval;
+
+ if (do_lint && get_curfunc_arg_count() > 3)
+ lintwarn("mkarray: called with too many arguments");
+
+ var = get_argument(tree, 0);
+ if (var == NULL)
+ var = stack_ptr[0];
+
+ var = get_array(var);
+ sub = get_argument(tree, 1);
+ val = get_argument(tree, 2);
+
+ printf("var->type = %s\n", nodetype2str(var->type));
+ printf("sub->type = %s\n", nodetype2str(sub->type));
+ printf("val->type = %s\n", nodetype2str(val->type));
+
+ assoc_clear(var);
+
+ elemval = assoc_lookup(var, sub, 0);
+ *elemval = dupnode(val);
+ ret = 0;
+
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("mkarray", do_mkarray, 3);
+
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+/*
+ * dl.c - Example of adding a new builtin function to gawk.
+ *
+ * Christos Zoulas, Thu Jun 29 17:40:41 EDT 1995
+ * Arnold Robbins, update for 3.1, Wed Sep 13 09:38:56 2000
+ */
+
+/*
+ * Copyright (C) 1995 - 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+#include <dlfcn.h>
+
+static void *sdl = NULL;
+
+static NODE *
+zaxxon(tree)
+NODE *tree;
+{
+ NODE *obj;
+ int i;
+ int comma = 0;
+
+ /*
+ * Print the arguments
+ */
+ printf("External linkage %s(", tree->param);
+
+ for (i = 0; i < tree->param_cnt; i++) {
+
+ obj = get_argument(tree, i);
+
+ if (obj == NULL)
+ break;
+
+ force_string(obj);
+
+ printf(comma ? ", %s" : "%s", obj->stptr);
+ free_temp(obj);
+ comma = 1;
+ }
+
+ printf(");\n");
+
+ /*
+ * Do something useful
+ */
+ obj = get_argument(tree, 0);
+
+ if (obj != NULL) {
+ force_string(obj);
+ if (strcmp(obj->stptr, "unload") == 0 && sdl) {
+ /*
+ * XXX: How to clean up the function?
+ * I would like the ability to remove a function...
+ */
+ dlclose(sdl);
+ sdl = NULL;
+ }
+ free_temp(obj);
+ }
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) 3.14));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ sdl = dl;
+ make_builtin("zaxxon", zaxxon, 4);
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+../gawk -f foo.awk
--- /dev/null
+/*
+ * filefuncs.c - Builtin functions that provide initial minimal iterface
+ * to the file system.
+ *
+ * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998
+ * Arnold Robbins and John Haque, update for 3.1.4, applied Mon Jun 14 13:55:30 IDT 2004
+ */
+
+/*
+ * Copyright (C) 2001, 2004, 2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+#include <sys/sysmacros.h>
+
+/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
+
+static NODE *
+do_chdir(tree)
+NODE *tree;
+{
+ NODE *newdir;
+ int ret = -1;
+
+ if (do_lint && get_curfunc_arg_count() != 1)
+ lintwarn("chdir: called with incorrect number of arguments");
+
+ newdir = get_scalar_argument(tree, 0, FALSE);
+ (void) force_string(newdir);
+ ret = chdir(newdir->stptr);
+ if (ret < 0)
+ update_ERRNO();
+ free_temp(newdir);
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* format_mode --- turn a stat mode field into something readable */
+
+static char *
+format_mode(fmode)
+unsigned long fmode;
+{
+ static char outbuf[12];
+ int i;
+
+ strcpy(outbuf, "----------");
+ /* first, get the file type */
+ i = 0;
+ switch (fmode & S_IFMT) {
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+ outbuf[i] = 's';
+ break;
+#endif
+#ifdef S_IFLNK
+ case S_IFLNK:
+ outbuf[i] = 'l';
+ break;
+#endif
+ case S_IFREG:
+ outbuf[i] = '-'; /* redundant */
+ break;
+ case S_IFBLK:
+ outbuf[i] = 'b';
+ break;
+ case S_IFDIR:
+ outbuf[i] = 'd';
+ break;
+#ifdef S_IFDOOR /* Solaris weirdness */
+ case S_IFDOOR:
+ outbuf[i] = 'D';
+ break;
+#endif /* S_IFDOOR */
+ case S_IFCHR:
+ outbuf[i] = 'c';
+ break;
+#ifdef S_IFIFO
+ case S_IFIFO:
+ outbuf[i] = 'p';
+ break;
+#endif
+ }
+
+ i++;
+ if ((fmode & S_IRUSR) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWUSR) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXUSR) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ if ((fmode & S_IRGRP) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWGRP) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXGRP) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ if ((fmode & S_IROTH) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWOTH) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXOTH) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ outbuf[i] = '\0';
+
+ if ((fmode & S_ISUID) != 0) {
+ if (outbuf[3] == 'x')
+ outbuf[3] = 's';
+ else
+ outbuf[3] = 'S';
+ }
+
+ /* setgid without execute == locking */
+ if ((fmode & S_ISGID) != 0) {
+ if (outbuf[6] == 'x')
+ outbuf[6] = 's';
+ else
+ outbuf[6] = 'l';
+ }
+
+ if ((fmode & S_ISVTX) != 0) {
+ if (outbuf[9] == 'x')
+ outbuf[9] = 't';
+ else
+ outbuf[9] = 'T';
+ }
+
+ return outbuf;
+}
+
+/* do_stat --- provide a stat() function for gawk */
+
+static NODE *
+do_stat(tree)
+NODE *tree;
+{
+ NODE *file, *array;
+ struct stat sbuf;
+ int ret;
+ NODE **aptr;
+ char *pmode; /* printable mode */
+ char *type = "unknown";
+
+ if (do_lint && get_curfunc_arg_count() > 2)
+ lintwarn("stat: called with too many arguments");
+
+ /* directory is first arg, array to hold results is second */
+ file = get_scalar_argument(tree, 0, FALSE);
+ array = get_array_argument(tree, 1, FALSE);
+
+ /* empty out the array */
+ assoc_clear(array);
+
+ /* lstat the file, if error, set ERRNO and return */
+ (void) force_string(file);
+ ret = lstat(file->stptr, & sbuf);
+ if (ret < 0) {
+ update_ERRNO();
+
+ set_value(tmp_number((AWKNUM) ret));
+
+ free_temp(file);
+ return tmp_number((AWKNUM) 0);
+ }
+
+ /* fill in the array */
+ aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
+ *aptr = dupnode(file);
+
+ aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_dev);
+
+ aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_ino);
+
+ aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mode);
+
+ aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_nlink);
+
+ aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_uid);
+
+ aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_gid);
+
+ aptr = assoc_lookup(array, tmp_string("size", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_size);
+
+ aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_blocks);
+
+ aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_atime);
+
+ aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mtime);
+
+ aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_ctime);
+
+ /* for block and character devices, add rdev, major and minor numbers */
+ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) {
+ aptr = assoc_lookup(array, tmp_string("rdev", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_rdev);
+
+ aptr = assoc_lookup(array, tmp_string("major", 5), FALSE);
+ *aptr = make_number((AWKNUM) major(sbuf.st_rdev));
+
+ aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE);
+ *aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
+ }
+
+#ifdef HAVE_ST_BLKSIZE
+ aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_blksize);
+#endif /* HAVE_ST_BLKSIZE */
+
+ aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
+ pmode = format_mode(sbuf.st_mode);
+ *aptr = make_string(pmode, strlen(pmode));
+
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf.st_mode)) {
+ char buf[BUFSIZ*2];
+ int linksize;
+
+ linksize = readlink(file->stptr, buf, sizeof(buf) - 1);
+ if (linksize >= 0) {
+ /* should make this smarter */
+ if (linksize >= sizeof(buf) - 1)
+ fatal("size of symbolic link too big");
+ buf[linksize] = '\0';
+
+ aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE);
+ *aptr = make_string(buf, linksize);
+ }
+ }
+
+ /* add a type field */
+ switch (sbuf.st_mode & S_IFMT) {
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+ type = "socket";
+ break;
+#endif
+#ifdef S_IFLNK
+ case S_IFLNK:
+ type = "symlink";
+ break;
+#endif
+ case S_IFREG:
+ type = "file";
+ break;
+ case S_IFBLK:
+ type = "blockdev";
+ break;
+ case S_IFDIR:
+ type = "directory";
+ break;
+#ifdef S_IFDOOR
+ case S_IFDOOR:
+ type = "door";
+ break;
+#endif
+ case S_IFCHR:
+ type = "chardev";
+ break;
+#ifdef S_IFIFO
+ case S_IFIFO:
+ type = "fifo";
+ break;
+#endif
+ }
+
+ aptr = assoc_lookup(array, tmp_string("type", 4), FALSE);
+ *aptr = make_string(type, strlen(type));
+
+ free_temp(file);
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("chdir", do_chdir, 1);
+ make_builtin("stat", do_stat, 2);
+
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+BEGIN {
+ extension("./dl.so","dlload")
+ zaxxon("hi there", "this is", "a test", "of argument passing")
+ zaxxon(1)
+ zaxxon(1,2)
+ z = zaxxon(1,2,3,4)
+ z = zaxxon(1,zaxxon(zaxxon("foo")),3,4)
+ print z
+}
--- /dev/null
+/*
+ * fork.c - Provide fork and waitpid functions for gawk.
+ *
+ * Revised 6/2004
+ */
+
+/*
+ * Copyright (C) 2001, 2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/* do_fork --- provide dynamically loaded fork() builtin for gawk */
+
+static NODE *
+do_fork(tree)
+NODE *tree;
+{
+ int ret = -1;
+ NODE **aptr;
+
+ if (do_lint && get_curfunc_arg_count() > 0)
+ lintwarn("fork: called with too many arguments");
+
+ ret = fork();
+
+ if (ret < 0)
+ update_ERRNO();
+ else if (ret == 0) {
+ /* update PROCINFO in the child */
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE);
+ (*aptr)->numbr = (AWKNUM) getpid();
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE);
+ (*aptr)->numbr = (AWKNUM) getppid();
+ }
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+
+/* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */
+
+static NODE *
+do_waitpid(tree)
+NODE *tree;
+{
+ NODE *pidnode;
+ int ret = -1;
+ double pidval;
+ pid_t pid;
+ int options = 0;
+
+ if (do_lint && get_curfunc_arg_count() > 1)
+ lintwarn("waitpid: called with too many arguments");
+
+ pidnode = get_argument(tree, 0);
+ if (pidnode != NULL) {
+ pidval = force_number(pidnode);
+ pid = (int) pidval;
+ options = WNOHANG|WUNTRACED;
+ ret = waitpid(pid, NULL, options);
+ if (ret < 0)
+ update_ERRNO();
+ } else if (do_lint)
+ lintwarn("wait: called with no arguments");
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("fork", do_fork, 0);
+ make_builtin("waitpid", do_waitpid, 1);
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+/*
+ * ordchr.c - Builtin functions that provide ord() and chr() functions.
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * 8/2001
+ * Revised 6/2004
+ */
+
+/*
+ * Copyright (C) 2001, 2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/* do_ord --- return numeric value of first char of string */
+
+static NODE *
+do_ord(tree)
+NODE *tree;
+{
+ NODE *str;
+ int ret = -1;
+
+ if (do_lint && get_curfunc_arg_count() > 1)
+ lintwarn("ord: called with too many arguments");
+
+ str = get_argument(tree, 0);
+ if (str != NULL) {
+ (void) force_string(str);
+ ret = str->stptr[0];
+ free_temp(str);
+ } else if (do_lint)
+ lintwarn("ord: called with no arguments");
+
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* do_chr --- turn numeric value into a string */
+
+static NODE *
+do_chr(tree)
+NODE *tree;
+{
+ NODE *num;
+ unsigned int ret = 0;
+ AWKNUM val = 0.0;
+ char str[2];
+
+ str[0] = str[1] = '\0';
+
+ if (do_lint && get_curfunc_arg_count() > 1)
+ lintwarn("chr: called with too many arguments");
+
+ num = get_argument(tree, 0);
+ if (num != NULL) {
+ val = force_number(num);
+ ret = val; /* convert to int */
+ free_temp(num);
+ ret &= 0xff;
+ str[0] = ret;
+ str[1] = '\0';
+ } else if (do_lint)
+ lintwarn("chr: called with no arguments");
+
+
+ /* Set the return value */
+ set_value(tmp_string(str, 1));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("ord", do_ord, 1);
+ make_builtin("chr", do_chr, 1);
+
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+EXPORTS\r
+dlload @1\r
--- /dev/null
+/*
+ * readfile.c - Read an entire file into a string.
+ *
+ * Arnold Robbins
+ * Tue Apr 23 17:43:30 IDT 2002
+ * Revised per Peter Tillier
+ * Mon Jun 9 17:05:11 IDT 2003
+ * Revised for new dynamic function facilities
+ * Mon Jun 14 14:53:07 IDT 2004
+ */
+
+/*
+ * Copyright (C) 2002, 2003, 2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* do_readfile --- read a file into memory */
+
+NODE *
+do_readfile(tree)
+NODE *tree;
+{
+ NODE *filename;
+ int ret = -1;
+ struct stat sbuf;
+ char *text;
+ int fd;
+
+ if (do_lint && get_curfunc_arg_count() > 1)
+ lintwarn("readfile: called with too many arguments");
+
+ filename = get_argument(tree, 0);
+ if (filename != NULL) {
+ (void) force_string(filename);
+
+ ret = stat(filename->stptr, & sbuf);
+ if (ret < 0) {
+ update_ERRNO();
+ free_temp(filename);
+ goto done;
+ } else if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
+ errno = EINVAL;
+ ret = -1;
+ update_ERRNO();
+ free_temp(filename);
+ goto done;
+ }
+
+ if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) {
+ ret = -1;
+ update_ERRNO();
+ free_temp(filename);
+ goto done;
+ }
+
+ emalloc(text, char *, sbuf.st_size + 2, "do_readfile");
+ memset(text, '\0', sbuf.st_size + 2);
+
+ if ((ret = read(fd, text, sbuf.st_size)) != sbuf.st_size) {
+ (void) close(fd);
+ ret = -1;
+ update_ERRNO();
+ free_temp(filename);
+ goto done;
+ }
+
+ close(fd);
+ free_temp(filename);
+ set_value(tmp_string(text, sbuf.st_size));
+ return tmp_number((AWKNUM) 0);
+ } else if (do_lint)
+ lintwarn("filename: called with no arguments");
+
+
+done:
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("readfile", do_readfile, 1);
+
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+# what to do under linux to make dl.so
+# Tue Nov 24 15:04:14 EST 1998
+# Sun Aug 26 16:03:58 IDT 2001
+# Sun Apr 28 15:59:57 IDT 2002
+# Mon Jun 21 17:03:37 IDT 2004
+
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. dl.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. filefuncs.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fork.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. ordchr.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. arrayparm.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. readfile.c
+gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. testarg.c
+ld -o dl.so -shared dl.o
+ld -o filefuncs.so -shared filefuncs.o
+ld -o fork.so -shared fork.o
+ld -o ordchr.so -shared ordchr.o
+ld -o arrayparm.so -shared arrayparm.o
+ld -o readfile.so -shared readfile.o
+ld -o testarg.so -shared testarg.o
--- /dev/null
+BEGIN {
+ extension("./testarg.so", "dlload")
+ check_arg(x, a);
+ check_arg(y, b, z);
+ check_arg(p, q, r, s);
+}
--- /dev/null
+#include "awk.h"
+
+static NODE *
+do_check_arg(tree)
+NODE *tree;
+{
+ int ret = 0, argc;
+ NODE *arg1, *arg2, *arg3;
+
+ argc = get_curfunc_arg_count();
+ printf("arg count: defined = %d, supplied = %d\n", tree->param_cnt, argc);
+
+ arg1 = get_scalar_argument(tree, 0, FALSE);
+ arg2 = get_array_argument(tree, 1, FALSE);
+ arg3 = get_scalar_argument(tree, 2, TRUE); /* optional */
+ if (argc > 3) { /* try to use an extra arg */
+ NODE *arg4;
+ arg4 = get_array_argument(tree, 3, TRUE);
+ }
+ if (arg3 != NULL)
+ printf("3rd arg present\n\n");
+ else
+ printf("no 3rd arg\n\n");
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("check_arg", do_check_arg, 3);
+ return tmp_number((AWKNUM) 0);
+}
--- /dev/null
+#! /bin/awk -f
+
+BEGIN {
+ extension("./arrayparm.so", "dlload")
+
+ mkarray(newvar, "hi", "hello")
+
+ for (i in newvar)
+ printf ("newvar[\"%s\"] = \"%s\"\n", i, newvar[i])
+}
--- /dev/null
+BEGIN {
+ extension("./filefuncs.so", "dlload")
+
+# printf "before: "
+# fflush()
+# system("pwd")
+#
+# chdir("..")
+#
+# printf "after: "
+# fflush()
+# system("pwd")
+
+ chdir(".")
+
+ data[1] = 1
+ print "Info for 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 for 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"])
+}
--- /dev/null
+BEGIN {
+ extension("./fork.so", "dlload")
+
+ printf "before fork, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+
+ fflush()
+ ret = fork()
+ if (ret < 0)
+ printf("ret = %d, ERRNO = %s\n", ret, ERRNO)
+ else if (ret == 0)
+ printf "child, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+ else {
+ system("sleep 3")
+ printf "parent, ret = %d\n", ret
+ printf "parent, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+ }
+}
--- /dev/null
+BEGIN {
+ extension("./ordchr.so", "dlload")
+
+ print "ord(\"a\") is", ord("a")
+ print "chr(65) is", chr(65)
+}
--- /dev/null
+/* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage
+
+ Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Jim Meyering <jim@meyering.net> */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "xreadlink.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
+
+#include "xalloc.h"
+
+/* Call readlink to get the symbolic link value of FILE.
+ SIZE is a hint as to how long the link is expected to be;
+ typically it is taken from st_size. It need not be correct.
+ Return a pointer to that NUL-terminated string in malloc'd storage.
+ If readlink fails, return NULL (caller may use errno to diagnose).
+ If malloc fails, or if the link value is longer than SSIZE_MAX :-),
+ give a diagnostic and exit. */
+
+char *
+xreadlink (char const *file, size_t size)
+{
+ /* The initial buffer size for the link value. A power of 2
+ detects arithmetic overflow earlier, but is not required. */
+ size_t buf_size = size < MAXSIZE ? size + 1 : MAXSIZE;
+
+ while (1)
+ {
+ char *buffer = xmalloc (buf_size);
+ ssize_t r = readlink (file, buffer, buf_size);
+ size_t link_length = r;
+
+ /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
+ with errno == ERANGE if the buffer is too small. */
+ if (r < 0 && errno != ERANGE)
+ {
+ int saved_errno = errno;
+ free (buffer);
+ errno = saved_errno;
+ return NULL;
+ }
+
+ if (link_length < buf_size)
+ {
+ buffer[link_length] = 0;
+ return buffer;
+ }
+
+ free (buffer);
+ if (buf_size <= MAXSIZE / 2)
+ buf_size *= 2;
+ else if (buf_size < MAXSIZE)
+ buf_size = MAXSIZE;
+ else
+ xalloc_die ();
+ }
+}
--- /dev/null
+/* readlink wrapper to return the link name in malloc'd storage
+
+ Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Jim Meyering <jim@meyering.net> */
+
+#include <stddef.h>
+char *xreadlink (char const *, size_t);
--- /dev/null
+/*
+ * field.c - routines for dealing with fields and record parsing
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/*
+ * In case that the system doesn't have isblank().
+ * Don't bother with autoconf ifdef junk, just force it.
+ * See dfa.c and regex_internal.h and regcomp.c. Bleah.
+ */
+static int
+is_blank(int c)
+{
+ return c == ' ' || c == '\t';
+}
+
+typedef void (* Setfunc) P((long, char *, long, NODE *));
+
+static long (*parse_field) P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static void rebuild_record P((void));
+static long re_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static long def_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static long posix_def_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static long null_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static long sc_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static long fw_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+static void set_element P((long num, char * str, long len, NODE *arr));
+static void grow_fields_arr P((long num));
+static void set_field P((long num, char *str, long len, NODE *dummy));
+static void update_PROCINFO P((char *subscript, char *str));
+
+
+static char *parse_extent; /* marks where to restart parse of record */
+static long parse_high_water = 0; /* field number that we have parsed so far */
+static long nf_high_water = 0; /* size of fields_arr */
+static int resave_fs;
+static NODE *save_FS; /* save current value of FS when line is read,
+ * to be used in deferred parsing
+ */
+static int *FIELDWIDTHS = NULL;
+
+NODE **fields_arr; /* array of pointers to the field nodes */
+int field0_valid; /* $(>0) has not been changed yet */
+int default_FS; /* TRUE when FS == " " */
+Regexp *FS_re_yes_case = NULL;
+Regexp *FS_re_no_case = NULL;
+Regexp *FS_regexp = NULL;
+NODE *Null_field = NULL;
+
+/* using_FIELDWIDTHS --- static function, macro to avoid overhead */
+#define using_FIELDWIDTHS() (parse_field == fw_parse_field)
+
+/* init_fields --- set up the fields array to start with */
+
+void
+init_fields()
+{
+ emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");
+ fields_arr[0] = Nnull_string;
+ parse_extent = fields_arr[0]->stptr;
+ save_FS = dupnode(FS_node->var_value);
+ getnode(Null_field);
+ *Null_field = *Nnull_string;
+ Null_field->flags |= FIELD;
+ Null_field->flags &= ~(NUMCUR|NUMBER|MAYBE_NUM|PERM);
+ field0_valid = TRUE;
+}
+
+/* grow_fields --- acquire new fields as needed */
+
+static void
+grow_fields_arr(long num)
+{
+ register int t;
+ register NODE *n;
+
+ erealloc(fields_arr, NODE **, (num + 1) * sizeof(NODE *), "grow_fields_arr");
+ for (t = nf_high_water + 1; t <= num; t++) {
+ getnode(n);
+ *n = *Null_field;
+ fields_arr[t] = n;
+ }
+ nf_high_water = num;
+}
+
+/* set_field --- set the value of a particular field */
+
+/*ARGSUSED*/
+static void
+set_field(long num,
+ char *str,
+ long len,
+ NODE *dummy ATTRIBUTE_UNUSED) /* just to make interface same as set_element */
+{
+ register NODE *n;
+
+ if (num > nf_high_water)
+ grow_fields_arr(num);
+ n = fields_arr[num];
+ n->stptr = str;
+ n->stlen = len;
+ n->flags = (STRCUR|STRING|MAYBE_NUM|FIELD);
+}
+
+/* rebuild_record --- Someone assigned a value to $(something).
+ Fix up $0 to be right */
+
+static void
+rebuild_record()
+{
+ /*
+ * use explicit unsigned longs for lengths, in case
+ * a size_t isn't big enough.
+ */
+ register unsigned long tlen;
+ register unsigned long ofslen;
+ register NODE *tmp;
+ NODE *ofs;
+ char *ops;
+ register char *cops;
+ long i;
+
+ assert(NF != -1);
+
+ tlen = 0;
+ ofs = force_string(OFS_node->var_value);
+ ofslen = ofs->stlen;
+ for (i = NF; i > 0; i--) {
+ tmp = fields_arr[i];
+ tmp = force_string(tmp);
+ tlen += tmp->stlen;
+ }
+ tlen += (NF - 1) * ofslen;
+ if ((long) tlen < 0)
+ tlen = 0;
+ emalloc(ops, char *, tlen + 2, "rebuild_record");
+ cops = ops;
+ ops[0] = '\0';
+ for (i = 1; i <= NF; i++) {
+ tmp = fields_arr[i];
+ /* copy field */
+ if (tmp->stlen == 1)
+ *cops++ = tmp->stptr[0];
+ else if (tmp->stlen != 0) {
+ memcpy(cops, tmp->stptr, tmp->stlen);
+ cops += tmp->stlen;
+ }
+ /* copy OFS */
+ if (i != NF) {
+ if (ofslen == 1)
+ *cops++ = ofs->stptr[0];
+ else if (ofslen != 0) {
+ memcpy(cops, ofs->stptr, ofslen);
+ cops += ofslen;
+ }
+ }
+ }
+ tmp = make_str_node(ops, tlen, ALREADY_MALLOCED);
+
+ /*
+ * Since we are about to unref fields_arr[0], we want to find
+ * any fields that still point into it, and have them point
+ * into the new field zero. This has to be done intelligently,
+ * so that unrefing a field doesn't try to unref into the old $0.
+ */
+ for (cops = ops, i = 1; i <= NF; i++) {
+ if (fields_arr[i]->stlen > 0) {
+ NODE *n;
+ getnode(n);
+
+ if ((fields_arr[i]->flags & FIELD) == 0) {
+ *n = *Null_field;
+ n->stlen = fields_arr[i]->stlen;
+ if ((fields_arr[i]->flags & (NUMCUR|NUMBER)) != 0) {
+ n->flags |= (fields_arr[i]->flags & (NUMCUR|NUMBER));
+ n->numbr = fields_arr[i]->numbr;
+ }
+ } else {
+ *n = *(fields_arr[i]);
+ n->flags &= ~(MALLOC|TEMP|PERM|STRING);
+ }
+
+ n->stptr = cops;
+ unref(fields_arr[i]);
+ fields_arr[i] = n;
+ }
+ cops += fields_arr[i]->stlen + ofslen;
+ }
+
+ unref(fields_arr[0]);
+
+ fields_arr[0] = tmp;
+ field0_valid = TRUE;
+}
+
+/*
+ * set_record:
+ * setup $0, but defer parsing rest of line until reference is made to $(>0)
+ * or to NF. At that point, parse only as much as necessary.
+ *
+ * Manage a private buffer for the contents of $0. Doing so keeps us safe
+ * if `getline var' decides to rearrange the contents of the IOBUF that
+ * $0 might have been pointing into. The cost is the copying of the buffer;
+ * but better correct than fast.
+ */
+void
+set_record(const char *buf, int cnt)
+{
+ NODE *n;
+ static char *databuf;
+ static unsigned long databuf_size;
+#define INITIAL_SIZE 512
+#define MAX_SIZE ((unsigned long) ~0) /* maximally portable ... */
+
+ reset_record();
+
+ /* buffer management: */
+ if (databuf_size == 0) { /* first time */
+ emalloc(databuf, char *, INITIAL_SIZE, "set_record");
+ databuf_size = INITIAL_SIZE;
+ memset(databuf, '\0', INITIAL_SIZE);
+
+ }
+ /*
+ * Make sure there's enough room. Since we sometimes need
+ * to place a sentinel at the end, we make sure
+ * databuf_size is > cnt after allocation.
+ */
+ if (cnt >= databuf_size) {
+ while (cnt >= databuf_size && databuf_size <= MAX_SIZE)
+ databuf_size *= 2;
+ erealloc(databuf, char *, databuf_size, "set_record");
+ memset(databuf, '\0', databuf_size);
+ }
+ /* copy the data */
+ memcpy(databuf, buf, cnt);
+
+ /* manage field 0: */
+ unref(fields_arr[0]);
+ getnode(n);
+ n->stptr = databuf;
+ n->stlen = cnt;
+ n->stref = 1;
+ n->type = Node_val;
+ n->stfmt = -1;
+ n->flags = (STRING|STRCUR|MAYBE_NUM|FIELD);
+ fields_arr[0] = n;
+
+#undef INITIAL_SIZE
+#undef MAX_SIZE
+}
+
+/* reset_record --- start over again with current $0 */
+
+void
+reset_record()
+{
+ register int i;
+ NODE *n;
+
+ (void) force_string(fields_arr[0]);
+
+ NF = -1;
+ for (i = 1; i <= parse_high_water; i++) {
+ unref(fields_arr[i]);
+ getnode(n);
+ *n = *Null_field;
+ fields_arr[i] = n;
+ }
+
+ parse_high_water = 0;
+ /*
+ * $0 = $0 should resplit using the current value of FS.
+ */
+ if (resave_fs) {
+ resave_fs = FALSE;
+ unref(save_FS);
+ save_FS = dupnode(FS_node->var_value);
+ }
+
+ field0_valid = TRUE;
+}
+
+/* set_NF --- handle what happens to $0 and fields when NF is changed */
+
+void
+set_NF()
+{
+ register int i;
+ NODE *n;
+
+ assert(NF != -1);
+
+ NF = (long) force_number(NF_node->var_value);
+
+ if (NF < 0)
+ fatal(_("NF set to negative value"));
+
+ if (NF > nf_high_water)
+ grow_fields_arr(NF);
+ if (parse_high_water < NF) {
+ for (i = parse_high_water + 1; i >= 0 && i <= NF; i++) {
+ unref(fields_arr[i]);
+ getnode(n);
+ *n = *Null_field;
+ fields_arr[i] = n;
+ }
+ } else if (parse_high_water > 0) {
+ for (i = NF + 1; i >= 0 && i <= parse_high_water; i++) {
+ unref(fields_arr[i]);
+ getnode(n);
+ *n = *Null_field;
+ fields_arr[i] = n;
+ }
+ parse_high_water = NF;
+ }
+ field0_valid = FALSE;
+}
+
+/*
+ * re_parse_field --- parse fields using a regexp.
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is a regular
+ * expression -- either user-defined or because RS=="" and FS==" "
+ */
+static long
+re_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs ATTRIBUTE_UNUSED,
+ Regexp *rp,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *field;
+ register char *end = scan + len;
+#ifdef MBS_SUPPORT
+ size_t mbclen = 0;
+ mbstate_t mbs;
+ if (gawk_mb_cur_max > 1)
+ memset(&mbs, 0, sizeof(mbstate_t));
+#endif
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+ if (RS_is_null && default_FS)
+ while (scan < end && (*scan == ' ' || *scan == '\t' || *scan == '\n'))
+ scan++;
+ field = scan;
+ while (scan < end
+ && research(rp, scan, 0, (end - scan), RE_NEED_START) != -1
+ && nf < up_to) {
+ if (REEND(rp, scan) == RESTART(rp, scan)) { /* null match */
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ mbclen = mbrlen(scan, end-scan, &mbs);
+ if ((mbclen == 1) || (mbclen == (size_t) -1)
+ || (mbclen == (size_t) -2) || (mbclen == 0)) {
+ /* We treat it as a singlebyte character. */
+ mbclen = 1;
+ }
+ scan += mbclen;
+ } else
+#endif
+ scan++;
+ if (scan == end) {
+ (*set)(++nf, field, (long)(scan - field), n);
+ up_to = nf;
+ break;
+ }
+ continue;
+ }
+ (*set)(++nf, field,
+ (long)(scan + RESTART(rp, scan) - field), n);
+ scan += REEND(rp, scan);
+ field = scan;
+ if (scan == end) /* FS at end of record */
+ (*set)(++nf, field, 0L, n);
+ }
+ if (nf != up_to && scan < end) {
+ (*set)(++nf, scan, (long)(end - scan), n);
+ scan = end;
+ }
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * def_parse_field --- default field parsing.
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is a single space
+ * character.
+ */
+
+static long
+def_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs,
+ Regexp *rp ATTRIBUTE_UNUSED,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *field;
+ register char *end = scan + len;
+ char sav;
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+ /*
+ * Nasty special case. If FS set to "", return whole record
+ * as first field. This is not worth a separate function.
+ */
+ if (fs->stlen == 0) {
+ (*set)(++nf, *buf, len, n);
+ *buf += len;
+ return nf;
+ }
+
+ /* before doing anything save the char at *end */
+ sav = *end;
+ /* because it will be destroyed now: */
+
+ *end = ' '; /* sentinel character */
+ for (; nf < up_to; scan++) {
+ /*
+ * special case: fs is single space, strip leading whitespace
+ */
+ while (scan < end && (*scan == ' ' || *scan == '\t' || *scan == '\n'))
+ scan++;
+ if (scan >= end)
+ break;
+ field = scan;
+ while (*scan != ' ' && *scan != '\t' && *scan != '\n')
+ scan++;
+ (*set)(++nf, field, (long)(scan - field), n);
+ if (scan == end)
+ break;
+ }
+
+ /* everything done, restore original char at *end */
+ *end = sav;
+
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * posix_def_parse_field --- default field parsing.
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is a single space
+ * character. The only difference between this and def_parse_field()
+ * is that this one does not allow newlines to separate fields.
+ */
+
+static long
+posix_def_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs,
+ Regexp *rp ATTRIBUTE_UNUSED,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *field;
+ register char *end = scan + len;
+ char sav;
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+ /*
+ * Nasty special case. If FS set to "", return whole record
+ * as first field. This is not worth a separate function.
+ */
+ if (fs->stlen == 0) {
+ (*set)(++nf, *buf, len, n);
+ *buf += len;
+ return nf;
+ }
+
+ /* before doing anything save the char at *end */
+ sav = *end;
+ /* because it will be destroyed now: */
+
+ *end = ' '; /* sentinel character */
+ for (; nf < up_to; scan++) {
+ /*
+ * special case: fs is single space, strip leading whitespace
+ */
+ while (scan < end && (*scan == ' ' || *scan == '\t'))
+ scan++;
+ if (scan >= end)
+ break;
+ field = scan;
+ while (*scan != ' ' && *scan != '\t')
+ scan++;
+ (*set)(++nf, field, (long)(scan - field), n);
+ if (scan == end)
+ break;
+ }
+
+ /* everything done, restore original char at *end */
+ *end = sav;
+
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * null_parse_field --- each character is a separate field
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is the null string.
+ */
+static long
+null_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs ATTRIBUTE_UNUSED,
+ Regexp *rp ATTRIBUTE_UNUSED,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *end = scan + len;
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ mbstate_t mbs;
+ memset(&mbs, 0, sizeof(mbstate_t));
+ for (; nf < up_to && scan < end;) {
+ size_t mbclen = mbrlen(scan, end-scan, &mbs);
+ if ((mbclen == 1) || (mbclen == (size_t) -1)
+ || (mbclen == (size_t) -2) || (mbclen == 0)) {
+ /* We treat it as a singlebyte character. */
+ mbclen = 1;
+ }
+ (*set)(++nf, scan, mbclen, n);
+ scan += mbclen;
+ }
+ } else
+#endif
+ for (; nf < up_to && scan < end; scan++)
+ (*set)(++nf, scan, 1L, n);
+
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * sc_parse_field --- single character field separator
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is a single character
+ * other than space.
+ */
+static long
+sc_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs,
+ Regexp *rp ATTRIBUTE_UNUSED,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register char fschar;
+ register long nf = parse_high_water;
+ register char *field;
+ register char *end = scan + len;
+ char sav;
+#ifdef MBS_SUPPORT
+ size_t mbclen = 0;
+ mbstate_t mbs;
+ if (gawk_mb_cur_max > 1)
+ memset(&mbs, 0, sizeof(mbstate_t));
+#endif
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+ if (RS_is_null && fs->stlen == 0)
+ fschar = '\n';
+ else
+ fschar = fs->stptr[0];
+
+ /* before doing anything save the char at *end */
+ sav = *end;
+ /* because it will be destroyed now: */
+ *end = fschar; /* sentinel character */
+
+ for (; nf < up_to;) {
+ field = scan;
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1) {
+ while (*scan != fschar) {
+ mbclen = mbrlen(scan, end-scan, &mbs);
+ if ((mbclen == 1) || (mbclen == (size_t) -1)
+ || (mbclen == (size_t) -2) || (mbclen == 0)) {
+ /* We treat it as a singlebyte character. */
+ mbclen = 1;
+ }
+ scan += mbclen;
+ }
+ } else
+#endif
+ while (*scan != fschar)
+ scan++;
+ (*set)(++nf, field, (long)(scan - field), n);
+ if (scan == end)
+ break;
+ scan++;
+ if (scan == end) { /* FS at end of record */
+ (*set)(++nf, field, 0L, n);
+ break;
+ }
+ }
+
+ /* everything done, restore original char at *end */
+ *end = sav;
+
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * fw_parse_field --- field parsing using FIELDWIDTHS spec
+ *
+ * This is called from get_field() via (*parse_field)().
+ * This variation is for fields are fixed widths.
+ */
+static long
+fw_parse_field(long up_to, /* parse only up to this field number */
+ char **buf, /* on input: string to parse; on output: point to start next */
+ int len,
+ NODE *fs ATTRIBUTE_UNUSED,
+ Regexp *rp ATTRIBUTE_UNUSED,
+ Setfunc set, /* routine to set the value of the parsed field */
+ NODE *n)
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *end = scan + len;
+
+ if (up_to == UNLIMITED)
+ nf = 0;
+ if (len == 0)
+ return nf;
+ for (; nf < up_to && (len = FIELDWIDTHS[nf+1]) != -1; ) {
+ if (len > end - scan)
+ len = end - scan;
+ (*set)(++nf, scan, (long) len, n);
+ scan += len;
+ }
+ if (len == -1)
+ *buf = end;
+ else
+ *buf = scan;
+ return nf;
+}
+
+/* get_field --- return a particular $n */
+
+/* assign is not NULL if this field is on the LHS of an assign */
+
+NODE **
+get_field(register long requested, Func_ptr *assign)
+{
+ /*
+ * if requesting whole line but some other field has been altered,
+ * then the whole line must be rebuilt
+ */
+ if (requested == 0) {
+ if (! field0_valid) {
+ /* first, parse remainder of input record */
+ if (NF == -1) {
+ NF = (*parse_field)(UNLIMITED-1, &parse_extent,
+ fields_arr[0]->stlen -
+ (parse_extent - fields_arr[0]->stptr),
+ save_FS, FS_regexp, set_field,
+ (NODE *) NULL);
+ parse_high_water = NF;
+ }
+ rebuild_record();
+ }
+ if (assign != NULL)
+ *assign = reset_record;
+ return &fields_arr[0];
+ }
+
+ /* assert(requested > 0); */
+
+ if (assign != NULL)
+ field0_valid = FALSE; /* $0 needs reconstruction */
+
+ if (requested <= parse_high_water) /* already parsed this field */
+ return &fields_arr[requested];
+
+ if (NF == -1) { /* have not yet parsed to end of record */
+ /*
+ * parse up to requested fields, calling set_field() for each,
+ * saving in parse_extent the point where the parse left off
+ */
+ if (parse_high_water == 0) /* starting at the beginning */
+ parse_extent = fields_arr[0]->stptr;
+ parse_high_water = (*parse_field)(requested, &parse_extent,
+ fields_arr[0]->stlen - (parse_extent - fields_arr[0]->stptr),
+ save_FS, FS_regexp, set_field, (NODE *) NULL);
+
+ /*
+ * if we reached the end of the record, set NF to the number of
+ * fields so far. Note that requested might actually refer to
+ * a field that is beyond the end of the record, but we won't
+ * set NF to that value at this point, since this is only a
+ * reference to the field and NF only gets set if the field
+ * is assigned to -- this case is handled below
+ */
+ if (parse_extent == fields_arr[0]->stptr + fields_arr[0]->stlen)
+ NF = parse_high_water;
+ if (requested == UNLIMITED-1) /* UNLIMITED-1 means set NF */
+ requested = parse_high_water;
+ }
+ if (parse_high_water < requested) { /* requested beyond end of record */
+ if (assign != NULL) { /* expand record */
+ if (requested > nf_high_water)
+ grow_fields_arr(requested);
+
+ NF = requested;
+ parse_high_water = requested;
+ } else
+ return &Null_field;
+ }
+
+ return &fields_arr[requested];
+}
+
+/* set_element --- set an array element, used by do_split() */
+
+static void
+set_element(long num, char *s, long len, NODE *n)
+{
+ register NODE *it;
+
+ it = make_string(s, len);
+ it->flags |= MAYBE_NUM;
+ *assoc_lookup(n, tmp_number((AWKNUM) (num)), FALSE) = it;
+}
+
+/* do_split --- implement split(), semantics are same as for field splitting */
+
+NODE *
+do_split(NODE *tree)
+{
+ NODE *src, *arr, *sep, *fs, *src2, *fs2, *tmp;
+ char *s;
+ long (*parseit) P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
+ Regexp *rp = NULL;
+
+ src = force_string(tree_eval(tree->lnode));
+
+ arr = get_param(tree->rnode->lnode);
+ if (arr->type != Node_var_array)
+ fatal(_("split: second argument is not an array"));
+
+ sep = tree->rnode->rnode->lnode;
+
+ if (src->stlen == 0) {
+ /*
+ * Skip the work if first arg is the null string.
+ */
+ free_temp(src);
+ /*
+ * Evaluate sep if it may have side effects.
+ */
+ if ((sep->re_flags & (FS_DFLT|CONST)) == 0)
+ free_temp(tree_eval(sep->re_exp));
+ /*
+ * And now we can safely turn off the array.
+ */
+ assoc_clear(arr);
+ return tmp_number((AWKNUM) 0);
+ }
+
+ if ((sep->re_flags & FS_DFLT) != 0 && ! using_FIELDWIDTHS() && ! RS_is_null) {
+ parseit = parse_field;
+ fs = force_string(FS_node->var_value);
+ rp = FS_regexp;
+ } else {
+ fs = force_string(tree_eval(sep->re_exp));
+ if (fs->stlen == 0) {
+ static short warned = FALSE;
+
+ parseit = null_parse_field;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("split: null string for third arg is a gawk extension"));
+ }
+ } else if (fs->stlen == 1 && (sep->re_flags & CONST) == 0) {
+ if (fs->stptr[0] == ' ') {
+ if (do_posix)
+ parseit = posix_def_parse_field;
+ else
+ parseit = def_parse_field;
+ } else
+ parseit = sc_parse_field;
+ } else {
+ parseit = re_parse_field;
+ rp = re_update(sep);
+ }
+ }
+
+ /*
+ * do dupnode(), to avoid problems like
+ * x = split(a["LINE"], a, a["FS"])
+ * since we assoc_clear the array. gack.
+ * this also gives us complete call by value semantics.
+ */
+ src2 = dupnode(src);
+ free_temp(src);
+
+ fs2 = dupnode(fs);
+ free_temp(fs);
+
+ assoc_clear(arr);
+
+ s = src2->stptr;
+ tmp = tmp_number((AWKNUM) (*parseit)(UNLIMITED, &s, (int) src2->stlen,
+ fs2, rp, set_element, arr));
+ unref(src2);
+ unref(fs2);
+ return tmp;
+}
+
+/* set_FIELDWIDTHS --- handle an assignment to FIELDWIDTHS */
+
+void
+set_FIELDWIDTHS()
+{
+ register char *scan;
+ char *end;
+ register int i;
+ static int fw_alloc = 4;
+ static int warned = FALSE;
+ extern unsigned long strtoul P((const char *, char **endptr, int base));
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("`FIELDWIDTHS' is a gawk extension"));
+ }
+ if (do_traditional) /* quick and dirty, does the trick */
+ return;
+
+ /*
+ * If changing the way fields are split, obey least-suprise
+ * semantics, and force $0 to be split totally.
+ */
+ if (fields_arr != NULL)
+ (void) get_field(UNLIMITED - 1, 0);
+
+ parse_field = fw_parse_field;
+ scan = force_string(FIELDWIDTHS_node->var_value)->stptr;
+ end = scan + 1;
+ if (FIELDWIDTHS == NULL)
+ emalloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS");
+ FIELDWIDTHS[0] = 0;
+ for (i = 1; ; i++) {
+ unsigned long int tmp;
+ if (i >= fw_alloc) {
+ fw_alloc *= 2;
+ erealloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS");
+ }
+ /* Ensure that there is no leading `-' sign. Otherwise,
+ strtoul would accept it and return a bogus result. */
+ while (is_blank(*scan)) {
+ ++scan;
+ }
+ if (*scan == '-')
+ fatal(_("invalid FIELDWIDTHS value, near `%s'"),
+ scan);
+
+ /* Detect an invalid base-10 integer, a valid value that
+ is followed by something other than a blank or '\0',
+ or a value that is not in the range [1..INT_MAX]. */
+ errno = 0;
+ tmp = strtoul(scan, &end, 10);
+ if (errno != 0
+ || !(*end == '\0' || is_blank(*end))
+ || !(0 < tmp && tmp <= INT_MAX))
+ fatal(_("invalid FIELDWIDTHS value, near `%s'"),
+ scan);
+ FIELDWIDTHS[i] = tmp;
+ scan = end;
+ /* Skip past any trailing blanks. */
+ while (is_blank(*scan)) {
+ ++scan;
+ }
+ if (*scan == '\0')
+ break;
+ }
+ FIELDWIDTHS[i] = -1;
+
+ update_PROCINFO("FS", "FIELDWIDTHS");
+}
+
+/* set_FS --- handle things when FS is assigned to */
+
+void
+set_FS()
+{
+ char buf[10];
+ NODE *fs;
+ static NODE *save_fs = NULL;
+ static NODE *save_rs = NULL;
+ int remake_re = TRUE;
+
+ /*
+ * If changing the way fields are split, obey least-suprise
+ * semantics, and force $0 to be split totally.
+ */
+ if (fields_arr != NULL)
+ (void) get_field(UNLIMITED - 1, 0);
+
+ /* It's possible that only IGNORECASE changed, or FS = FS */
+ /*
+ * This comparison can't use cmp_nodes(), which pays attention
+ * to IGNORECASE, and that's not what we want.
+ */
+ if (save_fs
+ && FS_node->var_value->stlen == save_fs->stlen
+ && memcmp(FS_node->var_value->stptr, save_fs->stptr, save_fs->stlen) == 0
+ && save_rs
+ && RS_node->var_value->stlen == save_rs->stlen
+ && memcmp(RS_node->var_value->stptr, save_rs->stptr, save_rs->stlen) == 0) {
+ if (FS_regexp != NULL)
+ FS_regexp = (IGNORECASE ? FS_re_no_case : FS_re_yes_case);
+
+ /* FS = FS */
+ if (! using_FIELDWIDTHS()) {
+ return;
+ } else {
+ remake_re = FALSE;
+ goto choose_fs_function;
+ }
+ }
+
+ unref(save_fs);
+ save_fs = dupnode(FS_node->var_value);
+ unref(save_rs);
+ save_rs = dupnode(RS_node->var_value);
+ resave_fs = TRUE;
+ if (FS_regexp != NULL) {
+ refree(FS_re_yes_case);
+ refree(FS_re_no_case);
+ FS_re_yes_case = FS_re_no_case = FS_regexp = NULL;
+ }
+
+
+choose_fs_function:
+ buf[0] = '\0';
+ default_FS = FALSE;
+ fs = force_string(FS_node->var_value);
+
+ if (! do_traditional && fs->stlen == 0) {
+ static short warned = FALSE;
+
+ parse_field = null_parse_field;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("null string for `FS' is a gawk extension"));
+ }
+ } else if (fs->stlen > 1) {
+ parse_field = re_parse_field;
+ } else if (RS_is_null) {
+ /* we know that fs->stlen <= 1 */
+ parse_field = sc_parse_field;
+ if (fs->stlen == 1) {
+ if (fs->stptr[0] == ' ') {
+ default_FS = TRUE;
+ strcpy(buf, "[ \t\n]+");
+ } else if (fs->stptr[0] == '\\') {
+ /* yet another special case */
+ strcpy(buf, "[\\\\\n]");
+ } else if (fs->stptr[0] != '\n')
+ sprintf(buf, "[%c\n]", fs->stptr[0]);
+ }
+ } else {
+ if (do_posix)
+ parse_field = posix_def_parse_field;
+ else
+ parse_field = def_parse_field;
+
+ if (fs->stlen == 1) {
+ if (fs->stptr[0] == ' ')
+ default_FS = TRUE;
+ else if (fs->stptr[0] == '\\')
+ /* same special case */
+ strcpy(buf, "[\\\\]");
+ else
+ parse_field = sc_parse_field;
+ }
+ }
+ if (remake_re) {
+ if (FS_regexp != NULL) {
+ refree(FS_re_yes_case);
+ refree(FS_re_no_case);
+ FS_re_yes_case = FS_re_no_case = FS_regexp = NULL;
+ }
+
+ if (buf[0] != '\0') {
+ FS_re_yes_case = make_regexp(buf, strlen(buf), FALSE, TRUE);
+ FS_re_no_case = make_regexp(buf, strlen(buf), TRUE, TRUE);
+ FS_regexp = (IGNORECASE ? FS_re_no_case : FS_re_yes_case);
+ parse_field = re_parse_field;
+ } else if (parse_field == re_parse_field) {
+ FS_re_yes_case = make_regexp(fs->stptr, fs->stlen, FALSE, TRUE);
+ FS_re_no_case = make_regexp(fs->stptr, fs->stlen, TRUE, TRUE);
+ FS_regexp = (IGNORECASE ? FS_re_no_case : FS_re_yes_case);
+ } else
+ FS_re_yes_case = FS_re_no_case = FS_regexp = NULL;
+ }
+
+ /*
+ * For FS = "c", we don't use IGNORECASE. But we must use
+ * re_parse_field to get the character and the newline as
+ * field separators.
+ */
+ if (fs->stlen == 1 && parse_field == re_parse_field)
+ FS_regexp = FS_re_yes_case;
+
+ update_PROCINFO("FS", "FS");
+}
+
+/* using_fieldwidths --- is FS or FIELDWIDTHS in use? */
+
+int
+using_fieldwidths()
+{
+ return using_FIELDWIDTHS();
+}
+
+/* update_PROCINFO --- update PROCINFO[sub] when FS or FIELDWIDTHS set */
+
+static void
+update_PROCINFO(char *subscript, char *str)
+{
+ NODE **aptr;
+
+ if (PROCINFO_node == NULL)
+ return;
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string(subscript, strlen(subscript)), FALSE);
+ assign_val(aptr, tmp_string(str, strlen(str)));
+}
--- /dev/null
+/*
+ * gawkmisc.c --- miscellanious gawk routines that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2004 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+#if defined(HAVE_FCNTL_H)
+#include <fcntl.h>
+#endif
+
+/* some old compilers don't grok #elif. sigh */
+
+#ifdef __EMX__
+#include "pc/gawkmisc.pc"
+#else /* not __EMX__ */
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
+#include "gawkmisc.pc"
+#else /* not MSDOS, not OS2, not WIN32 */
+#if defined(VMS)
+#include "vms/gawkmisc.vms"
+#else /* not VMS */
+#if defined(atarist)
+#include "unsupported/atari/gawkmisc.atr"
+#else /* not atarist */
+#if defined(TANDEM)
+#include "tmiscc"
+#else /* not TANDEM */
+#include "posix/gawkmisc.c"
+#endif /* not TANDEM */
+#endif /* not atarist */
+#endif /* not VMS */
+#endif /* not MSDOS, not OS2, not WIN32 */
+#endif /* not __EMX__ */
+
+/* xmalloc --- provide this so that other GNU library routines work */
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+extern pointer xmalloc P((size_t bytes)); /* get rid of gcc warning */
+
+pointer
+xmalloc(size_t bytes)
+{
+ pointer p;
+
+ emalloc(p, pointer, bytes, "xmalloc");
+
+ return p;
+}
--- /dev/null
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#include <string.h>
+
+#ifdef VMS
+# include <unixlib.h>
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "gettext.h"
+# define _(msgid) gettext (msgid)
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+#ifndef attribute_hidden
+# define attribute_hidden
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+#include "getopt_int.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Keep a global copy of all internal members of getopt_data. */
+
+static struct _getopt_data getopt_data;
+
+\f
+#ifndef __GNU_LIBRARY__
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (d->__nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+static void
+exchange (char **argv, struct _getopt_data *d)
+{
+ int bottom = d->__first_nonopt;
+ int middle = d->__last_nonopt;
+ int top = d->optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ d->__nonoption_flags_max_len),
+ '\0', top + 1 - d->__nonoption_flags_max_len);
+ d->__nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ d->__first_nonopt += (d->optind - d->__last_nonopt);
+ d->__last_nonopt = d->optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+static const char *
+_getopt_initialize (int argc, char *const *argv, const char *optstring,
+ struct _getopt_data *d)
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ d->__first_nonopt = d->__last_nonopt = d->optind;
+
+ d->__nextchar = NULL;
+
+ d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ d->__ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ d->__ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (d->__posixly_correct)
+ d->__ordering = REQUIRE_ORDER;
+ else
+ d->__ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (!d->__posixly_correct
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (d->__nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ d->__nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = d->__nonoption_flags_max_len = strlen (orig_str);
+ if (d->__nonoption_flags_max_len < argc)
+ d->__nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (d->__nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ d->__nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', d->__nonoption_flags_max_len - len);
+ }
+ }
+ d->__nonoption_flags_len = d->__nonoption_flags_max_len;
+ }
+ else
+ d->__nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal_r (int argc, char *const *argv, const char *optstring,
+ const struct option *longopts, int *longind,
+ int long_only, struct _getopt_data *d)
+{
+ int print_errors = d->opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ d->optarg = NULL;
+
+ if (d->optind == 0 || !d->__initialized)
+ {
+ if (d->optind == 0)
+ d->optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring, d);
+ d->__initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
+ || (d->optind < d->__nonoption_flags_len \
+ && __getopt_nonoption_flags[d->optind] == '1'))
+#else
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
+#endif
+
+ if (d->__nextchar == NULL || *d->__nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (d->__last_nonopt > d->optind)
+ d->__last_nonopt = d->optind;
+ if (d->__first_nonopt > d->optind)
+ d->__first_nonopt = d->optind;
+
+ if (d->__ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (d->__first_nonopt != d->__last_nonopt
+ && d->__last_nonopt != d->optind)
+ exchange ((char **) argv, d);
+ else if (d->__last_nonopt != d->optind)
+ d->__first_nonopt = d->optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (d->optind < argc && NONOPTION_P)
+ d->optind++;
+ d->__last_nonopt = d->optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (d->optind != argc && !strcmp (argv[d->optind], "--"))
+ {
+ d->optind++;
+
+ if (d->__first_nonopt != d->__last_nonopt
+ && d->__last_nonopt != d->optind)
+ exchange ((char **) argv, d);
+ else if (d->__first_nonopt == d->__last_nonopt)
+ d->__first_nonopt = d->optind;
+ d->__last_nonopt = argc;
+
+ d->optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (d->optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (d->__first_nonopt != d->__last_nonopt)
+ d->optind = d->__first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (d->__ordering == REQUIRE_ORDER)
+ return -1;
+ d->optarg = argv[d->optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ d->__nextchar = (argv[d->optind] + 1
+ + (longopts != NULL && argv[d->optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[d->optind][1] == '-'
+ || (long_only && (argv[d->optind][2]
+ || !strchr (optstring, argv[d->optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
+ {
+ if ((unsigned int) (nameend - d->__nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[d->optind]) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[d->optind]);
+#endif
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ d->optind++;
+ d->optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ d->optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ d->optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+ int n;
+#endif
+
+ if (argv[d->optind - 1][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[d->optind - 1][0],
+ pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[d->optind - 1][0],
+ pfound->name);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+
+ d->__nextchar += strlen (d->__nextchar);
+
+ d->optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (d->optind < argc)
+ d->optarg = argv[d->optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+ argv[0], argv[d->optind - 1]) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[d->optind - 1]);
+#endif
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ d->optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[d->optind][1] == '-'
+ || strchr (optstring, *d->__nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+ int n;
+#endif
+
+ if (argv[d->optind][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
+ argv[0], d->__nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], d->__nextchar);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[d->optind][0], d->__nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[d->optind][0], d->__nextchar);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+ d->__nextchar = (char *) "";
+ d->optind++;
+ d->optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *d->__nextchar++;
+ char *temp = strchr (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*d->__nextchar == '\0')
+ ++d->optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+ int n;
+#endif
+
+ if (d->__posixly_correct)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
+#endif
+ }
+ else
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+ d->optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*d->__nextchar != '\0')
+ {
+ d->optarg = d->__nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ d->optind++;
+ }
+ else if (d->optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ d->optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `d->optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ d->optarg = argv[d->optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
+ nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
+ {
+ if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[d->optind]) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[d->optind]);
+#endif
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ d->optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ d->optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+
+ d->__nextchar += strlen (d->__nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (d->optind < argc)
+ d->optarg = argv[d->optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+ argv[0], argv[d->optind - 1]) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[d->optind - 1]);
+#endif
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ d->__nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*d->__nextchar != '\0')
+ {
+ d->optarg = d->__nextchar;
+ d->optind++;
+ }
+ else
+ d->optarg = NULL;
+ d->__nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*d->__nextchar != '\0')
+ {
+ d->optarg = d->__nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ d->optind++;
+ }
+ else if (d->optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("\
+%s: option requires an argument -- %c\n"),
+ argv[0], c) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ d->optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ d->optarg = argv[d->optind++];
+ d->__nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+_getopt_internal (int argc, char *const *argv, const char *optstring,
+ const struct option *longopts, int *longind, int long_only)
+{
+ int result;
+
+ getopt_data.optind = optind;
+ getopt_data.opterr = opterr;
+
+ result = _getopt_internal_r (argc, argv, optstring, longopts,
+ longind, long_only, &getopt_data);
+
+ optind = getopt_data.optind;
+ optarg = getopt_data.optarg;
+ optopt = getopt_data.optopt;
+
+ return result;
+}
+
+int
+getopt (int argc, char *const *argv, const char *optstring)
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (int argc, char **argv)
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
--- /dev/null
+/* Declarations for getopt.
+ Copyright (C) 1989-1994,1996-1999,2001,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifndef __THROW
+# ifndef __GNUC_PREREQ
+# define __GNUC_PREREQ(maj, min) (0)
+# endif
+# if defined __cplusplus && __GNUC_PREREQ (2,8)
+# define __THROW throw ()
+# else
+# define __THROW
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+ const char *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
+ __THROW;
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+
+#ifndef __need_getopt
+extern int getopt_long (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind)
+ __THROW;
+extern int getopt_long_only (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind)
+ __THROW;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
--- /dev/null
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _LIBC
+# include <getopt.h>
+#else
+# include "getopt.h"
+#endif
+#include "getopt_int.h"
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+int
+_getopt_long_r (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index,
+ struct _getopt_data *d)
+{
+ return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+ 0, d);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+int
+_getopt_long_only_r (int argc, char *const *argv, const char *options,
+ const struct option *long_options, int *opt_index,
+ struct _getopt_data *d)
+{
+ return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+ 1, d);
+}
+
+#endif /* Not ELIDE_CODE. */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
--- /dev/null
+/* Internal declarations for getopt.
+ Copyright (C) 1989-1994,1996-1999,2001,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifndef _GETOPT_INT_H
+#define _GETOPT_INT_H 1
+
+extern int _getopt_internal (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+
+\f
+/* Reentrant versions which can handle parsing multiple argument
+ vectors at the same time. */
+
+/* Data type for reentrant functions. */
+struct _getopt_data
+{
+ /* These have exactly the same meaning as the corresponding global
+ variables, except that they are used for the reentrant
+ versions of getopt. */
+ int optind;
+ int opterr;
+ int optopt;
+ char *optarg;
+
+ /* Internal members. */
+
+ /* True if the internal members have been initialized. */
+ int __initialized;
+
+ /* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+ char *__nextchar;
+
+ /* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we
+ scan, so that eventually all the non-options are at the end.
+ This allows options to be given in any order, even with programs
+ that were not written to expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were
+ written to expect options and other ARGV-elements in any order
+ and that care about the ordering of the two. We describe each
+ non-option ARGV-element as if it were the argument of an option
+ with character code 1. Using `-' as the first character of the
+ list of option characters selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+ enum
+ {
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+ } __ordering;
+
+ /* If the POSIXLY_CORRECT environment variable is set. */
+ int __posixly_correct;
+
+
+ /* Handle permutation of arguments. */
+
+ /* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first
+ of them; `last_nonopt' is the index after the last of them. */
+
+ int __first_nonopt;
+ int __last_nonopt;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ int __nonoption_flags_max_len;
+ int __nonoption_flags_len;
+# endif
+};
+
+/* The initializer is necessary to set OPTIND and OPTERR to their
+ default values and to clear the initialization flag. */
+#define _GETOPT_DATA_INITIALIZER { 1, 1 }
+
+extern int _getopt_internal_r (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only, struct _getopt_data *__data);
+
+extern int _getopt_long_r (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ struct _getopt_data *__data);
+
+extern int _getopt_long_only_r (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts,
+ int *__longind,
+ struct _getopt_data *__data);
+
+#endif /* getopt_int.h */
--- /dev/null
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* ADR: Need this so gcc -g without -O works. */
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif /* HAVE_LOCALE_H */
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+/* ADR: Include <locale.h> even if not ENABLE_NLS so can pay attention
+ * to locale number formats, etc.
+ */
+#if defined(__sun) || defined(HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+/* ADR: BOGUS. Remove const. 19 Feb 2002 */
+# define gettext(Msgid) ((char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((char *) (Msgid))
+# define dcgettext(Domainname, Msgid, Category) ((char *) (Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2))
+# define textdomain(Domainname) ((char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) ((char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+#endif /* _LIBGETTEXT_H */
--- /dev/null
+/* hard-locale.h -- Same as hard-locale.c.
+ *
+ * For gawk, put this in a header file, provides source code
+ * compatibility with GNU grep for dfa.c, so that dfa.c need
+ * not be continually modified by hand.
+ */
+/* hard-locale.c -- Determine whether a locale is hard.
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+/* Return nonzero if the current CATEGORY locale is hard, i.e. if you
+ can't get away with assuming traditional C or POSIX behavior. */
+static int
+hard_locale (int category)
+{
+#if ! (defined ENABLE_NLS && HAVE_SETLOCALE)
+ return 0;
+#else
+
+ int hard = 1;
+ char const *p = setlocale (category, 0);
+
+ if (p)
+ {
+# if defined __GLIBC__ && __GLIBC__ >= 2
+ if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
+ hard = 0;
+# else
+ static ptr_t xmalloc PARAMS ((size_t n));
+
+ char *locale = xmalloc (strlen (p) + 1);
+ strcpy (locale, p);
+
+ /* Temporarily set the locale to the "C" and "POSIX" locales to
+ find their names, so that we can determine whether one or the
+ other is the caller's locale. */
+ if (((p = setlocale (category, "C")) && strcmp (p, locale) == 0)
+ || ((p = setlocale (category, "POSIX")) && strcmp (p, locale) == 0))
+ hard = 0;
+
+ /* Restore the caller's locale. */
+ setlocale (category, locale);
+ free(locale);
+# endif
+ }
+
+ return hard;
+
+#endif
+}
--- /dev/null
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-02-02.21
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ *) # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ test -n "$dir_arg$dstarg" && break
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+ break;;
+ esac
+done
+
+if test -z "$1"; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ src=
+
+ if test -d "$dst"; then
+ mkdircmd=:
+ chmodcmd=
+ else
+ mkdircmd=$mkdirprog
+ fi
+ else
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dst=$dst/`basename "$src"`
+ fi
+ fi
+
+ # This sed command emulates the dirname command.
+ dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+ # Make sure that the destination directory exists.
+
+ # Skip lots of stat calls in the usual case.
+ if test ! -d "$dstdir"; then
+ defaultIFS='
+ '
+ IFS="${IFS-$defaultIFS}"
+
+ oIFS=$IFS
+ # Some sh's can't handle IFS=/ for some reason.
+ IFS='%'
+ set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+ shift
+ IFS=$oIFS
+
+ pathcomp=
+
+ while test $# -ne 0 ; do
+ pathcomp=$pathcomp$1
+ shift
+ if test ! -d "$pathcomp"; then
+ $mkdirprog "$pathcomp"
+ # mkdir can fail with a `File exist' error in case several
+ # install-sh are creating the directory concurrently. This
+ # is OK.
+ test -d "$pathcomp" || exit
+ fi
+ pathcomp=$pathcomp/
+ done
+ fi
+
+ if test -n "$dir_arg"; then
+ $doit $mkdircmd "$dst" \
+ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+ else
+ dstfile=`basename "$dst"`
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Copy the file name to the temp name.
+ $doit $cpprog "$src" "$dsttmp" &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+ # Now rename the file to the real destination.
+ { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+ || {
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ if test -f "$dstdir/$dstfile"; then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+ || {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit 1
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+ }
+ }
+ fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+ (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+/*
+ * io.c --- routines for dealing with input and output and records
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+#ifdef HAVE_SYS_PARAM_H
+#undef RE_DUP_MAX /* avoid spurious conflict w/regex.h */
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifndef O_RDONLY
+#include <fcntl.h>
+#endif
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+
+#ifdef HAVE_SOCKETS
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#else
+#include <in.h>
+#endif /* HAVE_NETINET_IN_H */
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif /* HAVE_NETDB_H */
+#endif /* HAVE_SOCKETS */
+
+#ifdef __EMX__
+#include <process.h>
+#endif
+
+#ifndef ENFILE
+#define ENFILE EMFILE
+#endif
+
+extern int MRL;
+
+#ifdef HAVE_SOCKETS
+enum inet_prot { INET_NONE, INET_TCP, INET_UDP, INET_RAW };
+
+#ifndef SHUT_RD
+#define SHUT_RD 0
+#endif
+
+#ifndef SHUT_WR
+#define SHUT_WR 1
+#endif
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
+#endif /* HAVE_SOCKETS */
+
+#ifdef atarist
+#include <stddef.h>
+#endif
+
+#if defined(GAWK_AIX)
+#undef TANDEM /* AIX defines this in one of its header files */
+#undef MSDOS /* For good measure, */
+#undef WIN32 /* yes, I'm paranoid */
+#endif
+
+#if defined(MSDOS) || defined(WIN32) || defined(TANDEM)
+#define PIPES_SIMULATED
+#endif
+
+typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
+
+/* Several macros make the code a bit clearer: */
+/* */
+/* */
+/* <defines and enums>= */
+#define at_eof(iop) ((iop->flag & IOP_AT_EOF) != 0)
+#define has_no_data(iop) (iop->dataend == NULL)
+#define no_data_left(iop) (iop->off >= iop->dataend)
+/* The key point to the design is to split out the code that searches through */
+/* a buffer looking for the record and the terminator into separate routines, */
+/* with a higher-level routine doing the reading of data and buffer management. */
+/* This makes the code easier to manage; the buffering code is the same independent */
+/* of how we find a record. Communication is via the return value: */
+/* */
+/* */
+/* <defines and enums>= */
+typedef enum recvalues {
+ REC_OK, /* record and terminator found, recmatch struct filled in */
+ NOTERM, /* no terminator found, give me more input data */
+ TERMATEND, /* found terminator at end of buffer */
+ TERMNEAREND /* found terminator close to end of buffer, for RE might be bigger */
+} RECVALUE;
+/* Between calls to a scanning routine, the state is stored in */
+/* an [[enum scanstate]] variable. Not all states apply to all */
+/* variants, but the higher code doesn't really care. */
+/* */
+/* */
+/* <defines and enums>= */
+typedef enum scanstate {
+ NOSTATE, /* scanning not started yet (all) */
+ INLEADER, /* skipping leading data (RS = "") */
+ INDATA, /* in body of record (all) */
+ INTERM /* scanning terminator (RS = "", RS = regexp) */
+} SCANSTATE;
+/* When a record is seen ([[REC_OK]] or [[TERMATEND]]), the following */
+/* structure is filled in. */
+/* */
+/* */
+/* <recmatch>= */
+struct recmatch {
+ char *start; /* record start */
+ size_t len; /* length of record */
+ char *rt_start; /* start of terminator */
+ size_t rt_len; /* length of terminator */
+};
+
+static IOBUF *nextfile P((int skipping));
+static int inrec P((IOBUF *iop));
+static int iop_close P((IOBUF *iop));
+struct redirect *redirect P((NODE *tree, int *errflg));
+static void close_one P((void));
+static int close_redir P((struct redirect *rp, int exitwarn, two_way_close_type how));
+#ifndef PIPES_SIMULATED
+static int wait_any P((int interesting));
+#endif
+static IOBUF *gawk_popen P((const char *cmd, struct redirect *rp));
+static IOBUF *iop_open P((const char *file, const char *how, IOBUF *buf));
+static IOBUF *iop_alloc P((int fd, const char *name, IOBUF *buf));
+static int gawk_pclose P((struct redirect *rp));
+static int do_pathopen P((const char *file));
+static int str2mode P((const char *mode));
+static void spec_setup P((IOBUF *iop, int len, int allocate));
+static int specfdopen P((IOBUF *iop, const char *name, const char *mode));
+static int pidopen P((IOBUF *iop, const char *name, const char *mode));
+static int useropen P((IOBUF *iop, const char *name, const char *mode));
+static int two_way_open P((const char *str, struct redirect *rp));
+static int pty_vs_pipe P((const char *command));
+
+static RECVALUE rs1scan P((IOBUF *iop, struct recmatch *recm, SCANSTATE *state));
+static RECVALUE rsnullscan P((IOBUF *iop, struct recmatch *recm, SCANSTATE *state));
+static RECVALUE rsrescan P((IOBUF *iop, struct recmatch *recm, SCANSTATE *state));
+
+static RECVALUE (*matchrec) P((IOBUF *iop, struct recmatch *recm, SCANSTATE *state)) = rs1scan;
+
+static int get_a_record P((char **out, IOBUF *iop, int *errcode));
+
+#if defined(HAVE_POPEN_H)
+#include "popen.h"
+#endif
+
+static struct redirect *red_head = NULL;
+static NODE *RS;
+static Regexp *RS_re_yes_case;
+static Regexp *RS_re_no_case;
+static Regexp *RS_regexp;
+
+int RS_is_null;
+
+extern int output_is_tty;
+extern NODE *ARGC_node;
+extern NODE *ARGV_node;
+extern NODE *ARGIND_node;
+extern NODE *ERRNO_node;
+extern NODE **fields_arr;
+
+static jmp_buf filebuf; /* for do_nextfile() */
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__EMX__) || defined(__CYGWIN__)
+/* binmode --- convert BINMODE to string for fopen */
+
+static const char *
+binmode(const char *mode)
+{
+ switch (mode[0]) {
+ case 'r':
+ if ((BINMODE & 1) != 0)
+ mode = "rb";
+ break;
+ case 'w':
+ case 'a':
+ if ((BINMODE & 2) != 0)
+ mode = (mode[0] == 'w' ? "wb" : "ab");
+ break;
+ }
+ return mode;
+}
+#else
+#define binmode(mode) (mode)
+#endif
+
+#ifdef VMS
+/* File pointers have an extra level of indirection, and there are cases where
+ `stdin' can be null. That can crash gawk if fileno() is used as-is. */
+static int vmsrtl_fileno P((FILE *));
+static int vmsrtl_fileno(fp) FILE *fp; { return fileno(fp); }
+#undef fileno
+#define fileno(FP) (((FP) && *(FP)) ? vmsrtl_fileno(FP) : -1)
+#endif /* VMS */
+
+/* do_nextfile --- implement gawk "nextfile" extension */
+
+void
+do_nextfile()
+{
+ (void) nextfile(TRUE);
+ longjmp(filebuf, 1);
+}
+
+/* nextfile --- move to the next input data file */
+
+static IOBUF *
+nextfile(int skipping)
+{
+ static long i = 1;
+ static int files = FALSE;
+ NODE *arg;
+ static IOBUF *curfile = NULL;
+ static IOBUF mybuf;
+ const char *fname;
+
+ if (skipping) {
+ if (curfile != NULL)
+ iop_close(curfile);
+ curfile = NULL;
+ return NULL;
+ }
+ if (curfile != NULL) {
+ if (at_eof(curfile)) {
+ (void) iop_close(curfile);
+ curfile = NULL;
+ } else
+ return curfile;
+ }
+ for (; i < (long) (ARGC_node->lnode->numbr); i++) {
+ arg = *assoc_lookup(ARGV_node, tmp_number((AWKNUM) i), FALSE);
+ if (arg->stlen == 0)
+ continue;
+ arg->stptr[arg->stlen] = '\0';
+ if (! do_traditional) {
+ unref(ARGIND_node->var_value);
+ ARGIND_node->var_value = make_number((AWKNUM) i);
+ }
+ if (! arg_assign(arg->stptr, FALSE)) {
+ files = TRUE;
+ fname = arg->stptr;
+ curfile = iop_open(fname, binmode("r"), &mybuf);
+ if (curfile == NULL)
+ goto give_up;
+ curfile->flag |= IOP_NOFREE_OBJ;
+ /* This is a kludge. */
+ unref(FILENAME_node->var_value);
+ FILENAME_node->var_value = dupnode(arg);
+ FNR = 0;
+ i++;
+ break;
+ }
+ }
+ if (files == FALSE) {
+ files = TRUE;
+ /* no args. -- use stdin */
+ /* FNR is init'ed to 0 */
+ unref(FILENAME_node->var_value);
+ FILENAME_node->var_value = make_string("-", 1);
+ fname = "-";
+ curfile = iop_open(fname, binmode("r"), &mybuf);
+ if (curfile == NULL)
+ goto give_up;
+ curfile->flag |= IOP_NOFREE_OBJ;
+ }
+ return curfile;
+
+ give_up:
+ fatal(_("cannot open file `%s' for reading (%s)"),
+ fname, strerror(errno));
+ /* NOTREACHED */
+ return (IOBUF *) 0;
+}
+
+/* set_FNR --- update internal FNR from awk variable */
+
+void
+set_FNR()
+{
+ FNR = (long) FNR_node->var_value->numbr;
+}
+
+/* set_NR --- update internal NR from awk variable */
+
+void
+set_NR()
+{
+ NR = (long) NR_node->var_value->numbr;
+}
+
+/* inrec --- This reads in a record from the input file */
+
+static int
+inrec(IOBUF *iop)
+{
+ char *begin;
+ register int cnt;
+ int retval = 0;
+
+ if (at_eof(iop) && no_data_left(iop))
+ cnt = EOF;
+ else if ((iop->flag & IOP_CLOSED) != 0)
+ cnt = EOF;
+ else
+ cnt = get_a_record(&begin, iop, NULL);
+
+ if (cnt == EOF) {
+ cnt = 0;
+ retval = 1;
+ } else {
+ NR += 1;
+ FNR += 1;
+ set_record(begin, cnt);
+ }
+
+ return retval;
+}
+
+/* iop_close --- close an open IOP */
+
+static int
+iop_close(IOBUF *iop)
+{
+ int ret;
+
+ if (iop == NULL)
+ return 0;
+ errno = 0;
+
+ iop->flag &= ~IOP_AT_EOF;
+ iop->flag |= IOP_CLOSED; /* there may be dangling pointers */
+ iop->dataend = NULL;
+#ifdef _CRAY
+ /* Work around bug in UNICOS popen */
+ if (iop->fd < 3)
+ ret = 0;
+ else
+#endif
+ /* save these for re-use; don't free the storage */
+ if ((iop->flag & IOP_IS_INTERNAL) != 0) {
+ iop->off = iop->buf;
+ iop->end = iop->buf + strlen(iop->buf);
+ iop->count = 0;
+ return 0;
+ }
+
+ /* Don't close standard files or else crufty code elsewhere will lose */
+ /* FIXME: *DO* close it. Just reopen on an invalid handle. */
+ if (iop->fd == fileno(stdin)
+ || iop->fd == fileno(stdout)
+ || iop->fd == fileno(stderr))
+ ret = 0;
+ else
+ ret = close(iop->fd);
+
+ if (iop->close_func != NULL)
+ (*iop->close_func)(iop);
+
+ if (ret == -1)
+ warning(_("close of fd %d (`%s') failed (%s)"), iop->fd,
+ iop->name, strerror(errno));
+ if ((iop->flag & IOP_NO_FREE) == 0) {
+ /*
+ * Be careful -- $0 may still reference the buffer even though
+ * an explicit close is being done; in the future, maybe we
+ * can do this a bit better.
+ */
+ if (iop->buf) {
+ if ((fields_arr[0]->stptr >= iop->buf)
+ && (fields_arr[0]->stptr < (iop->buf + iop->size))) {
+ NODE *t;
+
+ t = make_string(fields_arr[0]->stptr,
+ fields_arr[0]->stlen);
+ unref(fields_arr[0]);
+ fields_arr[0] = t;
+ /*
+ * 1/27/2003: This used to be here:
+ *
+ * reset_record();
+ *
+ * Don't do that; reset_record() throws away all fields,
+ * saves FS etc. We just need to make sure memory isn't
+ * corrupted and that references to $0 and fields work.
+ */
+ }
+ free(iop->buf);
+ iop->buf = NULL;
+ }
+ if ((iop->flag & IOP_NOFREE_OBJ) == 0)
+ free((char *) iop);
+ }
+ return ret == -1 ? 1 : 0;
+}
+
+/* do_input --- the main input processing loop */
+
+void
+do_input()
+{
+ IOBUF *iop;
+ extern int exiting;
+ int rval1, rval2, rval3;
+
+ (void) setjmp(filebuf); /* for `nextfile' */
+
+ while ((iop = nextfile(FALSE)) != NULL) {
+ /*
+ * This was:
+ if (inrec(iop) == 0)
+ while (interpret(expression_value) && inrec(iop) == 0)
+ continue;
+ * Now expand it out for ease of debugging.
+ */
+ rval1 = inrec(iop);
+ if (rval1 == 0) {
+ for (;;) {
+ rval2 = rval3 = -1; /* for debugging */
+ rval2 = interpret(expression_value);
+ if (rval2 != 0)
+ rval3 = inrec(iop);
+ if (rval2 == 0 || rval3 != 0)
+ break;
+ }
+ }
+ if (exiting)
+ break;
+ }
+}
+
+/* redflags2str --- turn redirection flags into a string, for debugging */
+
+const char *
+redflags2str(int flags)
+{
+ static const struct flagtab redtab[] = {
+ { RED_FILE, "RED_FILE" },
+ { RED_PIPE, "RED_PIPE" },
+ { RED_READ, "RED_READ" },
+ { RED_WRITE, "RED_WRITE" },
+ { RED_APPEND, "RED_APPEND" },
+ { RED_NOBUF, "RED_NOBUF" },
+ { RED_EOF, "RED_EOF" },
+ { RED_TWOWAY, "RED_TWOWAY" },
+ { RED_PTY, "RED_PTY" },
+ { RED_SOCKET, "RED_SOCKET" },
+ { RED_TCP, "RED_TCP" },
+ { 0, NULL }
+ };
+
+ return genflags2str(flags, redtab);
+}
+
+/* redirect --- Redirection for printf and print commands */
+
+struct redirect *
+redirect(NODE *tree, int *errflg)
+{
+ register NODE *tmp;
+ register struct redirect *rp;
+ register char *str;
+ int tflag = 0;
+ int outflag = 0;
+ const char *direction = "to";
+ const char *mode;
+ int fd;
+ const char *what = NULL;
+
+ switch (tree->type) {
+ case Node_redirect_append:
+ tflag = RED_APPEND;
+ /* FALL THROUGH */
+ case Node_redirect_output:
+ outflag = (RED_FILE|RED_WRITE);
+ tflag |= outflag;
+ if (tree->type == Node_redirect_output)
+ what = ">";
+ else
+ what = ">>";
+ break;
+ case Node_redirect_pipe:
+ tflag = (RED_PIPE|RED_WRITE);
+ what = "|";
+ break;
+ case Node_redirect_pipein:
+ tflag = (RED_PIPE|RED_READ);
+ what = "|";
+ break;
+ case Node_redirect_input:
+ tflag = (RED_FILE|RED_READ);
+ what = "<";
+ break;
+ case Node_redirect_twoway:
+ tflag = (RED_READ|RED_WRITE|RED_TWOWAY);
+ what = "|&";
+ break;
+ default:
+ fatal(_("invalid tree type %s in redirect()"),
+ nodetype2str(tree->type));
+ break;
+ }
+ tmp = tree_eval(tree->subnode);
+ if (do_lint && (tmp->flags & STRCUR) == 0)
+ lintwarn(_("expression in `%s' redirection only has numeric value"),
+ what);
+ tmp = force_string(tmp);
+ str = tmp->stptr;
+
+ if (str == NULL || *str == '\0')
+ fatal(_("expression for `%s' redirection has null string value"),
+ what);
+
+ if (do_lint
+ && (STREQN(str, "0", tmp->stlen) || STREQN(str, "1", tmp->stlen)))
+ lintwarn(_("filename `%s' for `%s' redirection may be result of logical expression"), str, what);
+
+#ifdef HAVE_SOCKETS
+ if (STREQN(str, "/inet/", 6)) {
+ tflag |= RED_SOCKET;
+ if (STREQN(str + 6, "tcp/", 4))
+ tflag |= RED_TCP; /* use shutdown when closing */
+ }
+#endif /* HAVE_SOCKETS */
+
+ for (rp = red_head; rp != NULL; rp = rp->next) {
+#ifndef PIPES_SIMULATED
+ /*
+ * This is an efficiency hack. We want to
+ * recover the process slot for dead children,
+ * if at all possible. Messing with signal() for
+ * SIGCLD leads to lots of headaches. However, if
+ * we've gotten EOF from a child input pipeline, it's
+ * good bet that the child has died. So recover it.
+ */
+ if ((rp->flag & RED_EOF) && tree->type == Node_redirect_pipein) {
+ if (rp->pid != -1)
+ wait_any(0);
+ }
+#endif /* PIPES_SIMULATED */
+
+ /* now check for a match */
+ if (strlen(rp->value) == tmp->stlen
+ && memcmp(rp->value, str, tmp->stlen) == 0
+ && ((rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY)) == tflag
+ || (outflag != 0
+ && (rp->flag & (RED_FILE|RED_WRITE)) == outflag))) {
+
+ int rpflag = (rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY));
+ int newflag = (tflag & ~(RED_NOBUF|RED_EOF|RED_PTY));
+
+ if (do_lint && rpflag != newflag)
+ lintwarn(
+ _("unnecessary mixing of `>' and `>>' for file `%.*s'"),
+ (int) tmp->stlen, rp->value);
+
+ break;
+ }
+ }
+
+ if (rp == NULL) {
+ emalloc(rp, struct redirect *, sizeof(struct redirect),
+ "redirect");
+ emalloc(str, char *, tmp->stlen+1, "redirect");
+ memcpy(str, tmp->stptr, tmp->stlen);
+ str[tmp->stlen] = '\0';
+ rp->value = str;
+ rp->flag = tflag;
+ rp->fp = NULL;
+ rp->iop = NULL;
+ rp->pid = -1;
+ rp->status = 0;
+ /* maintain list in most-recently-used first order */
+ if (red_head != NULL)
+ red_head->prev = rp;
+ rp->prev = NULL;
+ rp->next = red_head;
+ red_head = rp;
+ } else
+ str = rp->value; /* get \0 terminated string */
+
+ while (rp->fp == NULL && rp->iop == NULL) {
+ if (rp->flag & RED_EOF)
+ /*
+ * encountered EOF on file or pipe -- must be cleared
+ * by explicit close() before reading more
+ */
+ return rp;
+ mode = NULL;
+ errno = 0;
+ switch (tree->type) {
+ case Node_redirect_output:
+ mode = binmode("w");
+ if ((rp->flag & RED_USED) != 0)
+ mode = (rp->mode[1] == 'b') ? "ab" : "a";
+ break;
+ case Node_redirect_append:
+ mode = binmode("a");
+ break;
+ case Node_redirect_pipe:
+ /* synchronize output before new pipe */
+ (void) flush_io();
+
+ os_restore_mode(fileno(stdin));
+ if ((rp->fp = popen(str, binmode("w"))) == NULL)
+ fatal(_("can't open pipe `%s' for output (%s)"),
+ str, strerror(errno));
+ /* set close-on-exec */
+ os_close_on_exec(fileno(rp->fp), str, "pipe", "to");
+ rp->flag |= RED_NOBUF;
+ break;
+ case Node_redirect_pipein:
+ direction = "from";
+ if (gawk_popen(str, rp) == NULL)
+ fatal(_("can't open pipe `%s' for input (%s)"),
+ str, strerror(errno));
+ break;
+ case Node_redirect_input:
+ direction = "from";
+ rp->iop = iop_open(str, binmode("r"), NULL);
+ break;
+ case Node_redirect_twoway:
+ direction = "to/from";
+ if (! two_way_open(str, rp)) {
+#ifdef HAVE_SOCKETS
+ /* multiple messages make life easier for translators */
+ if (STREQN(str, "/inet/", 6))
+ fatal(_("can't open two way socket `%s' for input/output (%s)"),
+ str, strerror(errno));
+ else
+#endif
+ fatal(_("can't open two way pipe `%s' for input/output (%s)"),
+ str, strerror(errno));
+ }
+ break;
+ default:
+ cant_happen();
+ }
+ if (mode != NULL) {
+ errno = 0;
+ fd = devopen(str, mode);
+ if (fd > INVALID_HANDLE) {
+ if (fd == fileno(stdin))
+ rp->fp = stdin;
+ else if (fd == fileno(stdout))
+ rp->fp = stdout;
+ else if (fd == fileno(stderr))
+ rp->fp = stderr;
+ else {
+#if defined(F_GETFL) && defined(O_APPEND)
+ int fd_flags;
+
+ fd_flags = fcntl(fd, F_GETFL);
+ if (fd_flags != -1 && (fd_flags & O_APPEND) == O_APPEND)
+ rp->fp = fdopen(fd, binmode("a"));
+ else
+#endif
+ rp->fp = fdopen(fd, (const char *) mode);
+ rp->mode = (const char *) mode;
+ /* don't leak file descriptors */
+ if (rp->fp == NULL)
+ close(fd);
+ }
+ if (rp->fp != NULL && isatty(fd))
+ rp->flag |= RED_NOBUF;
+ /* Move rp to the head of the list. */
+ if (red_head != rp) {
+ if ((rp->prev->next = rp->next) != NULL)
+ rp->next->prev = rp->prev;
+ red_head->prev = rp;
+ rp->prev = NULL;
+ rp->next = red_head;
+ red_head = rp;
+ }
+ }
+ }
+ if (rp->fp == NULL && rp->iop == NULL) {
+ /* too many files open -- close one and try again */
+ if (errno == EMFILE || errno == ENFILE)
+ close_one();
+#if defined __MINGW32__ || defined __sun
+ else if (errno == 0) /* HACK! */
+ close_one();
+#endif
+#ifdef VMS
+ /* Alpha/VMS V7.1's C RTL is returning this instead
+ of EMFILE (haven't tried other post-V6.2 systems) */
+#define SS$_EXQUOTA 0x001C
+ else if (errno == EIO && vaxc$errno == SS$_EXQUOTA)
+ close_one();
+#endif
+ else {
+ /*
+ * Some other reason for failure.
+ *
+ * On redirection of input from a file,
+ * just return an error, so e.g. getline
+ * can return -1. For output to file,
+ * complain. The shell will complain on
+ * a bad command to a pipe.
+ */
+ if (errflg != NULL)
+ *errflg = errno;
+ if (tree->type == Node_redirect_output
+ || tree->type == Node_redirect_append) {
+ /* multiple messages make life easier for translators */
+ if (*direction == 'f')
+ fatal(_("can't redirect from `%s' (%s)"),
+ str, strerror(errno));
+ else
+ fatal(_("can't redirect to `%s' (%s)"),
+ str, strerror(errno));
+ } else {
+ free_temp(tmp);
+ return NULL;
+ }
+ }
+ }
+ }
+ free_temp(tmp);
+ return rp;
+}
+
+/* getredirect --- find the struct redirect for this file or pipe */
+
+struct redirect *
+getredirect(const char *str, int len)
+{
+ struct redirect *rp;
+
+ for (rp = red_head; rp != NULL; rp = rp->next)
+ if (strlen(rp->value) == len && memcmp(rp->value, str, len) == 0)
+ return rp;
+
+ return NULL;
+}
+
+/* close_one --- temporarily close an open file to re-use the fd */
+
+static void
+close_one()
+{
+ register struct redirect *rp;
+ register struct redirect *rplast = NULL;
+
+ static short warned = FALSE;
+
+ if (do_lint && ! warned) {
+ warned = TRUE;
+ lintwarn(_("reached system limit for open files: starting to multiplex file descriptors"));
+ }
+
+ /* go to end of list first, to pick up least recently used entry */
+ for (rp = red_head; rp != NULL; rp = rp->next)
+ rplast = rp;
+ /* now work back up through the list */
+ for (rp = rplast; rp != NULL; rp = rp->prev) {
+ /* don't close standard files! */
+ if (rp->fp == NULL || rp->fp == stderr || rp->fp == stdout)
+ continue;
+
+ if ((rp->flag & (RED_FILE|RED_WRITE)) == (RED_FILE|RED_WRITE)) {
+ rp->flag |= RED_USED;
+ errno = 0;
+ if (/* do_lint && */ fclose(rp->fp) != 0)
+ warning(_("close of `%s' failed (%s)."),
+ rp->value, strerror(errno));
+ rp->fp = NULL;
+ break;
+ }
+ }
+ if (rp == NULL)
+ /* surely this is the only reason ??? */
+ fatal(_("too many pipes or input files open"));
+}
+
+/* do_close --- completely close an open file or pipe */
+
+NODE *
+do_close(NODE *tree)
+{
+ NODE *tmp, *tmp2;
+ register struct redirect *rp;
+ two_way_close_type how = CLOSE_ALL; /* default */
+
+ tmp = force_string(tree_eval(tree->lnode)); /* 1st arg: redir to close */
+
+ if (tree->rnode != NULL) {
+ /* 2nd arg if present: "to" or "from" for two-way pipe */
+ /* DO NOT use _() on the strings here! */
+ tmp2 = force_string(tree->rnode->lnode);
+ if (strcasecmp(tmp2->stptr, "to") == 0)
+ how = CLOSE_TO;
+ else if (strcasecmp(tmp2->stptr, "from") == 0)
+ how = CLOSE_FROM;
+ else
+ fatal(_("close: second argument must be `to' or `from'"));
+ free_temp(tmp2);
+ }
+
+ for (rp = red_head; rp != NULL; rp = rp->next) {
+ if (strlen(rp->value) == tmp->stlen
+ && memcmp(rp->value, tmp->stptr, tmp->stlen) == 0)
+ break;
+ }
+
+ if (rp == NULL) { /* no match, return -1 */
+ char *cp;
+
+ if (do_lint)
+ lintwarn(_("close: `%.*s' is not an open file, pipe or co-process"),
+ (int) tmp->stlen, tmp->stptr);
+
+ /* update ERRNO manually, using errno = ENOENT is a stretch. */
+ cp = _("close of redirection that was never opened");
+ unref(ERRNO_node->var_value);
+ ERRNO_node->var_value = make_string(cp, strlen(cp));
+
+ free_temp(tmp);
+ return tmp_number((AWKNUM) -1.0);
+ }
+ free_temp(tmp);
+ fflush(stdout); /* synchronize regular output */
+ tmp = tmp_number((AWKNUM) close_redir(rp, FALSE, how));
+ rp = NULL;
+ /*
+ * POSIX says close() returns 0 on success, non-zero otherwise.
+ * For POSIX, at this point we just return 0. Otherwise we
+ * return the exit status of the process or of pclose(), depending.
+ * This whole business is a mess.
+ */
+ if (do_posix) {
+ free_temp(tmp);
+ return tmp_number((AWKNUM) 0);
+ }
+ return tmp;
+}
+
+/* close_rp --- separate function to just do closing */
+
+static int
+close_rp(struct redirect *rp, two_way_close_type how)
+{
+ int status = 0;
+
+ errno = 0;
+ if ((rp->flag & RED_TWOWAY) != 0) { /* two-way pipe */
+ /* write end: */
+ if ((how == CLOSE_ALL || how == CLOSE_TO) && rp->fp != NULL) {
+#ifdef HAVE_SOCKETS
+ if ((rp->flag & RED_TCP) != 0)
+ (void) shutdown(fileno(rp->fp), SHUT_WR);
+#endif /* HAVE_SOCKETS */
+
+ if ((rp->flag & RED_PTY) != 0) {
+ fwrite("\004\n", sizeof("\004\n") - 1, 1, rp->fp);
+ fflush(rp->fp);
+ }
+ status = fclose(rp->fp);
+ rp->fp = NULL;
+ }
+
+ /* read end: */
+ if (how == CLOSE_ALL || how == CLOSE_FROM) {
+ if ((rp->flag & RED_SOCKET) != 0 && rp->iop != NULL) {
+#ifdef HAVE_SOCKETS
+ if ((rp->flag & RED_TCP) != 0)
+ (void) shutdown(rp->iop->fd, SHUT_RD);
+#endif /* HAVE_SOCKETS */
+ (void) iop_close(rp->iop);
+ } else
+ status = gawk_pclose(rp);
+
+ rp->iop = NULL;
+ }
+ } else if ((rp->flag & (RED_PIPE|RED_WRITE)) == (RED_PIPE|RED_WRITE)) { /* write to pipe */
+ status = pclose(rp->fp);
+ if ((BINMODE & 1) != 0)
+ os_setbinmode(fileno(stdin), O_BINARY);
+
+ rp->fp = NULL;
+ } else if (rp->fp != NULL) { /* write to file */
+ status = fclose(rp->fp);
+ rp->fp = NULL;
+ } else if (rp->iop != NULL) { /* read from pipe/file */
+ if ((rp->flag & RED_PIPE) != 0) /* read from pipe */
+ status = gawk_pclose(rp);
+ /* gawk_pclose sets rp->iop to null */
+ else { /* read from file */
+ status = iop_close(rp->iop);
+ rp->iop = NULL;
+ }
+ }
+
+ return status;
+}
+
+/* close_redir --- close an open file or pipe */
+
+static int
+close_redir(register struct redirect *rp, int exitwarn, two_way_close_type how)
+{
+ int status = 0;
+
+ if (rp == NULL)
+ return 0;
+ if (rp->fp == stdout || rp->fp == stderr)
+ goto checkwarn; /* bypass closing, remove from list */
+
+ if (do_lint && (rp->flag & RED_TWOWAY) == 0 && how != CLOSE_ALL)
+ lintwarn(_("close: redirection `%s' not opened with `|&', second argument ignored"),
+ rp->value);
+
+ status = close_rp(rp, how);
+
+ /* SVR4 awk checks and warns about status of close */
+ if (status != 0) {
+ int save_errno = errno;
+ char *s = strerror(save_errno);
+
+ /*
+ * Too many people have complained about this.
+ * As of 2.15.6, it is now under lint control.
+ */
+ if (do_lint) {
+ if ((rp->flag & RED_PIPE) != 0)
+ lintwarn(_("failure status (%d) on pipe close of `%s' (%s)"),
+ status, rp->value, s);
+ else
+ lintwarn(_("failure status (%d) on file close of `%s' (%s)"),
+ status, rp->value, s);
+ }
+
+ if (! do_traditional) {
+ /* set ERRNO too so that program can get at it */
+ update_ERRNO_saved(save_errno);
+ }
+ }
+
+checkwarn:
+ if (exitwarn) {
+ /*
+ * Don't use lintwarn() here. If lint warnings are fatal,
+ * doing so prevents us from closing other open redirections.
+ *
+ * Using multiple full messages instead of string parameters
+ * for the types makes message translation easier.
+ */
+ if ((rp->flag & RED_SOCKET) != 0)
+ warning(_("no explicit close of socket `%s' provided"),
+ rp->value);
+ else if ((rp->flag & RED_TWOWAY) != 0)
+ warning(_("no explicit close of co-process `%s' provided"),
+ rp->value);
+ else if ((rp->flag & RED_PIPE) != 0)
+ warning(_("no explicit close of pipe `%s' provided"),
+ rp->value);
+ else
+ warning(_("no explicit close of file `%s' provided"),
+ rp->value);
+ }
+
+ /* remove it from the list if closing both or both ends have been closed */
+ if (how == CLOSE_ALL || (rp->iop == NULL && rp->fp == NULL)) {
+ if (rp->next != NULL)
+ rp->next->prev = rp->prev;
+ if (rp->prev != NULL)
+ rp->prev->next = rp->next;
+ else
+ red_head = rp->next;
+ free(rp->value);
+ free((char *) rp);
+ }
+
+ return status;
+}
+
+/* flush_io --- flush all open output files */
+
+int
+flush_io()
+{
+ register struct redirect *rp;
+ int status = 0;
+
+ errno = 0;
+ if (fflush(stdout)) {
+ warning(_("error writing standard output (%s)"), strerror(errno));
+ status++;
+ }
+ if (fflush(stderr)) {
+ warning(_("error writing standard error (%s)"), strerror(errno));
+ status++;
+ }
+ for (rp = red_head; rp != NULL; rp = rp->next)
+ /* flush both files and pipes, what the heck */
+ if ((rp->flag & RED_WRITE) && rp->fp != NULL) {
+ if (fflush(rp->fp)) {
+ if (rp->flag & RED_PIPE)
+ warning(_("pipe flush of `%s' failed (%s)."),
+ rp->value, strerror(errno));
+ else if (rp->flag & RED_TWOWAY)
+ warning(_("co-process flush of pipe to `%s' failed (%s)."),
+ rp->value, strerror(errno));
+ else
+ warning(_("file flush of `%s' failed (%s)."),
+ rp->value, strerror(errno));
+ status++;
+ }
+ }
+ if (status != 0)
+ status = -1; /* canonicalize it */
+ return status;
+}
+
+/* close_io --- close all open files, called when exiting */
+
+int
+close_io(int *stdio_problem)
+{
+ register struct redirect *rp;
+ register struct redirect *next;
+ int status = 0;
+
+ errno = 0;
+ for (rp = red_head; rp != NULL; rp = next) {
+ next = rp->next;
+ /*
+ * close_redir() will print a message if needed
+ * if do_lint, warn about lack of explicit close
+ */
+ if (close_redir(rp, do_lint, CLOSE_ALL))
+ status++;
+ rp = NULL;
+ }
+ /*
+ * Some of the non-Unix os's have problems doing an fclose
+ * on stdout and stderr. Since we don't really need to close
+ * them, we just flush them, and do that across the board.
+ */
+ *stdio_problem = FALSE;
+ if (fflush(stdout)) {
+ warning(_("error writing standard output (%s)"), strerror(errno));
+ status++;
+ *stdio_problem = TRUE;
+ }
+ if (fflush(stderr)) {
+ warning(_("error writing standard error (%s)"), strerror(errno));
+ status++;
+ *stdio_problem = TRUE;
+ }
+ return status;
+}
+
+/* str2mode --- convert a string mode to an integer mode */
+
+static int
+str2mode(const char *mode)
+{
+ int ret;
+ const char *second = & mode[1];
+
+ if (*second == 'b')
+ second++;
+
+ switch(mode[0]) {
+ case 'r':
+ ret = O_RDONLY;
+ if (*second == '+' || *second == 'w')
+ ret = O_RDWR;
+ break;
+
+ case 'w':
+ ret = O_WRONLY|O_CREAT|O_TRUNC;
+ if (*second == '+' || *second == 'r')
+ ret = O_RDWR|O_CREAT|O_TRUNC;
+ break;
+
+ case 'a':
+ ret = O_WRONLY|O_APPEND|O_CREAT;
+ if (*second == '+')
+ ret = O_RDWR|O_APPEND|O_CREAT;
+ break;
+
+ default:
+ ret = 0; /* lint */
+ cant_happen();
+ }
+ if (strchr(mode, 'b') != NULL)
+ ret |= O_BINARY;
+ return ret;
+}
+
+#ifdef HAVE_SOCKETS
+/* socketopen --- open a socket and set it into connected state */
+
+static int
+socketopen(enum inet_prot type, int localport, int remoteport, const char *remotehostname)
+{
+ struct hostent *hp = gethostbyname(remotehostname);
+ struct sockaddr_in local_addr, remote_addr;
+ int socket_fd;
+ int any_remote_host = strcmp(remotehostname, "0");
+
+ socket_fd = INVALID_HANDLE;
+ switch (type) {
+ case INET_TCP:
+ if (localport != 0 || remoteport != 0) {
+ int on = 1;
+#ifdef SO_LINGER
+ struct linger linger;
+
+ memset(& linger, '\0', sizeof(linger));
+#endif
+ socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
+ (char *) & on, sizeof(on));
+#ifdef SO_LINGER
+ linger.l_onoff = 1;
+ linger.l_linger = 30; /* linger for 30/100 second */
+ setsockopt(socket_fd, SOL_SOCKET, SO_LINGER,
+ (char *) & linger, sizeof(linger));
+#endif
+ }
+ break;
+ case INET_UDP:
+ if (localport != 0 || remoteport != 0)
+ socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ break;
+ case INET_RAW:
+#ifdef SOCK_RAW
+ if (localport == 0 && remoteport == 0)
+ socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+#endif
+ break;
+ case INET_NONE:
+ /* fall through */
+ default:
+ cant_happen();
+ break;
+ }
+
+ if (socket_fd < 0 || socket_fd == INVALID_HANDLE
+ || (hp == NULL && any_remote_host != 0))
+ return INVALID_HANDLE;
+
+ local_addr.sin_family = remote_addr.sin_family = AF_INET;
+ local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ remote_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ local_addr.sin_port = htons(localport);
+ remote_addr.sin_port = htons(remoteport);
+ if (bind(socket_fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0) {
+ if (any_remote_host != 0) { /* not ANY => create a client */
+ if (type == INET_TCP || type == INET_UDP) {
+ memcpy(&remote_addr.sin_addr, hp->h_addr,
+ sizeof(remote_addr.sin_addr));
+ if (connect(socket_fd,
+ (struct sockaddr *) &remote_addr,
+ sizeof(remote_addr)) != 0) {
+ close(socket_fd);
+ if (localport == 0)
+ socket_fd = INVALID_HANDLE;
+ else
+ socket_fd = socketopen(type, localport, 0, "0");
+ }
+ } else {
+ /* /inet/raw client not ready yet */
+ fatal(_("/inet/raw client not ready yet, sorry"));
+ if (geteuid() != 0)
+ fatal(_("only root may use `/inet/raw'."));
+ }
+ } else { /* remote host is ANY => create a server */
+ if (type == INET_TCP) {
+ int clientsocket_fd = INVALID_HANDLE;
+ socklen_t namelen = sizeof(remote_addr);
+
+ if (listen(socket_fd, 1) >= 0
+ && (clientsocket_fd = accept(socket_fd,
+ (struct sockaddr *) &remote_addr,
+ &namelen)) >= 0) {
+ close(socket_fd);
+ socket_fd = clientsocket_fd;
+ } else {
+ close(socket_fd);
+ socket_fd = INVALID_HANDLE;
+ }
+ } else if (type == INET_UDP) {
+#ifdef MSG_PEEK
+ char buf[10];
+ socklen_t readle;
+
+ if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
+ (struct sockaddr *) & remote_addr,
+ & readle) < 1
+ || readle != sizeof(remote_addr)
+ || connect(socket_fd,
+ (struct sockaddr *)& remote_addr,
+ readle) != 0) {
+ close(socket_fd);
+ socket_fd = INVALID_HANDLE;
+ }
+#endif
+ } else {
+ /* /inet/raw server not ready yet */
+ fatal(_("/inet/raw server not ready yet, sorry"));
+ if (geteuid() != 0)
+ fatal(_("only root may use `/inet/raw'."));
+ }
+ }
+ } else {
+ close(socket_fd);
+ socket_fd = INVALID_HANDLE;
+ }
+
+ return socket_fd;
+}
+#endif /* HAVE_SOCKETS */
+
+/* devopen --- handle /dev/std{in,out,err}, /dev/fd/N, regular files */
+
+/*
+ * This separate version is still needed for output, since file and pipe
+ * output is done with stdio. iop_open() handles input with IOBUFs of
+ * more "special" files. Those files are not handled here since it makes
+ * no sense to use them for output.
+ */
+
+/*
+ * Strictly speaking, "name" is not a "const char *" because we temporarily
+ * change the string.
+ */
+
+int
+devopen(const char *name, const char *mode)
+{
+ int openfd;
+ char *cp;
+ char *ptr;
+ int flag = 0;
+ extern unsigned long strtoul P((const char *, char **endptr, int base));
+
+ flag = str2mode(mode);
+
+ if (STREQ(name, "-"))
+ return fileno(stdin);
+
+ openfd = INVALID_HANDLE;
+
+ if (do_traditional)
+ goto strictopen;
+
+ if ((openfd = os_devopen(name, flag)) != INVALID_HANDLE) {
+ os_close_on_exec(openfd, name, "file", "");
+ return openfd;
+ }
+
+ if (STREQN(name, "/dev/", 5)) {
+ cp = (char *) name + 5;
+
+ if (STREQ(cp, "stdin") && (flag & O_ACCMODE) == O_RDONLY)
+ openfd = fileno(stdin);
+ else if (STREQ(cp, "stdout") && (flag & O_ACCMODE) == O_WRONLY)
+ openfd = fileno(stdout);
+ else if (STREQ(cp, "stderr") && (flag & O_ACCMODE) == O_WRONLY)
+ openfd = fileno(stderr);
+ else if (STREQN(cp, "fd/", 3)) {
+ cp += 3;
+ openfd = (int) strtoul(cp, &ptr, 10);
+ if (openfd <= INVALID_HANDLE || ptr == cp)
+ openfd = INVALID_HANDLE;
+ }
+ /* do not set close-on-exec for inherited fd's */
+ if (openfd != INVALID_HANDLE)
+ return openfd;
+ } else if (STREQN(name, "/inet/", 6)) {
+#ifdef HAVE_SOCKETS
+ /* /inet/protocol/localport/hostname/remoteport */
+ enum inet_prot protocol = INET_NONE;
+ int localport, remoteport;
+ char *hostname;
+ char *hostnameslastcharp;
+ char *localpname;
+ char proto[4];
+ struct servent *service;
+
+ cp = (char *) name + 6;
+ /* which protocol? */
+ if (STREQN(cp, "tcp/", 4))
+ protocol = INET_TCP;
+ else if (STREQN(cp, "udp/", 4))
+ protocol = INET_UDP;
+ else if (STREQN(cp, "raw/", 4))
+ protocol = INET_RAW;
+ else
+ fatal(_("no (known) protocol supplied in special filename `%s'"),
+ name);
+
+ proto[0] = cp[0];
+ proto[1] = cp[1];
+ proto[2] = cp[2];
+ proto[3] = '\0';
+ cp += 4;
+
+ /* which localport? */
+ localpname = cp;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ /*
+ * Require a port, let them explicitly put 0 if
+ * they don't care.
+ */
+ if (*cp != '/' || cp == localpname)
+ fatal(_("special file name `%s' is incomplete"), name);
+ /* We change the special file name temporarily because we
+ * need a 0-terminated string here for conversion with atoi().
+ * By using atoi() the use of decimal numbers is enforced.
+ */
+ *cp = '\0';
+
+ localport = atoi(localpname);
+ if (strcmp(localpname, "0") != 0
+ && (localport <= 0 || localport > 65535)) {
+ service = getservbyname(localpname, proto);
+ if (service == NULL)
+ fatal(_("local port invalid in `%s'"), name);
+ else
+ localport = ntohs(service->s_port);
+ }
+ *cp = '/';
+
+ /* which hostname? */
+ cp++;
+ hostname = cp;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp != '/' || cp == hostname)
+ fatal(_("must supply a remote hostname to `/inet'"));
+ *cp = '\0';
+ hostnameslastcharp = cp;
+
+ /* which remoteport? */
+ cp++;
+ /*
+ * The remote port ends the special file name.
+ * This means there already is a 0 at the end of the string.
+ * Therefore no need to patch any string ending.
+ *
+ * Here too, require a port, let them explicitly put 0 if
+ * they don't care.
+ */
+ if (*cp == '\0')
+ fatal(_("must supply a remote port to `/inet'"));
+ remoteport = atoi(cp);
+ if (strcmp(cp, "0") != 0
+ && (remoteport <= 0 || remoteport > 65535)) {
+ service = getservbyname(cp, proto);
+ if (service == NULL)
+ fatal(_("remote port invalid in `%s'"), name);
+ else
+ remoteport = ntohs(service->s_port);
+ }
+
+ /* Open Sesame! */
+ openfd = socketopen(protocol, localport, remoteport, hostname);
+ *hostnameslastcharp = '/';
+
+#else /* ! HAVE_SOCKETS */
+ fatal(_("TCP/IP communications are not supported"));
+#endif /* HAVE_SOCKETS */
+ }
+
+strictopen:
+ if (openfd == INVALID_HANDLE)
+ openfd = open(name, flag, 0666);
+ if (openfd != INVALID_HANDLE) {
+ if (os_isdir(openfd))
+ fatal(_("file `%s' is a directory"), name);
+
+ os_close_on_exec(openfd, name, "file", "");
+ }
+ return openfd;
+}
+
+
+/* spec_setup --- setup an IOBUF for a special internal file */
+
+static void
+spec_setup(IOBUF *iop, int len, int allocate)
+{
+ char *cp;
+
+ if (allocate) {
+ emalloc(cp, char *, len+2, "spec_setup");
+ iop->buf = cp;
+ } else {
+ len = strlen(iop->buf);
+ iop->buf[len++] = '\n'; /* get_a_record clobbered it */
+ iop->buf[len] = '\0'; /* just in case */
+ }
+ iop->off = iop->buf;
+ iop->count = 0;
+ iop->size = len;
+ iop->end = iop->buf + len;
+ iop->dataend = iop->end;
+ iop->fd = -1;
+ iop->flag = IOP_IS_INTERNAL | IOP_AT_START;
+}
+
+/* specfdopen --- open an fd special file */
+
+static int
+specfdopen(IOBUF *iop, const char *name, const char *mode)
+{
+ int fd;
+ IOBUF *tp;
+
+ fd = devopen(name, mode);
+ if (fd == INVALID_HANDLE)
+ return INVALID_HANDLE;
+ tp = iop_alloc(fd, name, NULL);
+ if (tp == NULL) {
+ /* don't leak fd's */
+ close(fd);
+ return INVALID_HANDLE;
+ }
+ *iop = *tp;
+ iop->flag |= IOP_NO_FREE;
+ free(tp);
+ return 0;
+}
+
+#ifdef GETPGRP_VOID
+#define getpgrp_arg() /* nothing */
+#else
+#define getpgrp_arg() getpid()
+#endif
+
+/* pidopen --- "open" /dev/pid, /dev/ppid, and /dev/pgrpid */
+
+static int
+pidopen(IOBUF *iop, const char *name, const char *mode ATTRIBUTE_UNUSED)
+{
+ char tbuf[BUFSIZ];
+ int i;
+ const char *cp = name + 5;
+
+ warning(_("use `PROCINFO[\"%s\"]' instead of `%s'"), cp, name);
+
+ if (name[6] == 'g')
+ sprintf(tbuf, "%d\n", (int) getpgrp(getpgrp_arg()));
+ else if (name[6] == 'i')
+ sprintf(tbuf, "%d\n", (int) getpid());
+ else
+ sprintf(tbuf, "%d\n", (int) getppid());
+ i = strlen(tbuf);
+ spec_setup(iop, i, TRUE);
+ strcpy(iop->buf, tbuf);
+ return 0;
+}
+
+/* useropen --- "open" /dev/user */
+
+/*
+ * /dev/user creates a record as follows:
+ * $1 = getuid()
+ * $2 = geteuid()
+ * $3 = getgid()
+ * $4 = getegid()
+ * If multiple groups are supported, then $5 through $NF are the
+ * supplementary group set.
+ */
+
+static int
+useropen(IOBUF *iop, const char *name ATTRIBUTE_UNUSED, const char *mode ATTRIBUTE_UNUSED)
+{
+ char tbuf[BUFSIZ], *cp;
+ int i;
+
+ warning(_("use `PROCINFO[...]' instead of `/dev/user'"));
+
+ sprintf(tbuf, "%d %d %d %d", (int) getuid(), (int) geteuid(), (int) getgid(), (int) getegid());
+
+ cp = tbuf + strlen(tbuf);
+#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
+ for (i = 0; i < ngroups; i++) {
+ *cp++ = ' ';
+ sprintf(cp, "%d", (int) groupset[i]);
+ cp += strlen(cp);
+ }
+#endif
+ *cp++ = '\n';
+ *cp++ = '\0';
+
+ i = strlen(tbuf);
+ spec_setup(iop, i, TRUE);
+ strcpy(iop->buf, tbuf);
+ return 0;
+}
+
+/* iop_open --- handle special and regular files for input */
+
+static IOBUF *
+iop_open(const char *name, const char *mode, IOBUF *iop)
+{
+ int openfd = INVALID_HANDLE;
+ int flag = 0;
+ static struct internal {
+ const char *name;
+ int compare;
+ int (*fp) P((IOBUF *, const char *, const char *));
+ IOBUF iob;
+ } table[] = {
+ { "/dev/fd/", 8, specfdopen },
+ { "/dev/stdin", 10, specfdopen },
+ { "/dev/stdout", 11, specfdopen },
+ { "/dev/stderr", 11, specfdopen },
+ { "/inet/", 6, specfdopen },
+ { "/dev/pid", 8, pidopen },
+ { "/dev/ppid", 9, pidopen },
+ { "/dev/pgrpid", 11, pidopen },
+ { "/dev/user", 9, useropen },
+ };
+ int devcount = sizeof(table) / sizeof(table[0]);
+
+ flag = str2mode(mode);
+
+ if (STREQ(name, "-"))
+ openfd = fileno(stdin);
+ else if (do_traditional)
+ goto strictopen;
+ else if (STREQN(name, "/dev/", 5) || STREQN(name, "/inet/", 6)) {
+ int i;
+
+ for (i = 0; i < devcount; i++) {
+ if (STREQN(name, table[i].name, table[i].compare)) {
+ iop = & table[i].iob;
+
+ if (iop->buf != NULL) {
+ spec_setup(iop, 0, FALSE);
+ return iop;
+ } else if ((*table[i].fp)(iop, name, mode) == 0)
+ return iop;
+ else {
+ warning(_("could not open `%s', mode `%s'"),
+ name, mode);
+ return NULL;
+ }
+ }
+ }
+ /* not in table, fall through to regular code */
+ }
+
+strictopen:
+ if (openfd == INVALID_HANDLE)
+ openfd = open(name, flag, 0666);
+ if (openfd != INVALID_HANDLE) {
+ if (os_isdir(openfd))
+ fatal(_("file `%s' is a directory"), name);
+ }
+ /*
+ * At this point, fd could still be INVALID_HANDLE.
+ * We pass it to `iop_alloc' anyway, in case an open hook
+ * can manage to open the file.
+ */
+ iop = iop_alloc(openfd, name, iop);
+ if (iop != NULL) {
+ if (iop->fd > fileno(stderr))
+ os_close_on_exec(iop->fd, name, "file", "");
+ } else if (openfd != INVALID_HANDLE) /* have an fd, but IOP is null */
+ (void) close(openfd); /* avoid fd leak */
+ return iop;
+}
+
+/* two_way_open --- open a two way communications channel */
+
+static int
+two_way_open(const char *str, struct redirect *rp)
+{
+ static int no_ptys = FALSE;
+
+#ifdef HAVE_SOCKETS
+ /* case 1: socket */
+ if (STREQN(str, "/inet/", 6)) {
+ int fd, newfd;
+
+ fd = devopen(str, "rw");
+ if (fd == INVALID_HANDLE)
+ return FALSE;
+ rp->fp = fdopen(fd, "w");
+ if (rp->fp == NULL) {
+ close(fd);
+ return FALSE;
+ }
+ newfd = dup(fd);
+ if (newfd < 0) {
+ fclose(rp->fp);
+ return FALSE;
+ }
+ os_close_on_exec(newfd, str, "socket", "to/from");
+ rp->iop = iop_alloc(newfd, str, NULL);
+ if (rp->iop == NULL) {
+ fclose(rp->fp);
+ return FALSE;
+ }
+ rp->flag |= RED_SOCKET;
+ return TRUE;
+ }
+#endif /* HAVE_SOCKETS */
+
+#ifdef HAVE_PORTALS
+ /* case 1.5: portal */
+ if (STREQN(str, "/p/", 3)) {
+ int fd, newfd;
+
+ fd = open(str, O_RDWR);
+ if (fd == INVALID_HANDLE)
+ return FALSE;
+ rp->fp = fdopen(fd, "w");
+ if (rp->fp == NULL) {
+ close(fd);
+ return FALSE;
+ }
+ newfd = dup(fd);
+ if (newfd < 0) {
+ fclose(rp->fp);
+ return FALSE;
+ }
+ os_close_on_exec(newfd, str, "portal", "to/from");
+ rp->iop = iop_alloc(newfd, str, NULL);
+ if (rp->iop == NULL) {
+ fclose(rp->fp);
+ return FALSE;
+ }
+ rp->flag |= RED_SOCKET;
+ return TRUE;
+ }
+#endif /* HAVE_PORTALS */
+
+#ifdef HAVE_TERMIOS_H
+ /* case 2: use ptys for two-way communications to child */
+ if (! no_ptys && pty_vs_pipe(str)) {
+ static int initialized = FALSE;
+ static char first_pty_letter;
+#ifdef HAVE_GRANTPT
+ static int have_dev_ptmx;
+#endif
+ char slavenam[32];
+ char c;
+ int master, dup_master;
+ int slave;
+ int save_errno;
+ pid_t pid;
+ struct stat statb;
+ struct termios st;
+
+ if (! initialized) {
+ initialized = TRUE;
+#ifdef HAVE_GRANTPT
+ have_dev_ptmx = (stat("/dev/ptmx", &statb) >= 0);
+#endif
+ c = 'p';
+ do {
+ sprintf(slavenam, "/dev/pty%c0", c);
+ if (stat(slavenam, &statb) >= 0) {
+ first_pty_letter = c;
+ break;
+ }
+ if (++c > 'z')
+ c = 'a';
+ } while (c != 'p');
+ }
+
+#ifdef HAVE_GRANTPT
+ if (have_dev_ptmx) {
+ master = open("/dev/ptmx", O_RDWR);
+ if (master >= 0) {
+ char *tem;
+
+ grantpt(master);
+ unlockpt(master);
+ tem = ptsname(master);
+ if (tem != NULL) {
+ strcpy(slavenam, tem);
+ goto got_the_pty;
+ }
+ (void) close(master);
+ }
+ }
+#endif
+
+ if (first_pty_letter) {
+ /*
+ * Assume /dev/ptyXNN and /dev/ttyXN naming system.
+ * The FIRST_PTY_LETTER gives the first X to try. We try in the
+ * sequence FIRST_PTY_LETTER, .., 'z', 'a', .., FIRST_PTY_LETTER.
+ * Is this worthwhile, or just over-zealous?
+ */
+ c = first_pty_letter;
+ do {
+ int i;
+ for (i = 0; i < 16; i++) {
+ sprintf(slavenam, "/dev/pty%c%x", c, i);
+ if (stat(slavenam, &statb) < 0) {
+ no_ptys = TRUE; /* bypass all this next time */
+ goto use_pipes;
+ }
+
+ if ((master = open(slavenam, O_RDWR)) >= 0) {
+ slavenam[sizeof("/dev/") - 1] = 't';
+ if (access(slavenam, R_OK | W_OK) == 0)
+ goto got_the_pty;
+ close(master);
+ }
+ }
+ if (++c > 'z')
+ c = 'a';
+ } while (c != first_pty_letter);
+ } else
+ no_ptys = TRUE;
+
+ /* Couldn't find a pty. Fall back to using pipes. */
+ goto use_pipes;
+
+ got_the_pty:
+ if ((slave = open(slavenam, O_RDWR)) < 0) {
+ fatal(_("could not open `%s', mode `%s'"),
+ slavenam, "r+");
+ }
+
+#ifdef I_PUSH
+ /*
+ * Push the necessary modules onto the slave to
+ * get terminal semantics.
+ */
+ ioctl(slave, I_PUSH, "ptem");
+ ioctl(slave, I_PUSH, "ldterm");
+#endif
+
+#ifdef TIOCSCTTY
+ ioctl(slave, TIOCSCTTY, 0);
+#endif
+ tcgetattr(slave, &st);
+ st.c_iflag &= ~(ISTRIP | IGNCR | INLCR | IXOFF);
+ st.c_iflag |= (ICRNL | IGNPAR | BRKINT | IXON);
+ st.c_oflag &= ~OPOST;
+ st.c_cflag &= ~CSIZE;
+ st.c_cflag |= CREAD | CS8 | CLOCAL;
+ st.c_lflag &= ~(ECHO | ECHOE | ECHOK | NOFLSH | TOSTOP);
+ st.c_lflag |= ISIG;
+#if 0
+ st.c_cc[VMIN] = 1;
+ st.c_cc[VTIME] = 0;
+#endif
+
+ /* Set some control codes to default values */
+#ifdef VINTR
+ st.c_cc[VINTR] = '\003'; /* ^c */
+#endif
+#ifdef VQUIT
+ st.c_cc[VQUIT] = '\034'; /* ^| */
+#endif
+#ifdef VERASE
+ st.c_cc[VERASE] = '\177'; /* ^? */
+#endif
+#ifdef VKILL
+ st.c_cc[VKILL] = '\025'; /* ^u */
+#endif
+#ifdef VEOF
+ st.c_cc[VEOF] = '\004'; /* ^d */
+#endif
+ tcsetattr(slave, TCSANOW, &st);
+
+ switch (pid = fork ()) {
+ case 0:
+ /* Child process */
+ if (close(master) == -1)
+ fatal(_("close of master pty failed (%s)"), strerror(errno));
+ if (close(1) == -1)
+ fatal(_("close of stdout in child failed (%s)"),
+ strerror(errno));
+ if (dup(slave) != 1)
+ fatal(_("moving slave pty to stdout in child failed (dup: %s)"), strerror(errno));
+ if (close(0) == -1)
+ fatal(_("close of stdin in child failed (%s)"),
+ strerror(errno));
+ if (dup(slave) != 0)
+ fatal(_("moving slave pty to stdin in child failed (dup: %s)"), strerror(errno));
+ if (close(slave))
+ fatal(_("close of slave pty failed (%s)"), strerror(errno));
+
+ /* stderr does NOT get dup'ed onto child's stdout */
+
+ signal(SIGPIPE, SIG_DFL);
+
+ execl("/bin/sh", "sh", "-c", str, NULL);
+ _exit(errno == ENOENT ? 127 : 126);
+
+ case -1:
+ save_errno = errno;
+ close(master);
+ errno = save_errno;
+ return FALSE;
+
+ }
+
+ /* parent */
+ if (close(slave))
+ fatal(_("close of slave pty failed (%s)"), strerror(errno));
+
+ rp->pid = pid;
+ rp->iop = iop_alloc(master, str, NULL);
+ if (rp->iop == NULL) {
+ (void) close(master);
+ (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+ return FALSE;
+ }
+
+ /*
+ * Force read and write ends of two-way connection to
+ * be different fd's so they can be closed independently.
+ */
+ if ((dup_master = dup(master)) < 0
+ || (rp->fp = fdopen(dup_master, "w")) == NULL) {
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ (void) close(master);
+ (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+ if (dup_master > 0)
+ (void) close(dup_master);
+ return FALSE;
+ }
+ rp->flag |= RED_PTY;
+ os_close_on_exec(master, str, "pipe", "from");
+ os_close_on_exec(dup_master, str, "pipe", "to");
+ first_pty_letter = '\0'; /* reset for next command */
+ return TRUE;
+ }
+#endif /* HAVE_TERMIOS_H */
+
+use_pipes:
+#ifndef PIPES_SIMULATED /* real pipes */
+ /* case 3: two way pipe to a child process */
+ {
+ int ptoc[2], ctop[2];
+ int pid;
+ int save_errno;
+#ifdef __EMX__
+ int save_stdout, save_stdin;
+#endif
+
+ if (pipe(ptoc) < 0)
+ return FALSE; /* errno set, diagnostic from caller */
+
+ if (pipe(ctop) < 0) {
+ save_errno = errno;
+ close(ptoc[0]);
+ close(ptoc[1]);
+ errno = save_errno;
+ return FALSE;
+ }
+
+#ifdef __EMX__
+ save_stdin = dup(0); /* duplicate stdin */
+ save_stdout = dup(1); /* duplicate stdout */
+
+ if (save_stdout == -1 || save_stdin == -1) {
+ /* if an error occurrs close all open file handles */
+ save_errno = errno;
+ if (save_stdin != -1)
+ close(save_stdin);
+ if (save_stdout != -1)
+ close(save_stdout);
+ close(ptoc[0]); close(ptoc[1]);
+ close(ctop[0]); close(ctop[1]);
+ errno = save_errno;
+ return FALSE;
+ }
+
+ /* connect pipes to stdin and stdout */
+ close(1); /* close stdout */
+ if (dup(ctop[1]) != 1) /* connect pipe input to stdout */
+ fatal(_("moving pipe to stdout in child failed (dup: %s)"), strerror(errno));
+
+ close(0); /* close stdin */
+ if (dup(ptoc[0]) != 0) /* connect pipe output to stdin */
+ fatal(_("moving pipe to stdin in child failed (dup: %s)"), strerror(errno));
+
+ /* none of these handles must be inherited by the child process */
+ (void) close(ptoc[0]); /* close pipe output, child will use stdin instead */
+ (void) close(ctop[1]); /* close pipe input, child will use stdout instead */
+
+ os_close_on_exec(ptoc[1], str, "pipe", "from"); /* pipe input: output of the parent process */
+ os_close_on_exec(ctop[0], str, "pipe", "from"); /* pipe output: input of the parent process */
+ os_close_on_exec(save_stdin, str, "pipe", "from"); /* saved stdin of the parent process */
+ os_close_on_exec(save_stdout, str, "pipe", "from"); /* saved stdout of the parent process */
+
+ /* stderr does NOT get dup'ed onto child's stdout */
+ pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", str, NULL);
+
+ /* restore stdin and stdout */
+ close(1);
+ if (dup(save_stdout) != 1)
+ fatal(_("restoring stdout in parent process failed\n"));
+ close(save_stdout);
+
+ close(0);
+ if (dup(save_stdin) != 0)
+ fatal(_("restoring stdin in parent process failed\n"));
+ close(save_stdin);
+
+ if (pid < 0) { /* spawnl() failed */
+ save_errno = errno;
+ close(ptoc[1]);
+ close(ctop[0]);
+
+ errno = save_errno;
+ return FALSE;
+ }
+
+#else /* NOT __EMX__ */
+ if ((pid = fork()) < 0) {
+ save_errno = errno;
+ close(ptoc[0]); close(ptoc[1]);
+ close(ctop[0]); close(ctop[1]);
+ errno = save_errno;
+ return FALSE;
+ }
+
+ if (pid == 0) { /* child */
+ if (close(1) == -1)
+ fatal(_("close of stdout in child failed (%s)"),
+ strerror(errno));
+ if (dup(ctop[1]) != 1)
+ fatal(_("moving pipe to stdout in child failed (dup: %s)"), strerror(errno));
+ if (close(0) == -1)
+ fatal(_("close of stdin in child failed (%s)"),
+ strerror(errno));
+ if (dup(ptoc[0]) != 0)
+ fatal(_("moving pipe to stdin in child failed (dup: %s)"), strerror(errno));
+ if ( close(ptoc[0]) == -1 || close(ptoc[1]) == -1
+ || close(ctop[0]) == -1 || close(ctop[1]) == -1)
+ fatal(_("close of pipe failed (%s)"), strerror(errno));
+ /* stderr does NOT get dup'ed onto child's stdout */
+ execl("/bin/sh", "sh", "-c", str, NULL);
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+#endif /* NOT __EMX__ */
+
+ /* parent */
+ rp->pid = pid;
+ rp->iop = iop_alloc(ctop[0], str, NULL);
+ if (rp->iop == NULL) {
+ (void) close(ctop[0]);
+ (void) close(ctop[1]);
+ (void) close(ptoc[0]);
+ (void) close(ptoc[1]);
+ (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+
+ return FALSE;
+ }
+ rp->fp = fdopen(ptoc[1], "w");
+ if (rp->fp == NULL) {
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ (void) close(ctop[0]);
+ (void) close(ctop[1]);
+ (void) close(ptoc[0]);
+ (void) close(ptoc[1]);
+ (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+
+ return FALSE;
+ }
+
+#ifndef __EMX__
+ os_close_on_exec(ctop[0], str, "pipe", "from");
+ os_close_on_exec(ptoc[1], str, "pipe", "from");
+
+ (void) close(ptoc[0]);
+ (void) close(ctop[1]);
+#endif
+
+ return TRUE;
+ }
+
+#else /*PIPES_SIMULATED*/
+
+ fatal(_("`|&' not supported"));
+ /*NOTREACHED*/
+ return FALSE;
+
+#endif
+}
+
+#ifndef PIPES_SIMULATED /* real pipes */
+
+/* wait_any --- wait for a child process, close associated pipe */
+
+static int
+wait_any(int interesting) /* pid of interest, if any */
+{
+ RETSIGTYPE (*hstat) P((int)), (*istat) P((int)), (*qstat) P((int));
+ int pid;
+ int status = 0;
+ struct redirect *redp;
+
+ hstat = signal(SIGHUP, SIG_IGN);
+ istat = signal(SIGINT, SIG_IGN);
+ qstat = signal(SIGQUIT, SIG_IGN);
+ for (;;) {
+#ifdef HAVE_SYS_WAIT_H /* Posix compatible sys/wait.h */
+ pid = wait(&status);
+#else
+ pid = wait((union wait *)&status);
+#endif /* NeXT */
+ if (interesting && pid == interesting) {
+ break;
+ } else if (pid != -1) {
+ for (redp = red_head; redp != NULL; redp = redp->next)
+ if (pid == redp->pid) {
+ redp->pid = -1;
+ redp->status = status;
+ break;
+ }
+ }
+ if (pid == -1 && errno == ECHILD)
+ break;
+ }
+ signal(SIGHUP, hstat);
+ signal(SIGINT, istat);
+ signal(SIGQUIT, qstat);
+ return status;
+}
+
+/* gawk_popen --- open an IOBUF on a child process */
+
+static IOBUF *
+gawk_popen(const char *cmd, struct redirect *rp)
+{
+ int p[2];
+ register int pid;
+#ifdef __EMX__
+ int save_stdout;
+#endif
+
+ /*
+ * used to wait for any children to synchronize input and output,
+ * but this could cause gawk to hang when it is started in a pipeline
+ * and thus has a child process feeding it input (shell dependant)
+ */
+ /*(void) wait_any(0);*/ /* wait for outstanding processes */
+
+ if (pipe(p) < 0)
+ fatal(_("cannot open pipe `%s' (%s)"), cmd, strerror(errno));
+
+#ifdef __EMX__
+ save_stdout = dup(1); /* save stdout */
+ rp->iop = NULL;
+ if (save_stdout == -1)
+ return rp->iop; /* failed */
+
+ close(1); /* close stdout */
+ if (dup(p[1]) != 1)
+ fatal(_("moving pipe to stdout in child failed (dup: %s)"), strerror(errno));
+
+ /* none of these handles must be inherited by the child process */
+ close(p[1]); /* close pipe input */
+
+ os_close_on_exec(p[0], cmd, "pipe", "from"); /* pipe output: input of the parent process */
+ os_close_on_exec(save_stdout, cmd, "pipe", "from"); /* saved stdout of the parent process */
+
+ pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", cmd, NULL);
+
+ /* restore stdout */
+ close(1);
+ if (dup(save_stdout) != 1)
+ fatal(_("restoring stdout in parent process failed\n"));
+ close(save_stdout);
+
+#else /* NOT __EMX__ */
+ if ((pid = fork()) == 0) {
+ if (close(1) == -1)
+ fatal(_("close of stdout in child failed (%s)"),
+ strerror(errno));
+ if (dup(p[1]) != 1)
+ fatal(_("moving pipe to stdout in child failed (dup: %s)"), strerror(errno));
+ if (close(p[0]) == -1 || close(p[1]) == -1)
+ fatal(_("close of pipe failed (%s)"), strerror(errno));
+ execl("/bin/sh", "sh", "-c", cmd, NULL);
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+#endif /* NOT __EMX__ */
+
+ if (pid == -1)
+ fatal(_("cannot create child process for `%s' (fork: %s)"), cmd, strerror(errno));
+ rp->pid = pid;
+#ifndef __EMX__
+ if (close(p[1]) == -1)
+ fatal(_("close of pipe failed (%s)"), strerror(errno));
+#endif
+ os_close_on_exec(p[0], cmd, "pipe", "from");
+ rp->iop = iop_alloc(p[0], cmd, NULL);
+ if (rp->iop == NULL)
+ (void) close(p[0]);
+
+ return rp->iop;
+}
+
+/* gawk_pclose --- close an open child pipe */
+
+static int
+gawk_pclose(struct redirect *rp)
+{
+ if (rp->iop != NULL)
+ (void) iop_close(rp->iop);
+ rp->iop = NULL;
+
+ /* process previously found, return stored status */
+ if (rp->pid == -1)
+ return rp->status;
+ rp->status = wait_any(rp->pid);
+ rp->pid = -1;
+ return rp->status;
+}
+
+#else /* PIPES_SIMULATED */
+
+/*
+ * use temporary file rather than pipe
+ * except if popen() provides real pipes too
+ */
+
+#if defined(VMS) || defined(OS2) || defined (MSDOS) || defined(WIN32) || defined(TANDEM) || defined(__EMX__)
+
+/* gawk_popen --- open an IOBUF on a child process */
+
+static IOBUF *
+gawk_popen(const char *cmd, struct redirect *rp)
+{
+ FILE *current;
+
+ os_restore_mode(fileno(stdin));
+ current = popen(cmd, binmode("r"));
+ if ((BINMODE & 1) != 0)
+ os_setbinmode(fileno(stdin), O_BINARY);
+ if (current == NULL)
+ return NULL;
+ os_close_on_exec(fileno(current), cmd, "pipe", "from");
+ rp->iop = iop_alloc(fileno(current), cmd, NULL);
+ if (rp->iop == NULL) {
+ (void) pclose(current);
+ current = NULL;
+ }
+ rp->ifp = current;
+ return rp->iop;
+}
+
+/* gawk_pclose --- close an open child pipe */
+
+static int
+gawk_pclose(struct redirect *rp)
+{
+ int rval, aval, fd = rp->iop->fd;
+
+ if (rp->iop != NULL) {
+ rp->iop->fd = dup(fd); /* kludge to allow close() + pclose() */
+ rval = iop_close(rp->iop);
+ }
+ rp->iop = NULL;
+ aval = pclose(rp->ifp);
+ rp->ifp = NULL;
+ return (rval < 0 ? rval : aval);
+}
+#else /* not (VMS || OS2 || MSDOS || TANDEM) */
+
+static struct pipeinfo {
+ char *command;
+ char *name;
+} pipes[_NFILE];
+
+/* gawk_popen --- open an IOBUF on a child process */
+
+static IOBUF *
+gawk_popen(const char *cmd, struct redirect *rp)
+{
+ int current;
+ char *name;
+ static char cmdbuf[256];
+
+ /* get a name to use */
+ if ((name = tempnam(".", "pip")) == NULL)
+ return NULL;
+ sprintf(cmdbuf, "%s > %s", cmd, name);
+ system(cmdbuf);
+ if ((current = open(name, O_RDONLY)) == INVALID_HANDLE)
+ return NULL;
+ pipes[current].name = name;
+ emalloc(pipes[current].command, char *, strlen(cmd)+1, "gawk_popen");
+ strcpy(pipes[current].command, cmd);
+ os_close_on_exec(current, cmd, "pipe", "from");
+ rp->iop = iop_alloc(current, name, NULL);
+ if (rp->iop == NULL)
+ (void) close(current);
+ return rp->iop;
+}
+
+/* gawk_pclose --- close an open child pipe */
+
+static int
+gawk_pclose(struct redirect *rp)
+{
+ int cur = rp->iop->fd;
+ int rval = 0;
+
+ if (rp->iop != NULL)
+ rval = iop_close(rp->iop);
+ rp->iop = NULL;
+
+ /* check for an open file */
+ if (pipes[cur].name == NULL)
+ return -1;
+ unlink(pipes[cur].name);
+ free(pipes[cur].name);
+ pipes[cur].name = NULL;
+ free(pipes[cur].command);
+ return rval;
+}
+#endif /* not (VMS || OS2 || MSDOS || TANDEM) */
+
+#endif /* PIPES_SIMULATED */
+
+/* do_getline --- read in a line, into var and with redirection, as needed */
+
+NODE *
+do_getline(NODE *tree)
+{
+ struct redirect *rp = NULL;
+ IOBUF *iop;
+ int cnt = EOF;
+ char *s = NULL;
+ int errcode;
+
+ while (cnt == EOF) {
+ if (tree->rnode == NULL) { /* no redirection */
+ iop = nextfile(FALSE);
+ if (iop == NULL) /* end of input */
+ return tmp_number((AWKNUM) 0.0);
+ } else {
+ int redir_error = 0;
+
+ rp = redirect(tree->rnode, &redir_error);
+ if (rp == NULL && redir_error) { /* failed redirect */
+ if (! do_traditional)
+ update_ERRNO_saved(redir_error);
+
+ return tmp_number((AWKNUM) -1.0);
+ }
+ iop = rp->iop;
+ if (iop == NULL) /* end of input */
+ return tmp_number((AWKNUM) 0.0);
+ }
+ errcode = 0;
+ cnt = get_a_record(&s, iop, &errcode);
+ if (errcode != 0) {
+ if (! do_traditional && (errcode != -1))
+ update_ERRNO_saved(errcode);
+
+ return tmp_number((AWKNUM) -1.0);
+ }
+ if (cnt == EOF) {
+ if (rp != NULL) {
+ /*
+ * Don't do iop_close() here if we are
+ * reading from a pipe; otherwise
+ * gawk_pclose will not be called.
+ */
+ if ((rp->flag & (RED_PIPE|RED_TWOWAY)) == 0) {
+ (void) iop_close(iop);
+ rp->iop = NULL;
+ }
+ rp->flag |= RED_EOF; /* sticky EOF */
+ return tmp_number((AWKNUM) 0.0);
+ } else
+ continue; /* try another file */
+ }
+ if (rp == NULL) {
+ NR++;
+ FNR++;
+ }
+ if (tree->lnode == NULL) /* no optional var. */
+ set_record(s, cnt);
+ else { /* assignment to variable */
+ Func_ptr after_assign = NULL;
+ NODE **lhs;
+
+ lhs = get_lhs(tree->lnode, &after_assign, FALSE);
+ unref(*lhs);
+ *lhs = make_string(s, cnt);
+ (*lhs)->flags |= MAYBE_NUM;
+ /* we may have to regenerate $0 here! */
+ if (after_assign != NULL)
+ (*after_assign)();
+ }
+ }
+ return tmp_number((AWKNUM) 1.0);
+}
+
+/* pathopen --- pathopen with default file extension handling */
+
+int
+pathopen(const char *file)
+{
+ int fd = do_pathopen(file);
+
+#ifdef DEFAULT_FILETYPE
+ if (! do_traditional && fd <= INVALID_HANDLE) {
+ char *file_awk;
+ int save = errno;
+#ifdef VMS
+ int vms_save = vaxc$errno;
+#endif
+
+ /* append ".awk" and try again */
+ emalloc(file_awk, char *, strlen(file) +
+ sizeof(DEFAULT_FILETYPE) + 1, "pathopen");
+ sprintf(file_awk, "%s%s", file, DEFAULT_FILETYPE);
+ fd = do_pathopen(file_awk);
+ free(file_awk);
+ if (fd <= INVALID_HANDLE) {
+ errno = save;
+#ifdef VMS
+ vaxc$errno = vms_save;
+#endif
+ }
+ }
+#endif /*DEFAULT_FILETYPE*/
+
+ return fd;
+}
+
+/* do_pathopen --- search $AWKPATH for source file */
+
+static int
+do_pathopen(const char *file)
+{
+ static const char *savepath = NULL;
+ static int first = TRUE;
+ const char *awkpath;
+ char *cp, *trypath;
+ int fd;
+ int len;
+
+ if (STREQ(file, "-"))
+ return 0;
+
+ if (do_traditional)
+ return devopen(file, "r");
+
+ if (first) {
+ first = FALSE;
+ if ((awkpath = getenv("AWKPATH")) != NULL && *awkpath)
+ savepath = awkpath; /* used for restarting */
+ else
+ savepath = defpath;
+ }
+ awkpath = savepath;
+
+ /* some kind of path name, no search */
+ if (ispath(file))
+ return devopen(file, "r");
+
+ /* no arbitrary limits: */
+ len = strlen(awkpath) + strlen(file) + 2;
+ emalloc(trypath, char *, len, "do_pathopen");
+
+ do {
+ trypath[0] = '\0';
+
+ for (cp = trypath; *awkpath && *awkpath != envsep; )
+ *cp++ = *awkpath++;
+
+ if (cp != trypath) { /* nun-null element in path */
+ /* add directory punctuation only if needed */
+ if (! isdirpunct(*(cp-1)))
+ *cp++ = '/';
+ /* append filename */
+ strcpy(cp, file);
+ } else
+ strcpy(trypath, file);
+ if ((fd = devopen(trypath, "r")) > INVALID_HANDLE) {
+ free(trypath);
+ return fd;
+ }
+
+ /* no luck, keep going */
+ if(*awkpath == envsep && awkpath[1] != '\0')
+ awkpath++; /* skip colon */
+ } while (*awkpath != '\0');
+ free(trypath);
+
+ /*
+ * You might have one of the awk paths defined, WITHOUT the current
+ * working directory in it. Therefore try to open the file in the
+ * current directory.
+ */
+ return devopen(file, "r");
+}
+
+#ifdef TEST
+int bufsize = 8192;
+
+void
+fatal(const char *s)
+{
+ printf("%s\n", s);
+ exit(1);
+}
+#endif
+
+/* open hooks, mainly for use by extension functions */
+
+static struct open_hook {
+ struct open_hook *next;
+ void *(*open_func)(IOBUF *);
+} *open_hooks;
+
+/* register_open_hook --- add an open hook to the list */
+
+void
+register_open_hook(void *(*open_func)(IOBUF *))
+{
+ struct open_hook *oh;
+
+ emalloc(oh, struct open_hook *, sizeof(*oh), "register_open_hook");
+ oh->open_func = open_func;
+ oh->next = open_hooks;
+ open_hooks = oh;
+}
+
+/* iop_alloc --- allocate an IOBUF structure for an open fd */
+
+static IOBUF *
+iop_alloc(int fd, const char *name, IOBUF *iop)
+{
+ struct stat sbuf;
+ struct open_hook *oh;
+
+ if (iop == NULL)
+ emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
+ memset(iop, '\0', sizeof(IOBUF));
+ iop->flag = 0;
+ iop->fd = fd;
+ iop->name = name;
+
+ /* walk through open hooks, stop at first one that responds */
+ for (oh = open_hooks; oh != NULL; oh = oh->next) {
+ if ((iop->opaque = (*oh->open_func)(iop)) != NULL)
+ break;
+ }
+
+ if (iop->fd == INVALID_HANDLE) {
+ free(iop);
+ return NULL;
+ }
+ if (isatty(iop->fd))
+ iop->flag |= IOP_IS_TTY;
+ iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf);
+ iop->sbuf = sbuf;
+ if (do_lint && S_ISREG(sbuf.st_mode) && sbuf.st_size == 0)
+ lintwarn(_("data file `%s' is empty"), name);
+ errno = 0;
+ iop->count = iop->scanoff = 0;
+ emalloc(iop->buf, char *, iop->size += 2, "iop_alloc");
+ iop->off = iop->buf;
+ iop->dataend = NULL;
+ iop->end = iop->buf + iop->size;
+ iop->flag |= IOP_AT_START;
+ return iop;
+}
+
+#define set_RT_to_null() \
+ (void)(! do_traditional && (unref(RT_node->var_value), \
+ RT_node->var_value = Nnull_string))
+
+#define set_RT(str, len) \
+ (void)(! do_traditional && (unref(RT_node->var_value), \
+ RT_node->var_value = make_string(str, len)))
+
+/* grow must increase size of buffer, set end, make sure off and dataend point at */
+/* right spot. */
+/* */
+/* */
+/* <growbuffer>= */
+/* grow_iop_buffer --- grow the buffer */
+
+static void
+grow_iop_buffer(IOBUF *iop)
+{
+ size_t valid = iop->dataend - iop->off;
+ size_t off = iop->off - iop->buf;
+ size_t newsize;
+
+ /*
+ * Lop off original extra two bytes, double the size,
+ * add them back.
+ */
+ newsize = ((iop->size - 2) * 2) + 2;
+
+ /* Check for overflow */
+ if (newsize <= iop->size)
+ fatal(_("could not allocate more input memory"));
+
+ /* Make sure there's room for a disk block */
+ if (newsize - valid < iop->readsize)
+ newsize += iop->readsize + 2;
+
+ /* Check for overflow, again */
+ if (newsize <= iop->size)
+ fatal(_("could not allocate more input memory"));
+
+ iop->size = newsize;
+ erealloc(iop->buf, char *, iop->size, "grow_iop_buffer");
+ iop->off = iop->buf + off;
+ iop->dataend = iop->off + valid;
+ iop->end = iop->buf + iop->size;
+}
+
+/* Here are the routines. */
+/* */
+/* */
+/* <rs1scan>= */
+/* rs1scan --- scan for a single character record terminator */
+
+static RECVALUE
+rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
+{
+ register char *bp;
+ register char rs;
+#ifdef MBS_SUPPORT
+ size_t mbclen = 0;
+ mbstate_t mbs;
+#endif
+
+ memset(recm, '\0', sizeof(struct recmatch));
+ rs = RS->stptr[0];
+ *(iop->dataend) = rs; /* set sentinel */
+ recm->start = iop->off; /* beginning of record */
+
+ bp = iop->off;
+ if (*state == INDATA) /* skip over data we've already seen */
+ bp += iop->scanoff;
+
+#ifdef MBS_SUPPORT
+ /*
+ * From: Bruno Haible <bruno@clisp.org>
+ * To: Aharon Robbins <arnold@skeeve.com>, gnits@gnits.org
+ * Subject: Re: multibyte locales: any way to find if a character isn't multibyte?
+ * Date: Mon, 23 Jun 2003 12:20:16 +0200
+ * Cc: isamu@yamato.ibm.com
+ *
+ * Hi,
+ *
+ * > Is there any way to make the following query to the current locale?
+ * >
+ * > Given an 8-bit value, can this value ever appear as part of
+ * > a multibyte character?
+ *
+ * There is no simple answer here. The easiest solution I see is to
+ * get the current locale's codeset (via locale_charset() which is a
+ * wrapper around nl_langinfo(CODESET)), and then perform a case-by-case
+ * treatment of the known multibyte encodings, from GB2312 to EUC-JISX0213;
+ * for the unibyte encodings, a single btowc() call will tell you.
+ *
+ * > This is particularly critical for me for ASCII newline ('\n'). If I
+ * > can be guaranteed that it never shows up as part of a multibyte character,
+ * > I can speed up gawk considerably in mulitbyte locales.
+ *
+ * This is much simpler to answer!
+ * In all ASCII based multibyte encodings used for locales today (this
+ * excludes EBCDIC based doublebyte encodings from IBM, and also excludes
+ * ISO-2022-JP which is used for email exchange but not as a locale encoding)
+ * ALL bytes in the range 0x00..0x2F occur only as a single character, not
+ * as part of a multibyte character.
+ *
+ * So it's safe to assume, but deserves a comment in the source.
+ *
+ * Bruno
+ ***************************************************************
+ * From: Bruno Haible <bruno@clisp.org>
+ * To: Aharon Robbins <arnold@skeeve.com>
+ * Subject: Re: multibyte locales: any way to find if a character isn't multibyte?
+ * Date: Mon, 23 Jun 2003 14:27:49 +0200
+ *
+ * On Monday 23 June 2003 14:11, you wrote:
+ *
+ * > if (rs != '\n' && MB_CUR_MAX > 1) {
+ *
+ * If you assume ASCII, you can even write
+ *
+ * if (rs >= 0x30 && MB_CUR_MAX > 1) {
+ *
+ * (this catches also the space character) but if portability to EBCDIC
+ * systems is desired, your code is fine as is.
+ *
+ * Bruno
+ */
+ /* Thus, the check for \n here; big speedup ! */
+ if (rs != '\n' && gawk_mb_cur_max > 1) {
+ int len = iop->dataend - bp;
+ int found = 0;
+ memset(&mbs, 0, sizeof(mbstate_t));
+ do {
+ if (*bp == rs)
+ found = 1;
+ mbclen = mbrlen(bp, len, &mbs);
+ if ((mbclen == 1) || (mbclen == (size_t) -1)
+ || (mbclen == (size_t) -2) || (mbclen == 0)) {
+ /* We treat it as a singlebyte character. */
+ mbclen = 1;
+ }
+ len -= mbclen;
+ bp += mbclen;
+ } while (len > 0 && ! found);
+
+ /* Check that newline found isn't the sentinel. */
+ if (found && (bp - mbclen) < iop->dataend) {
+ /*
+ * set len to what we have so far, in case this is
+ * all there is
+ */
+ recm->len = bp - recm->start - mbclen;
+ recm->rt_start = bp - mbclen;
+ recm->rt_len = mbclen;
+ *state = NOSTATE;
+ return REC_OK;
+ } else {
+ /* also set len */
+ recm->len = bp - recm->start;
+ *state = INDATA;
+ iop->scanoff = bp - iop->off;
+ return NOTERM;
+ }
+ }
+#endif
+ while (*bp != rs)
+ bp++;
+
+ /* set len to what we have so far, in case this is all there is */
+ recm->len = bp - recm->start;
+
+ if (bp < iop->dataend) { /* found it in the buffer */
+ recm->rt_start = bp;
+ recm->rt_len = 1;
+ *state = NOSTATE;
+ return REC_OK;
+ } else {
+ *state = INDATA;
+ iop->scanoff = bp - iop->off;
+ return NOTERM;
+ }
+}
+
+/* <rsrescan>= */
+/* rsrescan --- search for a regex match in the buffer */
+
+static RECVALUE
+rsrescan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
+{
+ register char *bp;
+ size_t restart = 0, reend = 0;
+ Regexp *RSre = RS_regexp;
+ int regex_flags = RE_NEED_START;
+
+ memset(recm, '\0', sizeof(struct recmatch));
+ recm->start = iop->off;
+
+ bp = iop->off;
+ if (*state == INDATA)
+ bp += iop->scanoff;
+
+ if ((iop->flag & IOP_AT_START) == 0)
+ regex_flags |= RE_NO_BOL;
+again:
+ /* case 1, no match */
+ if (research(RSre, bp, 0, iop->dataend - bp, regex_flags) == -1) {
+ /* set len, in case this all there is. */
+ recm->len = iop->dataend - iop->off;
+ return NOTERM;
+ }
+
+ /* ok, we matched within the buffer, set start and end */
+ restart = RESTART(RSre, iop->off);
+ reend = REEND(RSre, iop->off);
+
+ /* case 2, null regex match, grow buffer, try again */
+ if (restart == reend) {
+ *state = INDATA;
+ iop->scanoff = reend + 1;
+ /*
+ * If still room in buffer, skip over null match
+ * and restart search. Otherwise, return.
+ */
+ if (bp + iop->scanoff < iop->dataend) {
+ bp += iop->scanoff;
+ goto again;
+ }
+ recm->len = (bp - iop->off) + restart;
+ return NOTERM;
+ }
+
+ /*
+ * At this point, we have a non-empty match.
+ *
+ * First, fill in rest of data. The rest of the cases return
+ * a record and terminator.
+ */
+ recm->len = restart;
+ recm->rt_start = bp + restart;
+ recm->rt_len = reend - restart;
+ *state = NOSTATE;
+
+ /*
+ * 3. Match exactly at end:
+ * if re is a simple string match
+ * found a simple string match at end, return REC_OK
+ * else
+ * grow buffer, add more data, try again
+ * fi
+ */
+ if (iop->off + reend >= iop->dataend) {
+ if (reisstring(RS->stptr, RS->stlen, RSre, iop->off))
+ return REC_OK;
+ else
+ return TERMATEND;
+ }
+
+ /*
+ * 4. Match within xxx bytes of end & maybe islong re:
+ * return TERMNEAREND
+ */
+
+ /*
+ * case 4, match succeeded, but there may be more in
+ * the next input buffer.
+ *
+ * Consider an RS of xyz(abc)? where the
+ * exact end of the buffer is xyza and the
+ * next two, unread, characters are bc.
+ *
+ * This matches the "xyz" and ends up putting the
+ * "abc" into the front of the next record. Ooops.
+ *
+ * The remaybelong() function looks to see if the
+ * regex contains one of: + * ? |. This is a very
+ * simple heuristic, but in combination with the
+ * "end of match within a few bytes of end of buffer"
+ * check, should keep things reasonable.
+ */
+
+ /*
+ * XXX: The reisstring and remaybelong tests should
+ * really be done once when RS is assigned to and
+ * then tested as flags here. Maybe one day.
+ */
+
+ /* succession of tests is easier to trace in GDB. */
+ if (remaybelong(RS->stptr, RS->stlen)) {
+ char *matchend = iop->off + reend;
+
+ if (iop->dataend - matchend < RS->stlen)
+ return TERMNEAREND;
+ }
+
+ return REC_OK;
+}
+
+/* <rsnullscan>= */
+/* rsnullscan --- handle RS = "" */
+
+static RECVALUE
+rsnullscan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
+{
+ register char *bp;
+
+ if (*state == NOSTATE || *state == INLEADER)
+ memset(recm, '\0', sizeof(struct recmatch));
+
+ recm->start = iop->off;
+
+ bp = iop->off;
+ if (*state != NOSTATE)
+ bp += iop->scanoff;
+
+ /* set sentinel */
+ *(iop->dataend) = '\n';
+
+ if (*state == INTERM)
+ goto find_longest_terminator;
+ else if (*state == INDATA)
+ goto scan_data;
+ /* else
+ fall into things from beginning,
+ either NOSTATE or INLEADER */
+
+/* skip_leading: */
+ /* leading newlines are ignored */
+ while (*bp == '\n' && bp < iop->dataend)
+ bp++;
+
+ if (bp >= iop->dataend) { /* LOTS of leading newlines, sheesh. */
+ *state = INLEADER;
+ iop->scanoff = bp - iop->off;
+ return NOTERM;
+ }
+
+ iop->off = recm->start = bp; /* real start of record */
+scan_data:
+ while (*bp++ != '\n')
+ continue;
+
+ if (bp >= iop->dataend) { /* no terminator */
+ iop->scanoff = recm->len = bp - iop->off - 1;
+ *state = INDATA;
+ return NOTERM;
+ }
+
+ /* found one newline before end of buffer, check next char */
+ if (*bp != '\n')
+ goto scan_data;
+
+ /* we've now seen at least two newlines */
+ *state = INTERM;
+ recm->len = bp - iop->off - 1;
+ recm->rt_start = bp - 1;
+
+find_longest_terminator:
+ /* find as many newlines as we can, to set RT */
+ while (*bp == '\n' && bp < iop->dataend)
+ bp++;
+
+ recm->rt_len = bp - recm->rt_start;
+ iop->scanoff = bp - iop->off;
+
+ if (bp >= iop->dataend)
+ return TERMATEND;
+
+ return REC_OK;
+}
+
+/* <getarecord>= */
+/* get_a_record --- read a record from IOP into out, return length of EOF, set RT */
+
+int
+get_a_record(char **out, /* pointer to pointer to data */
+ IOBUF *iop, /* input IOP */
+ int *errcode) /* pointer to error variable */
+{
+ struct recmatch recm;
+ SCANSTATE state;
+ RECVALUE ret;
+ int retval;
+ NODE *rtval = NULL;
+ static RECVALUE (*lastmatchrec)P((IOBUF *iop, struct recmatch *recm, SCANSTATE *state)) = NULL;
+
+ if (at_eof(iop) && no_data_left(iop))
+ return EOF;
+
+ if (iop->get_record != NULL)
+ return (*iop->get_record)(out, iop, errcode);
+
+ /* <fill initial buffer>= */
+ if (has_no_data(iop) || no_data_left(iop)) {
+ iop->count = read(iop->fd, iop->buf, iop->readsize);
+ if (iop->count == 0) {
+ iop->flag |= IOP_AT_EOF;
+ return EOF;
+ } else if (iop->count == -1) {
+ if (! do_traditional && errcode != NULL) {
+ *errcode = errno;
+ iop->flag |= IOP_AT_EOF;
+ return EOF;
+ } else
+ fatal(_("error reading input file `%s': %s"),
+ iop->name, strerror(errno));
+ } else {
+ iop->dataend = iop->buf + iop->count;
+ iop->off = iop->buf;
+ }
+ }
+
+
+
+ /* <loop through file to find a record>= */
+ state = NOSTATE;
+ for (;;) {
+ size_t dataend_off;
+
+ ret = (*matchrec)(iop, & recm, & state);
+
+ iop->flag &= ~IOP_AT_START;
+
+ if (ret == REC_OK)
+ break;
+
+ /* need to add more data to buffer */
+ /* <shift data down in buffer>= */
+ dataend_off = iop->dataend - iop->off;
+ memmove(iop->buf, iop->off, dataend_off);
+ iop->off = iop->buf;
+ iop->dataend = iop->buf + dataend_off;
+
+ /* <adjust recm contents>= */
+ recm.start = iop->off;
+ if (recm.rt_start != NULL)
+ recm.rt_start = iop->off + recm.len;
+
+ /* <read more data, break if EOF>= */
+ if ((iop->flag & IOP_IS_INTERNAL) != 0) {
+ iop->flag |= IOP_AT_EOF;
+ break;
+ } else {
+#define min(x, y) (x < y ? x : y)
+ /* subtract one in read count to leave room for sentinel */
+ size_t room_left = iop->end - iop->dataend - 1;
+ size_t amt_to_read = min(iop->readsize, room_left);
+
+ if (amt_to_read < iop->readsize) {
+ grow_iop_buffer(iop);
+ /* <adjust recm contents>= */
+ recm.start = iop->off;
+ if (recm.rt_start != NULL)
+ recm.rt_start = iop->off + recm.len;
+
+ /* recalculate amt_to_read */
+ room_left = iop->end - iop->dataend - 1;
+ amt_to_read = min(iop->readsize, room_left);
+ }
+ while (amt_to_read + iop->readsize < room_left)
+ amt_to_read += iop->readsize;
+
+ iop->count = read(iop->fd, iop->dataend, amt_to_read);
+ if (iop->count == -1) {
+ if (! do_traditional && errcode != NULL) {
+ *errcode = errno;
+ iop->flag |= IOP_AT_EOF;
+ break;
+ } else
+ fatal(_("error reading input file `%s': %s"),
+ iop->name, strerror(errno));
+ } else if (iop->count == 0) {
+ /*
+ * hit EOF before matching RS, so end
+ * the record and set RT to ""
+ */
+ iop->flag |= IOP_AT_EOF;
+ break;
+ } else
+ iop->dataend += iop->count;
+ }
+
+
+ }
+
+
+
+ /* <set record, RT, return right value>= */
+
+ /*
+ * rtval is not a static pointer to avoid dangling pointer problems
+ * in case awk code assigns to RT. A remote possibility, to be sure,
+ * but Bitter Experience teaches us not to make ``that'll never
+ * happen'' kinds of assumptions.
+ */
+ rtval = RT_node->var_value;
+
+ if (recm.rt_len == 0) {
+ set_RT_to_null();
+ lastmatchrec = NULL;
+ } else {
+ assert(recm.rt_start != NULL);
+ /*
+ * Optimization. For rs1 case, don't set RT if
+ * character is same as last time. This knocks a
+ * chunk of time off something simple like
+ *
+ * gawk '{ print }' /some/big/file
+ *
+ * Similarly, for rsnull case, if length of new RT is
+ * shorter than current RT, just bump length down in RT.
+ *
+ * Make sure that matchrec didn't change since the last
+ * check. (Ugh, details, details, details.)
+ */
+ if (lastmatchrec == NULL || lastmatchrec != matchrec) {
+ lastmatchrec = matchrec;
+ set_RT(recm.rt_start, recm.rt_len);
+ } else if (matchrec == rs1scan) {
+ if (rtval->stlen != 1 || rtval->stptr[0] != recm.rt_start[0])
+ set_RT(recm.rt_start, recm.rt_len);
+ /* else
+ leave it alone */
+ } else if (matchrec == rsnullscan) {
+ if (rtval->stlen <= recm.rt_len)
+ rtval->stlen = recm.rt_len;
+ else
+ set_RT(recm.rt_start, recm.rt_len);
+ } else
+ set_RT(recm.rt_start, recm.rt_len);
+ }
+
+ if (recm.len == 0) {
+ *out = NULL;
+ retval = 0;
+ } else {
+ assert(recm.start != NULL);
+ *out = recm.start;
+ retval = recm.len;
+ }
+
+ iop->off += recm.len + recm.rt_len;
+
+ if (recm.len == 0 && recm.rt_len == 0 && at_eof(iop))
+ return EOF;
+ else
+ return retval;
+
+}
+
+/* set_RS --- update things as appropriate when RS is set */
+
+void
+set_RS()
+{
+ static NODE *save_rs = NULL;
+
+ /*
+ * Don't use cmp_nodes(), which pays attention to IGNORECASE.
+ */
+ if (save_rs
+ && RS_node->var_value->stlen == save_rs->stlen
+ && memcmp(RS_node->var_value->stptr, save_rs->stptr, save_rs->stlen) == 0) {
+ /*
+ * It could be that just IGNORECASE changed. If so,
+ * update the regex and then do the same for FS.
+ * set_IGNORECASE() relies on this routine to call
+ * set_FS().
+ */
+ RS_regexp = (IGNORECASE ? RS_re_no_case : RS_re_yes_case);
+ goto set_FS;
+ }
+ unref(save_rs);
+ save_rs = dupnode(RS_node->var_value);
+ RS_is_null = FALSE;
+ RS = force_string(RS_node->var_value);
+ if (RS_regexp != NULL) {
+ refree(RS_re_yes_case);
+ refree(RS_re_no_case);
+ RS_re_yes_case = RS_re_no_case = RS_regexp = NULL;
+ }
+ if (RS->stlen == 0) {
+ RS_is_null = TRUE;
+ matchrec = rsnullscan;
+ } else if (RS->stlen > 1) {
+ static int warned = FALSE;
+
+ RS_re_yes_case = make_regexp(RS->stptr, RS->stlen, FALSE, TRUE);
+ RS_re_no_case = make_regexp(RS->stptr, RS->stlen, TRUE, TRUE);
+ RS_regexp = (IGNORECASE ? RS_re_no_case : RS_re_yes_case);
+
+ matchrec = rsrescan;
+
+ if (do_lint && ! warned) {
+ lintwarn(_("multicharacter value of `RS' is a gawk extension"));
+ warned = TRUE;
+ }
+ } else
+ matchrec = rs1scan;
+set_FS:
+ if (! using_fieldwidths())
+ set_FS();
+}
+
+/* pty_vs_pipe --- return true if should use pty instead of pipes for `|&' */
+
+/*
+ * This works by checking if PROCINFO["command", "pty"] exists and is true.
+ */
+
+static int
+pty_vs_pipe(const char *command)
+{
+#ifdef HAVE_TERMIOS_H
+ char *full_index;
+ size_t full_len;
+ NODE *val;
+ NODE *sub;
+
+ if (PROCINFO_node == NULL)
+ return FALSE;
+
+ full_len = strlen(command)
+ + SUBSEP_node->var_value->stlen
+ + 3 /* strlen("pty") */
+ + 1; /* string terminator */
+ emalloc(full_index, char *, full_len, "pty_vs_pipe");
+ sprintf(full_index, "%s%.*spty", command,
+ (int) SUBSEP_node->var_value->stlen, SUBSEP_node->var_value->stptr);
+
+ sub = tmp_string(full_index, strlen(full_index));
+ val = in_array(PROCINFO_node, sub);
+ free_temp(sub);
+ free(full_index);
+
+ if (val) {
+ if (val->flags & MAYBE_NUM)
+ (void) force_number(val);
+ if (val->flags & NUMBER)
+ return (val->numbr != 0.0);
+ else
+ return (val->stlen != 0);
+ }
+#endif /* HAVE_TERMIOS_H */
+ return FALSE;
+}
+
+/* iopflags2str --- make IOP flags printable */
+
+const char *
+iopflags2str(int flag)
+{
+ static const struct flagtab values[] = {
+ { IOP_IS_TTY, "IOP_IS_TTY" },
+ { IOP_IS_INTERNAL, "IOP_IS_INTERNAL" },
+ { IOP_NO_FREE, "IOP_NO_FREE" },
+ { IOP_NOFREE_OBJ, "IOP_NOFREE_OBJ" },
+ { IOP_AT_EOF, "IOP_AT_EOF" },
+ { IOP_CLOSED, "IOP_CLOSED" },
+ { IOP_AT_START, "IOP_AT_START" },
+ { 0, NULL }
+ };
+
+ return genflags2str(flag, values);
+}
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Wed Jul 6 17:05:32 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gettext.m4: Per Bruno Haible, revert the change for the test
+ for locale.h from Sergey Poznyakoff.
+
+Wed Jun 8 20:45:17 2005 Sergey Poznyakoff <gray@Mirddin.farlep.net>
+
+ * gettext.m4: Move test for locale.h and LC_MESSAGES in AM_GNU_GETTEXT.
+ Makes things work when the library is external.
+
+Mon May 30 21:31:43 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * intmax_t.m4: Updated macro for intmax_t from Jim Meyering.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+2004-02-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * po.m4: Upgrade to gettext-0.14.1.
+
+2004-01-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * gettext.m4: Upgrade to gettext-0.13.1.
+ * intmax.m4: New file, from gettext-0.13.1.
+ * lib-ld.m4: Upgrade to gettext-0.13.1.
+ * lib-prefix.m4: Upgrade to gettext-0.13.1.
+ * longdouble.m4: New file, from gettext-0.13.1.
+ * longlong.m4: Upgrade to gettext-0.13.1.
+ * po.m4: Upgrade to gettext-0.13.1.
+ * printf-posix.m4: New file, from gettext-0.13.1.
+ * signed.m4: New file, from gettext-0.13.1.
+ * size_max.m4: New file, from gettext-0.13.1.
+ * ulonglong.m4: Upgrade to gettext-0.13.1.
+ * wchar_t.m4: New file, from gettext-0.13.1.
+ * wint_t.m4: New file, from gettext-0.13.1.
+ * xsize.m4: New file, from gettext-0.13.1.
+ * Makefile.am: New file.
+
+Thu Jan 15 15:51:12 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * m4/arch.m4, m4/socket.m4, m4/strtod.m4: Quoting fixed for automake 1.8.x.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+2003-06-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * gettext.m4: Upgrade to gettext-0.12.1.
+ * inttypes_h.m4: Upgrade to gettext-0.12.1.
+ * lib-ld.m4: Upgrade to gettext-0.12.1.
+ * lib-link.m4: Upgrade to gettext-0.12.1.
+ * lib-prefix.m4: Upgrade to gettext-0.12.1.
+ * nls.m4: New file, from gettext-0.12.1.
+ * po.m4: New file, from gettext-0.12.1.
+ * progtest.m4: Upgrade to gettext-0.12.1.
+ * stdint_h.m4: Upgrade to gettext-0.12.1.
+ * uintmax_t.m4: New file, from gettext-0.12.1.
+ * ulonglong.m4: New file, from gettext-0.12.1.
+ * Makefile.am: New file.
+
+2003-03-26 Paul Eggert <eggert@twinsun.com>
+
+ * longlong.m4, intmax_t.m4: New files.
+ * ulonglong.m4, uintmax_t.m4: Removed.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Wed Nov 20 13:15:59 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * arch.m4 (GAWK_AIX_TWEAK): Add -DGAWK_AIX for use in
+ io.c to get real pipes. Ugh.
+ Change test to -d /lpp so it actually works. Sigh.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+2002-04-28 gettextize <bug-gnu-gettext@gnu.org>
+
+ * gettext.m4: Upgrade to gettext-0.11.2.
+ * isc-posix.m4: Upgrade to gettext-0.11.2.
+ * lib-link.m4: Upgrade to gettext-0.11.2.
+
+2002-04-09 gettextize <bug-gnu-gettext@gnu.org>
+
+ * gettext.m4: Upgrade to gettext-0.11.1.
+
--- /dev/null
+dnl
+dnl arch.m4 --- autoconf input file for gawk
+dnl
+dnl Copyright (C) 1995, 1996, 1998, 1999, 2000, 2003, 2004 the Free Software Foundation, Inc.
+dnl
+dnl This file is part of GAWK, the GNU implementation of the
+dnl AWK Progamming Language.
+dnl
+dnl GAWK is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl GAWK is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+dnl
+
+dnl Check for AIX and add _XOPEN_SOURCE_EXTENDED
+AC_DEFUN([GAWK_AC_AIX_TWEAK], [
+AC_MSG_CHECKING([for AIX compilation hacks])
+AC_CACHE_VAL(gawk_cv_aix_hack, [
+if test -d /lpp
+then
+ CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=1 -DGAWK_AIX=1"
+ gawk_cv_aix_hack=yes
+else
+ gawk_cv_aix_hack=no
+fi
+])dnl
+AC_MSG_RESULT([${gawk_cv_aix_hack}])
+])dnl
+
+dnl Check for Alpha Linux systems
+AC_DEFUN([GAWK_AC_LINUX_ALPHA], [
+AC_MSG_CHECKING([for Linux/Alpha compilation hacks])
+AC_CACHE_VAL(gawk_cv_linux_alpha_hack, [
+if test "Linux" = "`uname`" && test "alpha" = "`uname -m`"
+then
+ # this isn't necessarily always true,
+ # the vendor's compiler is also often found
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -mieee"
+ gawk_cv_linux_alpha_hack=yes
+ else
+ gawk_cv_linux_alpha_hack=no
+ fi
+else
+ gawk_cv_linux_alpha_hack=no
+fi
+])dnl
+AC_MSG_RESULT([${gawk_cv_linux_alpha_hack}])
+])dnl
--- /dev/null
+# codeset.m4 serial AM1 (gettext-0.10.40)
+dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_LANGINFO_CODESET],
+[
+ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
+ [AC_TRY_LINK([#include <langinfo.h>],
+ [char* cs = nl_langinfo(CODESET);],
+ am_cv_langinfo_codeset=yes,
+ am_cv_langinfo_codeset=no)
+ ])
+ if test $am_cv_langinfo_codeset = yes; then
+ AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
+ [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
+ fi
+])
--- /dev/null
+# gettext.m4 serial 37 (gettext-0.14.4)
+dnl Copyright (C) 1995-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
+dnl default (if it is not specified or empty) is 'no-libtool'.
+dnl INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl depending on --{enable,disable}-{shared,static} and on the presence of
+dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl implementations (in libc or libintl) without the ngettext() function
+dnl will be ignored. If NEEDSYMBOL is specified and is
+dnl 'need-formatstring-macros', then GNU gettext implementations that don't
+dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries. If empty,
+dnl the value `$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl and used.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl Catalog format: none
+dnl Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+ dnl Argument checking.
+ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+ [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+ ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
+ [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+ define([gt_included_intl], ifelse([$1], [external], [no], [yes]))
+ define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+
+ AC_REQUIRE([AM_PO_SUBDIRS])dnl
+ ifelse(gt_included_intl, yes, [
+ AC_REQUIRE([AM_INTL_SUBDIR])dnl
+ ])
+
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ dnl Ideally we would do this search only after the
+ dnl if test "$USE_NLS" = "yes"; then
+ dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then
+ dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+ dnl the configure script would need to contain the same shell code
+ dnl again, outside any 'if'. There are two solutions:
+ dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+ dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+ dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+ dnl documented, we avoid it.
+ ifelse(gt_included_intl, yes, , [
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+ ])
+
+ dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+ gt_INTL_MACOSX
+
+ dnl Set USE_NLS.
+ AM_NLS
+
+ ifelse(gt_included_intl, yes, [
+ BUILD_INCLUDED_LIBINTL=no
+ USE_INCLUDED_LIBINTL=no
+ ])
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+ ifelse(gt_included_intl, yes, [
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ ])
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If GNU gettext is available we use this. Else we have
+ dnl to fall back to GNU NLS library.
+
+ dnl Add a version number to the cache macros.
+ define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1)))
+ define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc])
+ define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl])
+
+ AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>
+]ifelse([$2], [need-formatstring-macros],
+[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+], [])[extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+ [bindtextdomain ("", "");
+return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings],
+ gt_cv_func_gnugettext_libc=yes,
+ gt_cv_func_gnugettext_libc=no)])
+
+ if test "$gt_cv_func_gnugettext_libc" != "yes"; then
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ ifelse(gt_included_intl, yes, , [
+ AM_ICONV_LINK
+ ])
+ dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+ dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+ dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+ dnl even if libiconv doesn't exist.
+ AC_LIB_LINKFLAGS_BODY([intl])
+ AC_CACHE_CHECK([for GNU gettext in libintl],
+ gt_cv_func_gnugettext_libintl,
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ dnl Now see whether libintl exists and does not depend on libiconv.
+ AC_TRY_LINK([#include <libintl.h>
+]ifelse([$2], [need-formatstring-macros],
+[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+], [])[extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ gt_cv_func_gnugettext_libintl=yes,
+ gt_cv_func_gnugettext_libintl=no)
+ dnl Now see whether libintl exists and depends on libiconv.
+ if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <libintl.h>
+]ifelse([$2], [need-formatstring-macros],
+[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+], [])[extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ gt_cv_func_gnugettext_libintl=yes
+ ])
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ fi
+
+ dnl If an already present or preinstalled GNU gettext() is found,
+ dnl use it. But if this macro is used in GNU gettext, and GNU
+ dnl gettext is already preinstalled in libintl, we update this
+ dnl libintl. (Cf. the install rule in intl/Makefile.in.)
+ if test "$gt_cv_func_gnugettext_libc" = "yes" \
+ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \
+ && test "$PACKAGE" != gettext-runtime \
+ && test "$PACKAGE" != gettext-tools; }; then
+ gt_use_preinstalled_gnugettext=yes
+ else
+ dnl Reset the values set by searching for libintl.
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+ dnl GNU gettext is not found in the C library.
+ dnl Fall back on included GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ BUILD_INCLUDED_LIBINTL=yes
+ USE_INCLUDED_LIBINTL=yes
+ LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV"
+ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV"
+ LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
+ fi
+
+ CATOBJEXT=
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions to use GNU gettext tools.
+ CATOBJEXT=.gmo
+ fi
+ ])
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Some extra flags are needed during linking.
+ LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+ LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+ fi
+ fi
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1,
+ [Define to 1 if translation of program messages to the user's native language
+ is requested.])
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ AC_MSG_CHECKING([whether to use NLS])
+ AC_MSG_RESULT([$USE_NLS])
+ if test "$USE_NLS" = "yes"; then
+ AC_MSG_CHECKING([where the gettext function comes from])
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if test "$gt_cv_func_gnugettext_libintl" = "yes"; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ AC_MSG_RESULT([$gt_source])
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if test "$gt_cv_func_gnugettext_libintl" = "yes"; then
+ AC_MSG_CHECKING([how to link with libintl])
+ AC_MSG_RESULT([$LIBINTL])
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+ fi
+
+ dnl For backward compatibility. Some packages may be using this.
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define if the GNU gettext() function is already present or preinstalled.])
+ AC_DEFINE(HAVE_DCGETTEXT, 1,
+ [Define if the GNU dcgettext() function is already present or preinstalled.])
+ fi
+
+ dnl We need to process the po/ directory.
+ POSUB=po
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+ dnl to 'yes' because some of the testsuite requires it.
+ if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
+ BUILD_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(BUILD_INCLUDED_LIBINTL)
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATOBJEXT)
+
+ dnl For backward compatibility. Some configure.ins may be using this.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ DATADIRNAME=share
+ AC_SUBST(DATADIRNAME)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INSTOBJEXT=.mo
+ AC_SUBST(INSTOBJEXT)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ GENCAT=gencat
+ AC_SUBST(GENCAT)
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLOBJS=
+ if test "$USE_INCLUDED_LIBINTL" = yes; then
+ INTLOBJS="\$(GETTOBJS)"
+ fi
+ AC_SUBST(INTLOBJS)
+
+ dnl Enable libtool support if the surrounding package wishes it.
+ INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+ AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
+ ])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLLIBS="$LIBINTL"
+ AC_SUBST(INTLLIBS)
+
+ dnl Make all documented variables known to autoconf.
+ AC_SUBST(LIBINTL)
+ AC_SUBST(LTLIBINTL)
+ AC_SUBST(POSUB)
+])
+
+
+dnl Checks for all prerequisites of the intl subdirectory,
+dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
+dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
+AC_DEFUN([AM_INTL_SUBDIR],
+[
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+ AC_REQUIRE([AM_MKINSTALLDIRS])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl
+ AC_REQUIRE([gt_GLIBC2])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([bh_C_SIGNED])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([gl_AC_TYPE_LONG_LONG])dnl
+ AC_REQUIRE([gt_TYPE_LONGDOUBLE])dnl
+ AC_REQUIRE([gt_TYPE_WCHAR_T])dnl
+ AC_REQUIRE([gt_TYPE_WINT_T])dnl
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ AC_REQUIRE([gt_TYPE_INTMAX_T])
+ AC_REQUIRE([gt_PRINTF_POSIX])
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+ AC_REQUIRE([gl_GLIBC21])dnl
+ AC_REQUIRE([gt_INTDIV0])dnl
+ AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl
+ AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl
+ AC_REQUIRE([gt_INTTYPES_PRI])dnl
+ AC_REQUIRE([gl_XSIZE])dnl
+ AC_REQUIRE([gt_INTL_MACOSX])dnl
+
+ AC_CHECK_TYPE([ptrdiff_t], ,
+ [AC_DEFINE([ptrdiff_t], [long],
+ [Define as the type of the result of subtracting two pointers, if the system doesn't define it.])
+ ])
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \
+stdlib.h string.h unistd.h sys/param.h])
+ AC_CHECK_FUNCS([asprintf fwprintf getcwd getegid geteuid getgid getuid \
+mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \
+strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \
+__fsetlocking])
+
+ dnl Use the _snprintf function only if it is declared (because on NetBSD it
+ dnl is defined as a weak alias of snprintf; we prefer to use the latter).
+ gt_CHECK_DECL(_snprintf, [#include <stdio.h>])
+ gt_CHECK_DECL(_snwprintf, [#include <stdio.h>])
+
+ dnl Use the *_unlocked functions only if they are declared.
+ dnl (because some of them were defined without being declared in Solaris
+ dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built
+ dnl on Solaris 2.5.1 to run on Solaris 2.6).
+ dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13.
+ gt_CHECK_DECL(feof_unlocked, [#include <stdio.h>])
+ gt_CHECK_DECL(fgets_unlocked, [#include <stdio.h>])
+ gt_CHECK_DECL(getc_unlocked, [#include <stdio.h>])
+
+ case $gt_cv_func_printf_posix in
+ *yes) HAVE_POSIX_PRINTF=1 ;;
+ *) HAVE_POSIX_PRINTF=0 ;;
+ esac
+ AC_SUBST([HAVE_POSIX_PRINTF])
+ if test "$ac_cv_func_asprintf" = yes; then
+ HAVE_ASPRINTF=1
+ else
+ HAVE_ASPRINTF=0
+ fi
+ AC_SUBST([HAVE_ASPRINTF])
+ if test "$ac_cv_func_snprintf" = yes; then
+ HAVE_SNPRINTF=1
+ else
+ HAVE_SNPRINTF=0
+ fi
+ AC_SUBST([HAVE_SNPRINTF])
+ if test "$ac_cv_func_wprintf" = yes; then
+ HAVE_WPRINTF=1
+ else
+ HAVE_WPRINTF=0
+ fi
+ AC_SUBST([HAVE_WPRINTF])
+
+ AM_ICONV
+ AM_LANGINFO_CODESET
+ if test $ac_cv_header_locale_h = yes; then
+ gt_LC_MESSAGES
+ fi
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers"
+ fi
+
+ dnl intl/plural.c is generated from intl/plural.y. It requires bison,
+ dnl because plural.y uses bison specific features. It requires at least
+ dnl bison-1.26 because earlier versions generate a plural.c that doesn't
+ dnl compile.
+ dnl bison is only needed for the maintainer (who touches plural.y). But in
+ dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put
+ dnl the rule in general Makefile. Now, some people carelessly touch the
+ dnl files or have a broken "make" program, hence the plural.c rule will
+ dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not
+ dnl present or too old.
+ AC_CHECK_PROGS([INTLBISON], [bison])
+ if test -z "$INTLBISON"; then
+ ac_verc_fail=yes
+ else
+ dnl Found it, now check the version.
+ AC_MSG_CHECKING([version of bison])
+changequote(<<,>>)dnl
+ ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
+ case $ac_prog_version in
+ '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+ 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
+changequote([,])dnl
+ ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+ *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
+ esac
+ AC_MSG_RESULT([$ac_prog_version])
+ fi
+ if test $ac_verc_fail = yes; then
+ INTLBISON=:
+ fi
+])
+
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+ dnl Check for API introduced in MacOS X 10.2.
+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+ gt_cv_func_CFPreferencesCopyAppValue,
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -framework CoreFoundation"
+ AC_TRY_LINK([#include <CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1,
+ [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
+ fi
+ dnl Check for API introduced in MacOS X 10.3.
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent,
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -framework CoreFoundation"
+ AC_TRY_LINK([#include <CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1,
+ [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+ AC_SUBST([INTL_MACOSX_LIBS])
+])
+
+
+dnl gt_CHECK_DECL(FUNC, INCLUDES)
+dnl Check whether a function is declared.
+AC_DEFUN([gt_CHECK_DECL],
+[
+ AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1,
+ [AC_TRY_COMPILE([$2], [
+#ifndef $1
+ char *p = (char *) $1;
+#endif
+], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)])
+ if test $ac_cv_have_decl_$1 = yes; then
+ gt_value=1
+ else
+ gt_value=0
+ fi
+ AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value],
+ [Define to 1 if you have the declaration of `$1', and to 0 if you don't.])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
--- /dev/null
+# glibc2.m4 serial 1
+dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Test for the GNU C Library, version 2.0 or newer.
+# From Bruno Haible.
+
+AC_DEFUN([gt_GLIBC2],
+ [
+ AC_CACHE_CHECK(whether we are using the GNU C Library 2 or newer,
+ ac_cv_gnu_library_2,
+ [AC_EGREP_CPP([Lucky GNU user],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ >= 2)
+ Lucky GNU user
+ #endif
+#endif
+ ],
+ ac_cv_gnu_library_2=yes,
+ ac_cv_gnu_library_2=no)
+ ]
+ )
+ AC_SUBST(GLIBC2)
+ GLIBC2="$ac_cv_gnu_library_2"
+ ]
+)
--- /dev/null
+# glibc21.m4 serial 3
+dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Test for the GNU C Library, version 2.1 or newer.
+# From Bruno Haible.
+
+AC_DEFUN([gl_GLIBC21],
+ [
+ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer,
+ ac_cv_gnu_library_2_1,
+ [AC_EGREP_CPP([Lucky GNU user],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
+ Lucky GNU user
+ #endif
+#endif
+ ],
+ ac_cv_gnu_library_2_1=yes,
+ ac_cv_gnu_library_2_1=no)
+ ]
+ )
+ AC_SUBST(GLIBC21)
+ GLIBC21="$ac_cv_gnu_library_2_1"
+ ]
+)
--- /dev/null
+# iconv.m4 serial AM4 (gettext-0.11.3)
+dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+ dnl those with the standalone portable GNU libiconv installed).
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+ dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed libiconv and not disabled its use
+ dnl via --without-libiconv-prefix, he wants to use it. The first
+ dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
+ am_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+ AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ am_cv_func_iconv=yes)
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ am_cv_lib_iconv=yes
+ am_cv_func_iconv=yes)
+ LIBS="$am_save_LIBS"
+ fi
+ ])
+ if test "$am_cv_func_iconv" = yes; then
+ AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ AC_MSG_CHECKING([how to link with libiconv])
+ AC_MSG_RESULT([$LIBICONV])
+ else
+ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+ dnl either.
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+ AC_SUBST(LIBICONV)
+ AC_SUBST(LTLIBICONV)
+])
+
+AC_DEFUN([AM_ICONV],
+[
+ AM_ICONV_LINK
+ if test "$am_cv_func_iconv" = yes; then
+ AC_MSG_CHECKING([for iconv declaration])
+ AC_CACHE_VAL(am_cv_proto_iconv, [
+ AC_TRY_COMPILE([
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+ AC_MSG_RESULT([$]{ac_t:-
+ }[$]am_cv_proto_iconv)
+ AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
+ [Define as const if the declaration of iconv() needs const.])
+ fi
+])
--- /dev/null
+# intdiv0.m4 serial 1 (gettext-0.11.3)
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gt_INTDIV0],
+[
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+ AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
+ gt_cv_int_divbyzero_sigfpe,
+ [
+ AC_TRY_RUN([
+#include <stdlib.h>
+#include <signal.h>
+
+static void
+#ifdef __cplusplus
+sigfpe_handler (int sig)
+#else
+sigfpe_handler (sig) int sig;
+#endif
+{
+ /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */
+ exit (sig != SIGFPE);
+}
+
+int x = 1;
+int y = 0;
+int z;
+int nan;
+
+int main ()
+{
+ signal (SIGFPE, sigfpe_handler);
+/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */
+#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
+ signal (SIGTRAP, sigfpe_handler);
+#endif
+/* Linux/SPARC yields signal SIGILL. */
+#if defined (__sparc__) && defined (__linux__)
+ signal (SIGILL, sigfpe_handler);
+#endif
+
+ z = x / y;
+ nan = y / y;
+ exit (1);
+}
+], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no,
+ [
+ # Guess based on the CPU.
+ case "$host_cpu" in
+ alpha* | i[34567]86 | m68k | s390*)
+ gt_cv_int_divbyzero_sigfpe="guessing yes";;
+ *)
+ gt_cv_int_divbyzero_sigfpe="guessing no";;
+ esac
+ ])
+ ])
+ case "$gt_cv_int_divbyzero_sigfpe" in
+ *yes) value=1;;
+ *) value=0;;
+ esac
+ AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value,
+ [Define if integer division by zero raises signal SIGFPE.])
+])
--- /dev/null
+# intmax.m4 serial 2 (gettext-0.14.2)
+dnl Copyright (C) 2002-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether the system has the 'intmax_t' type, but don't attempt to
+dnl find a replacement if it is lacking.
+
+AC_DEFUN([gt_TYPE_INTMAX_T],
+[
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t,
+ [AC_TRY_COMPILE([
+#include <stddef.h>
+#include <stdlib.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+#include <inttypes.h>
+#endif
+], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)])
+ if test $gt_cv_c_intmax_t = yes; then
+ AC_DEFINE(HAVE_INTMAX_T, 1,
+ [Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
+ fi
+])
--- /dev/null
+#serial 6
+
+dnl From Paul Eggert.
+
+AC_PREREQ(2.52)
+
+# Define intmax_t to long or long long if <inttypes.h> doesn't define.
+
+AC_DEFUN([gl_AC_TYPE_INTMAX_T],
+[
+ dnl For simplicity, we assume that a header file defines 'intmax_t' if and
+ dnl only if it defines 'uintmax_t'.
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+ AC_REQUIRE([gl_AC_TYPE_LONG_LONG])
+ test $ac_cv_type_long_long = yes \
+ && ac_type='long long' \
+ || ac_type='long'
+ AC_DEFINE_UNQUOTED(intmax_t, $ac_type,
+ [Define to long or long long if <inttypes.h> and <stdint.h> don't define.])
+ else
+ AC_DEFINE(HAVE_INTMAX_T, 1,
+ [Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
+ fi
+])
+
+# Define uintmax_t to unsigned long or unsigned long long
+# if <inttypes.h> doesn't define.
+
+AC_DEFUN([jm_AC_TYPE_UINTMAX_T],
+[
+ AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG])
+ AC_CHECK_TYPE(uintmax_t, ,
+ [test $ac_cv_type_unsigned_long_long = yes \
+ && ac_type='unsigned long long' \
+ || ac_type='unsigned long'
+ AC_DEFINE_UNQUOTED(uintmax_t, $ac_type,
+ [Define to widest unsigned type if <inttypes.h> doesn't define.])])
+])
--- /dev/null
+# inttypes-pri.m4 serial 1 (gettext-0.11.4)
+dnl Copyright (C) 1997-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI*
+# macros to non-string values. This is the case on AIX 4.3.3.
+
+AC_DEFUN([gt_INTTYPES_PRI],
+[
+ AC_REQUIRE([gt_HEADER_INTTYPES_H])
+ if test $gt_cv_header_inttypes_h = yes; then
+ AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken],
+ gt_cv_inttypes_pri_broken,
+ [
+ AC_TRY_COMPILE([#include <inttypes.h>
+#ifdef PRId32
+char *p = PRId32;
+#endif
+], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes)
+ ])
+ fi
+ if test "$gt_cv_inttypes_pri_broken" = yes; then
+ AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1,
+ [Define if <inttypes.h> exists and defines unusable PRI* macros.])
+ fi
+])
--- /dev/null
+# inttypes.m4 serial 1 (gettext-0.11.4)
+dnl Copyright (C) 1997-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_INTTYPES_H if <inttypes.h> exists and doesn't clash with
+# <sys/types.h>.
+
+AC_DEFUN([gt_HEADER_INTTYPES_H],
+[
+ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h,
+ [
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <inttypes.h>],
+ [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no)
+ ])
+ if test $gt_cv_header_inttypes_h = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1,
+ [Define if <inttypes.h> exists and doesn't clash with <sys/types.h>.])
+ fi
+])
--- /dev/null
+# inttypes_h.m4 serial 6
+dnl Copyright (C) 1997-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists,
+# doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_DEFUN([gl_AC_HEADER_INTTYPES_H],
+[
+ AC_CACHE_CHECK([for inttypes.h], gl_cv_header_inttypes_h,
+ [AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <inttypes.h>],
+ [uintmax_t i = (uintmax_t) -1;],
+ gl_cv_header_inttypes_h=yes,
+ gl_cv_header_inttypes_h=no)])
+ if test $gl_cv_header_inttypes_h = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1,
+ [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>,
+ and declares uintmax_t. ])
+ fi
+])
--- /dev/null
+# isc-posix.m4 serial 2 (gettext-0.11.2)
+dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# This file is not needed with autoconf-2.53 and newer. Remove it in 2005.
+
+# This test replaces the one in autoconf.
+# Currently this macro should have the same name as the autoconf macro
+# because gettext's gettext.m4 (distributed in the automake package)
+# still uses it. Otherwise, the use in gettext.m4 makes autoheader
+# give these diagnostics:
+# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
+# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
+
+undefine([AC_ISC_POSIX])
+
+AC_DEFUN([AC_ISC_POSIX],
+ [
+ dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
+ AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
+ ]
+)
--- /dev/null
+# lcmessage.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 1995-2002, 2004-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+
+AC_DEFUN([gt_LC_MESSAGES],
+[
+ AC_CACHE_CHECK([for LC_MESSAGES], gt_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ gt_cv_val_LC_MESSAGES=yes, gt_cv_val_LC_MESSAGES=no)])
+ if test $gt_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your <locale.h> file defines LC_MESSAGES.])
+ fi
+])
--- /dev/null
+# lib-ld.m4 serial 3 (gettext-0.13)
+dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ [re_direlt='/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(acl_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
--- /dev/null
+# lib-link.m4 serial 6 (gettext-0.14.3)
+dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ(2.50)
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ define([Name],[translit([$1],[./-], [___])])
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+ ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+ ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+ dnl results of this search when this library appears as a dependency.
+ HAVE_LIB[]NAME=yes
+ undefine([Name])
+ undefine([NAME])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. If found, it
+dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
+dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ define([Name],[translit([$1],[./-], [___])])
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+
+ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed lib[]Name and not disabled its use
+ dnl via --without-lib[]Name-prefix, he wants to use it.
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIB[]NAME"
+ AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
+ LIBS="$ac_save_LIBS"
+ ])
+ if test "$ac_cv_lib[]Name" = yes; then
+ HAVE_LIB[]NAME=yes
+ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
+ AC_MSG_CHECKING([how to link with lib[]$1])
+ AC_MSG_RESULT([$LIB[]NAME])
+ else
+ HAVE_LIB[]NAME=no
+ dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+ dnl $INC[]NAME either.
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIB[]NAME=
+ LTLIB[]NAME=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ undefine([Name])
+ undefine([NAME])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator,
+dnl hardcode_direct, hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+ dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
+ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
+ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+ AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+ ])
+ wl="$acl_cv_wl"
+ libext="$acl_cv_libext"
+ shlibext="$acl_cv_shlibext"
+ hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ hardcode_direct="$acl_cv_hardcode_direct"
+ hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ dnl Determine whether the user wants rpath handling at all.
+ AC_ARG_ENABLE(rpath,
+ [ --disable-rpath do not hardcode runtime library paths],
+ :, enable_rpath=yes)
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib$1-prefix],
+[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
+ --without-lib$1-prefix don't search for lib$1 in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/lib"
+ fi
+ fi
+])
+ dnl Search the library and its dependencies in $additional_libdir and
+ dnl $LDFLAGS. Using breadth-first-seach.
+ LIB[]NAME=
+ LTLIB[]NAME=
+ INC[]NAME=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='$1 $2'
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+ dnl or AC_LIB_HAVE_LINKFLAGS call.
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+ else
+ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+ dnl that this library doesn't exist. So just drop it.
+ :
+ fi
+ else
+ dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+ dnl and the already constructed $LIBNAME/$LTLIBNAME.
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ if test $use_additional = yes; then
+ if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
+ found_dir="$additional_libdir"
+ found_so="$additional_libdir/lib$name.$shlibext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ else
+ if test -f "$additional_libdir/lib$name.$libext"; then
+ found_dir="$additional_libdir"
+ found_a="$additional_libdir/lib$name.$libext"
+ if test -f "$additional_libdir/lib$name.la"; then
+ found_la="$additional_libdir/lib$name.la"
+ fi
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
+ found_dir="$dir"
+ found_so="$dir/lib$name.$shlibext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ else
+ if test -f "$dir/lib$name.$libext"; then
+ found_dir="$dir"
+ found_a="$dir/lib$name.$libext"
+ if test -f "$dir/lib$name.la"; then
+ found_la="$dir/lib$name.la"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ dnl Found the library.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ dnl Linking with a shared library. We attempt to hardcode its
+ dnl directory into the executable's runpath, unless it's the
+ dnl standard /usr/lib.
+ if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
+ dnl No hardcoding is needed.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ dnl The hardcoding into $LIBNAME is system dependent.
+ if test "$hardcode_direct" = yes; then
+ dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+ dnl resulting binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ dnl Rely on "-L$found_dir".
+ dnl But don't add it if it's already contained in the LDFLAGS
+ dnl or the already constructed $LIBNAME
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+ fi
+ if test "$hardcode_minus_L" != no; then
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH
+ dnl here, because this doesn't fit in flags passed to the
+ dnl compiler. So give up. No hardcoding. This affects only
+ dnl very old systems.
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ dnl Linking with a static library.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+ else
+ dnl We shouldn't come here, but anyway it's good to have a
+ dnl fallback.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+ fi
+ fi
+ dnl Assume the include files are nearby.
+ additional_includedir=
+ case "$found_dir" in
+ */lib | */lib/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ dnl Potentially add $additional_includedir to $INCNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 3. if it's already present in $CPPFLAGS or the already
+ dnl constructed $INCNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INC[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $INCNAME.
+ INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ dnl Look for dependencies.
+ if test -n "$found_la"; then
+ dnl Read the .la file. It defines the variables
+ dnl dlname, library_names, old_library, dependency_libs, current,
+ dnl age, revision, installed, dlopen, dlpreopen, libdir.
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ dnl We use only dependency_libs.
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 3. if it's already present in $LDFLAGS or the already
+ dnl constructed $LIBNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/lib"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/lib"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ dnl Handle this in the next round.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ dnl Handle this in the next round. Throw away the .la's
+ dnl directory; it is already contained in a preceding -L
+ dnl option.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ dnl Most likely an immediate library name.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ dnl Didn't find the library; assume it is in the system directories
+ dnl known to the linker and runtime loader. (All the system
+ dnl directories known to the linker should also be known to the
+ dnl runtime loader, otherwise the system is severely misconfigured.)
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user must
+ dnl pass all path elements in one option. We can arrange that for a
+ dnl single library, but not when more than one $LIBNAMEs are used.
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ dnl When using libtool, the option that works for both libraries and
+ dnl executables is -R. The -R options are cumulative.
+ for found_dir in $ltrpathdirs; do
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+ done
+ fi
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+ for element in [$2]; do
+ haveit=
+ for x in $[$1]; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ [$1]="${[$1]}${[$1]:+ }$element"
+ fi
+ done
+])
--- /dev/null
+# lib-prefix.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+ AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib-prefix],
+[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/lib"
+ fi
+ fi
+])
+ if test $use_additional = yes; then
+ dnl Potentially add $additional_includedir to $CPPFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's already present in $CPPFLAGS,
+ dnl 3. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ for x in $CPPFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $CPPFLAGS.
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ dnl Potentially add $additional_libdir to $LDFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's already present in $LDFLAGS,
+ dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/lib"; then
+ haveit=
+ for x in $LDFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_libdir" = "X/usr/local/lib"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux*) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LDFLAGS.
+ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+ dnl Unfortunately, prefix and exec_prefix get only finally determined
+ dnl at the end of configure.
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ $1
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+])
--- /dev/null
+# longdouble.m4 serial 1 (gettext-0.12)
+dnl Copyright (C) 2002-2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether the compiler supports the 'long double' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_LONGDOUBLE],
+[
+ AC_CACHE_CHECK([for long double], gt_cv_c_long_double,
+ [if test "$GCC" = yes; then
+ gt_cv_c_long_double=yes
+ else
+ AC_TRY_COMPILE([
+ /* The Stardent Vistra knows sizeof(long double), but does not support it. */
+ long double foo = 0.0;
+ /* On Ultrix 4.3 cc, long double is 4 and double is 8. */
+ int array [2*(sizeof(long double) >= sizeof(double)) - 1];
+ ], ,
+ gt_cv_c_long_double=yes, gt_cv_c_long_double=no)
+ fi])
+ if test $gt_cv_c_long_double = yes; then
+ AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.])
+ fi
+])
--- /dev/null
+# longlong.m4 serial 5
+dnl Copyright (C) 1999-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_LONG_LONG if 'long long' works.
+
+AC_DEFUN([gl_AC_TYPE_LONG_LONG],
+[
+ AC_CACHE_CHECK([for long long], ac_cv_type_long_long,
+ [AC_TRY_LINK([long long ll = 1LL; int i = 63;],
+ [long long llmax = (long long) -1;
+ return ll << i | ll >> i | llmax / ll | llmax % ll;],
+ ac_cv_type_long_long=yes,
+ ac_cv_type_long_long=no)])
+ if test $ac_cv_type_long_long = yes; then
+ AC_DEFINE(HAVE_LONG_LONG, 1,
+ [Define if you have the 'long long' type.])
+ fi
+])
--- /dev/null
+# nls.m4 serial 2 (gettext-0.14.3)
+dnl Copyright (C) 1995-2003, 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ(2.50)
+
+AC_DEFUN([AM_NLS],
+[
+ AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+])
+
+AC_DEFUN([AM_MKINSTALLDIRS],
+[
+ dnl Tell automake >= 1.10 to complain if mkinstalldirs is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([mkinstalldirs])])
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but $(top_srcdir).
+ dnl Try to locate it.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ case "$ac_aux_dir" in
+ /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;;
+ *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;;
+ esac
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+])
--- /dev/null
+# po.m4 serial 7 (gettext-0.14.3)
+dnl Copyright (C) 1995-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ(2.50)
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+ AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+ AC_REQUIRE([AM_MKINSTALLDIRS])dnl
+ AC_REQUIRE([AM_NLS])dnl
+
+ dnl Perform the following tests also if --disable-nls has been given,
+ dnl because they are needed for "make dist" to work.
+
+ dnl Search for GNU msgfmt in the PATH.
+ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+ dnl The second test excludes FreeBSD msgfmt.
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+
+ dnl Search for GNU xgettext 0.12 or newer in the PATH.
+ dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+ dnl The second test excludes FreeBSD xgettext.
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ dnl Remove leftover from FreeBSD xgettext call.
+ rm -f messages.po
+
+ dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
+
+ dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
+ dnl Test whether we really found GNU msgfmt.
+ if test "$GMSGFMT" != ":"; then
+ dnl If it is no GNU msgfmt we define it as : so that the
+ dnl Makefiles still can work.
+ if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 &&
+ (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'`
+ AC_MSG_RESULT(
+ [found $GMSGFMT program is not GNU msgfmt; ignore it])
+ GMSGFMT=":"
+ fi
+ fi
+
+ dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
+ (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ dnl Remove leftover from FreeBSD xgettext call.
+ rm -f messages.po
+ fi
+
+ AC_OUTPUT_COMMANDS([
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done],
+ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+ ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+ # When this code is run, in config.status, two variables have already been
+ # set:
+ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+ # - LINGUAS is the value of the environment variable LINGUAS at configure
+ # time.
+
+changequote(,)dnl
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ # Find a way to echo strings without interpreting backslash.
+ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='echo'
+ else
+ if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='printf %s\n'
+ else
+ echo_func () {
+ cat <<EOT
+$*
+EOT
+ }
+ gt_echo='echo_func'
+ fi
+ fi
+
+ # A sed script that extracts the value of VARIABLE from a Makefile.
+ sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^[ ]*VARIABLE[ ]*=/{
+ # Seen the first line of the variable definition.
+ s/^[ ]*VARIABLE[ ]*=//
+ ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+ # Set POTFILES to the value of the Makefile variable POTFILES.
+ sed_x_POTFILES="`$gt_echo \"$sed_x_variable\" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`"
+ POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+ # Compute POTFILES_DEPS as
+ # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+ POTFILES_DEPS=
+ for file in $POTFILES; do
+ POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+ done
+ POMAKEFILEDEPS=""
+
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+ sed_x_LINGUAS="`$gt_echo \"$sed_x_variable\" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`"
+ ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+ fi
+ # Hide the ALL_LINGUAS assigment from automake.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ # Compute PROPERTIESFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+ # Compute CLASSFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+ # Compute QMFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+ # Compute MSGFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+ # Compute RESOURCESDLLFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ PROPERTIESFILES=
+ CLASSFILES=
+ QMFILES=
+ MSGFILES=
+ RESOURCESDLLFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+ CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+ QMFILES="$QMFILES $srcdirpre$lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ JAVACATALOGS=
+ QTCATALOGS=
+ TCLCATALOGS=
+ CSHARPCATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+ QTCATALOGS="$QTCATALOGS $lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ fi
+
+ sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
+ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+ @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+ \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+ @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+ \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if test -n "$POMAKEFILEDEPS"; then
+ cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+ fi
+ mv "$ac_file.tmp" "$ac_file"
+])
--- /dev/null
+# printf-posix.m4 serial 2 (gettext-0.13.1)
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether the printf() function supports POSIX/XSI format strings with
+dnl positions.
+
+AC_DEFUN([gt_PRINTF_POSIX],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([whether printf() supports POSIX/XSI format strings],
+ gt_cv_func_printf_posix,
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+/* The string "%2$d %1$d", with dollar characters protected from the shell's
+ dollar expansion (possibly an autoconf bug). */
+static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
+static char buf[100];
+int main ()
+{
+ sprintf (buf, format, 33, 55);
+ return (strcmp (buf, "55 33") != 0);
+}], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no,
+ [
+ AC_EGREP_CPP(notposix, [
+#if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__
+ notposix
+#endif
+ ], gt_cv_func_printf_posix="guessing no",
+ gt_cv_func_printf_posix="guessing yes")
+ ])
+ ])
+ case $gt_cv_func_printf_posix in
+ *yes)
+ AC_DEFINE(HAVE_POSIX_PRINTF, 1,
+ [Define if your printf() function supports format strings with positions.])
+ ;;
+ esac
+])
--- /dev/null
+# progtest.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+AC_PREREQ(2.50)
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ [[\\/]]* | ?:[[\\/]]*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
--- /dev/null
+# signed.m4 serial 1 (gettext-0.10.40)
+dnl Copyright (C) 2001-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([bh_C_SIGNED],
+[
+ AC_CACHE_CHECK([for signed], bh_cv_c_signed,
+ [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)])
+ if test $bh_cv_c_signed = no; then
+ AC_DEFINE(signed, ,
+ [Define to empty if the C compiler doesn't support this keyword.])
+ fi
+])
--- /dev/null
+# size_max.m4 serial 2
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gl_SIZE_MAX],
+[
+ AC_CHECK_HEADERS(stdint.h)
+ dnl First test whether the system already has SIZE_MAX.
+ AC_MSG_CHECKING([for SIZE_MAX])
+ result=
+ AC_EGREP_CPP([Found it], [
+#include <limits.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef SIZE_MAX
+Found it
+#endif
+], result=yes)
+ if test -z "$result"; then
+ dnl Define it ourselves. Here we assume that the type 'size_t' is not wider
+ dnl than the type 'unsigned long'.
+ dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr',
+ dnl which is guaranteed to work from LONG_MIN to LONG_MAX.
+ _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi,
+ [#include <stddef.h>], result=?)
+ _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo,
+ [#include <stddef.h>], result=?)
+ _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint,
+ [#include <stddef.h>], result=?)
+ if test "$fits_in_uint" = 1; then
+ dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
+ dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'.
+ AC_TRY_COMPILE([#include <stddef.h>
+ extern size_t foo;
+ extern unsigned long foo;
+ ], [], fits_in_uint=0)
+ fi
+ if test -z "$result"; then
+ if test "$fits_in_uint" = 1; then
+ result="$res_hi$res_lo"U
+ else
+ result="$res_hi$res_lo"UL
+ fi
+ else
+ dnl Shouldn't happen, but who knows...
+ result='~(size_t)0'
+ fi
+ fi
+ AC_MSG_RESULT([$result])
+ if test "$result" != yes; then
+ AC_DEFINE_UNQUOTED([SIZE_MAX], [$result],
+ [Define as the maximum value of type 'size_t', if the system doesn't define it.])
+ fi
+])
--- /dev/null
+dnl
+dnl socket.m4 --- autoconf input file for gawk
+dnl
+dnl Copyright (C) 1995, 1996, 1998, 1999, 2000, 2003, 2004 the Free Software Foundation, Inc.
+dnl
+dnl This file is part of GAWK, the GNU implementation of the
+dnl AWK Progamming Language.
+dnl
+dnl GAWK is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl GAWK is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+dnl
+
+dnl Find the socket libraries
+dnl largely stolen from AC_PATH_XTRA
+AC_DEFUN([GAWK_AC_LIB_SOCKETS], [
+gawk_have_sockets=no
+# Check for system-dependent location of socket libraries
+
+SOCKET_LIBS=
+if test "$ISC" = yes; then
+ SOCKET_LIBS="-lnsl_s -linet"
+else
+ # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And karl@cs.umb.edu says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ #
+ # ADR: Is this needed just for sockets???
+# AC_CHECK_LIB(dnet, dnet_ntoa, [SOCKET_LIBS="$SOCKET_LIBS -ldnet"])
+# if test $ac_cv_lib_dnet_ntoa = no; then
+# AC_CHECK_LIB(dnet_stub, dnet_ntoa,
+# [SOCKET_LIBS="$SOCKET_LIBS -ldnet_stub"])
+# fi
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # chad@anasazi.com says the Pyramid MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to dickey@clark.net.
+ AC_CHECK_FUNC(gethostbyname)
+ if test $ac_cv_func_gethostbyname = no; then
+ AC_CHECK_LIB(nsl, gethostbyname, SOCKET_LIBS="$SOCKET_LIBS -lnsl")
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says simon@lia.di.epfl.ch: it contains
+ # gethostby* variants that don't use the nameserver (or something).
+ # -lsocket must be given before -lnsl if both are needed.
+ # We assume that if connect needs -lnsl, so does gethostbyname.
+ AC_CHECK_FUNC(connect)
+ if test $ac_cv_func_connect = no; then
+ AC_CHECK_LIB(socket, connect, SOCKET_LIBS="-lsocket $SOCKET_LIBS"
+ gawk_have_sockets=yes, ,
+ $SOCKET_LIBS)
+ else
+ gawk_have_sockets=yes
+ fi
+fi
+
+if test "${gawk_have_sockets}" = "yes"
+then
+ AC_MSG_CHECKING([where to find the socket library calls])
+ case "${SOCKET_LIBS}" in
+ ?*) gawk_lib_loc="${SOCKET_LIBS}" ;;
+ *) gawk_lib_loc="the standard library" ;;
+ esac
+ AC_MSG_RESULT([${gawk_lib_loc}])
+
+ AC_DEFINE(HAVE_SOCKETS, 1, [we have sockets on this system])
+fi
+AC_SUBST(SOCKET_LIBS)dnl
+])dnl
--- /dev/null
+# stdint_h.m4 serial 5
+dnl Copyright (C) 1997-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists,
+# doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_DEFUN([gl_AC_HEADER_STDINT_H],
+[
+ AC_CACHE_CHECK([for stdint.h], gl_cv_header_stdint_h,
+ [AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <stdint.h>],
+ [uintmax_t i = (uintmax_t) -1;],
+ gl_cv_header_stdint_h=yes,
+ gl_cv_header_stdint_h=no)])
+ if test $gl_cv_header_stdint_h = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1,
+ [Define if <stdint.h> exists, doesn't clash with <sys/types.h>,
+ and declares uintmax_t. ])
+ fi
+])
--- /dev/null
+dnl
+dnl strtod.m4 --- autoconf input file for gawk
+dnl
+dnl Copyright (C) 2001, 2002, 2004 the Free Software Foundation, Inc.
+dnl
+dnl This file is part of GAWK, the GNU implementation of the
+dnl AWK Progamming Language.
+dnl
+dnl GAWK is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl GAWK is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+dnl Check for strtod with C89 semantics
+
+AC_DEFUN([GAWK_AC_FUNC_STRTOD_C89], [
+AC_CHECK_HEADERS(stdlib.h)
+AC_CHECK_FUNCS(strtod)
+AC_CACHE_CHECK([for strtod with C89 semantics], gawk_ac_cv_func_strtod_c89,
+[AC_TRY_RUN(
+[/* Test program from Arnold Robbins (arnold@skeeve.com) */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#else
+extern double strtod();
+#endif
+
+int
+main ()
+{
+#if ! HAVE_STRTOD
+ exit(1);
+#else
+ double d;
+ char *str = "0x345a";
+
+ d = strtod(str, 0);
+ if (d == 0)
+ exit (0);
+ else
+ exit (1);
+#endif
+}],
+gawk_ac_cv_func_strtod_c89=yes, gawk_ac_cv_func_strtod_c89=no,
+gawk_ac_cv_func_strtod_c89=no)])
+if test $gawk_ac_cv_func_strtod_c89 = no; then
+ AC_DEFINE(STRTOD_NOT_C89, 1, [strtod doesn't have C89 semantics])
+fi
+])# GAWK_FUNC_STRTOD_C89
--- /dev/null
+# uintmax_t.m4 serial 9
+dnl Copyright (C) 1997-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_PREREQ(2.13)
+
+# Define uintmax_t to 'unsigned long' or 'unsigned long long'
+# if it is not already defined in <stdint.h> or <inttypes.h>.
+
+AC_DEFUN([gl_AC_TYPE_UINTMAX_T],
+[
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+ AC_REQUIRE([gl_AC_TYPE_UNSIGNED_LONG_LONG])
+ test $ac_cv_type_unsigned_long_long = yes \
+ && ac_type='unsigned long long' \
+ || ac_type='unsigned long'
+ AC_DEFINE_UNQUOTED(uintmax_t, $ac_type,
+ [Define to unsigned long or unsigned long long
+ if <stdint.h> and <inttypes.h> don't define.])
+ else
+ AC_DEFINE(HAVE_UINTMAX_T, 1,
+ [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.])
+ fi
+])
--- /dev/null
+# ulonglong.m4 serial 4
+dnl Copyright (C) 1999-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_UNSIGNED_LONG_LONG if 'unsigned long long' works.
+
+AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG],
+[
+ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long,
+ [AC_TRY_LINK([unsigned long long ull = 1ULL; int i = 63;],
+ [unsigned long long ullmax = (unsigned long long) -1;
+ return ull << i | ull >> i | ullmax / ull | ullmax % ull;],
+ ac_cv_type_unsigned_long_long=yes,
+ ac_cv_type_unsigned_long_long=no)])
+ if test $ac_cv_type_unsigned_long_long = yes; then
+ AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1,
+ [Define if you have the 'unsigned long long' type.])
+ fi
+])
--- /dev/null
+# wchar_t.m4 serial 1 (gettext-0.12)
+dnl Copyright (C) 2002-2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <stddef.h> has the 'wchar_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WCHAR_T],
+[
+ AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t,
+ [AC_TRY_COMPILE([#include <stddef.h>
+ wchar_t foo = (wchar_t)'\0';], ,
+ gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)])
+ if test $gt_cv_c_wchar_t = yes; then
+ AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.])
+ fi
+])
--- /dev/null
+# wint_t.m4 serial 1 (gettext-0.12)
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <wchar.h> has the 'wint_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WINT_T],
+[
+ AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t,
+ [AC_TRY_COMPILE([#include <wchar.h>
+ wint_t foo = (wchar_t)'\0';], ,
+ gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)])
+ if test $gt_cv_c_wint_t = yes; then
+ AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.])
+ fi
+])
--- /dev/null
+# xsize.m4 serial 3
+dnl Copyright (C) 2003-2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_XSIZE],
+[
+ dnl Prerequisites of lib/xsize.h.
+ AC_REQUIRE([gl_SIZE_MAX])
+ AC_REQUIRE([AC_C_INLINE])
+ AC_CHECK_HEADERS(stdint.h)
+])
--- /dev/null
+/*
+ * main.c -- Expression tree constructors and main program for gawk.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* FIX THIS BEFORE EVERY RELEASE: */
+#define UPDATE_YEAR 2005
+
+#include "awk.h"
+#include "getopt.h"
+
+#ifndef O_BINARY
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_MCHECK_H
+#include <mcheck.h>
+#endif
+
+#define DEFAULT_PROFILE "awkprof.out" /* where to put profile */
+#define DEFAULT_VARFILE "awkvars.out" /* where to put vars */
+
+static const char *varfile = DEFAULT_VARFILE;
+
+static void usage P((int exitval, FILE *fp)) ATTRIBUTE_NORETURN;
+static void copyleft P((void)) ATTRIBUTE_NORETURN;
+static void cmdline_fs P((char *str));
+static void init_args P((int argc0, int argc, char *argv0, char **argv));
+static void init_vars P((void));
+static NODE *load_environ P((void));
+static NODE *load_procinfo P((void));
+static void add_src P((struct src **data, long *num, long *alloc, enum srctype stype, char *val));
+static RETSIGTYPE catchsig P((int sig)) ATTRIBUTE_NORETURN;
+static void nostalgia P((void)) ATTRIBUTE_NORETURN;
+static void version P((void)) ATTRIBUTE_NORETURN;
+static void init_fds P((void));
+static void init_groupset P((void));
+
+/* These nodes store all the special variables AWK uses */
+NODE *ARGC_node, *ARGIND_node, *ARGV_node, *BINMODE_node, *CONVFMT_node;
+NODE *ENVIRON_node, *ERRNO_node, *FIELDWIDTHS_node, *FILENAME_node, *FNR_node;
+NODE *FS_node, *IGNORECASE_node, *NF_node, *NR_node, *OFMT_node, *OFS_node;
+NODE *ORS_node, *PROCINFO_node, *RLENGTH_node, *RSTART_node, *RS_node;
+NODE *RT_node, *SUBSEP_node, *LINT_node, *TEXTDOMAIN_node;
+
+long NF;
+long NR;
+long FNR;
+int BINMODE;
+int IGNORECASE;
+char *OFS;
+char *ORS;
+char *OFMT;
+char *TEXTDOMAIN;
+int MRL; /* See -mr option for use of this variable */
+
+/*
+ * CONVFMT is a convenience pointer for the current number to string format.
+ * We must supply an initial value to avoid recursion problems of
+ * set_CONVFMT -> fmt_index -> r_force_string: gets NULL CONVFMT
+ * Fun, fun, fun, fun.
+ */
+char *CONVFMT = "%.6g";
+
+
+int errcount = 0; /* error counter, used by yyerror() */
+
+NODE *Nnull_string; /* The global null string */
+
+#if defined(HAVE_LOCALE_H)
+struct lconv loc; /* current locale */
+#endif /* defined(HAVE_LOCALE_H) */
+
+/* The name the program was invoked under, for error messages */
+const char *myname;
+
+/* A block of AWK code to be run before running the program */
+NODE *begin_block = NULL;
+
+/* A block of AWK code to be run after the last input file */
+NODE *end_block = NULL;
+
+int exiting = FALSE; /* Was an "exit" statement executed? */
+int exit_val = 0; /* optional exit value */
+
+#if defined(YYDEBUG) || defined(GAWKDEBUG)
+extern int yydebug;
+#endif
+
+struct src *srcfiles = NULL; /* source file name(s) */
+long numfiles = -1; /* how many source files */
+static long allocfiles; /* for how many is *srcfiles allocated */
+
+#define srcfiles_add(stype, val) \
+ add_src(&srcfiles, &numfiles, &allocfiles, stype, val)
+
+static struct src *preassigns = NULL; /* requested via -v or -F */
+static long numassigns = -1; /* how many of them */
+static long allocassigns; /* for how many is allocated */
+
+static int disallow_var_assigns = FALSE; /* true for --exec */
+
+#define preassigns_add(stype, val) \
+ add_src(&preassigns, &numassigns, &allocassigns, stype, val)
+
+#undef do_lint
+#undef do_lint_old
+
+int do_traditional = FALSE; /* no gnu extensions, add traditional weirdnesses */
+int do_posix = FALSE; /* turn off gnu and unix extensions */
+int do_lint = FALSE; /* provide warnings about questionable stuff */
+int do_lint_old = FALSE; /* warn about stuff not in V7 awk */
+int do_intl = FALSE; /* dump locale-izable strings to stdout */
+int do_non_decimal_data = FALSE; /* allow octal/hex C style DATA. Use with caution! */
+int do_nostalgia = FALSE; /* provide a blast from the past */
+int do_intervals = FALSE; /* allow {...,...} in regexps */
+int do_profiling = FALSE; /* profile and pretty print the program */
+int do_dump_vars = FALSE; /* dump all global variables at end */
+int do_tidy_mem = FALSE; /* release vars when done */
+
+int in_begin_rule = FALSE; /* we're in a BEGIN rule */
+int in_end_rule = FALSE; /* we're in a END rule */
+int whiny_users = FALSE; /* do things that whiny users want */
+#ifdef MBS_SUPPORT
+int gawk_mb_cur_max; /* MB_CUR_MAX value, see comment in main() */
+#else
+const int gawk_mb_cur_max = 1;
+#endif
+
+int output_is_tty = FALSE; /* control flushing of output */
+
+extern const char *version_string;
+
+#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
+GETGROUPS_T *groupset; /* current group set */
+int ngroups; /* size of said set */
+#endif
+
+/* The parse tree is stored here. */
+NODE *expression_value;
+
+#if _MSC_VER == 510
+void (*lintfunc) P((va_list va_alist, ...)) = warning;
+#else
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+void (*lintfunc) P((const char *mesg, ...)) = warning;
+#else
+void (*lintfunc) () = warning;
+#endif
+#endif
+
+static const struct option optab[] = {
+ { "compat", no_argument, & do_traditional, 1 },
+ { "traditional", no_argument, & do_traditional, 1 },
+ { "lint", optional_argument, NULL, 'l' },
+ { "lint-old", no_argument, & do_lint_old, 1 },
+ { "posix", no_argument, & do_posix, 1 },
+ { "nostalgia", no_argument, & do_nostalgia, 1 },
+ { "gen-po", no_argument, & do_intl, 1 },
+ { "non-decimal-data", no_argument, & do_non_decimal_data, 1 },
+ { "profile", optional_argument, NULL, 'p' },
+ { "copyleft", no_argument, NULL, 'C' },
+ { "copyright", no_argument, NULL, 'C' },
+ { "field-separator", required_argument, NULL, 'F' },
+ { "file", required_argument, NULL, 'f' },
+ { "re-interval", no_argument, & do_intervals, 1 },
+ { "source", required_argument, NULL, 's' },
+ { "dump-variables", optional_argument, NULL, 'd' },
+ { "assign", required_argument, NULL, 'v' },
+ { "version", no_argument, NULL, 'V' },
+ { "usage", no_argument, NULL, 'u' },
+ { "help", no_argument, NULL, 'u' },
+ { "exec", required_argument, NULL, 'S' },
+#ifdef GAWKDEBUG
+ { "parsedebug", no_argument, NULL, 'D' },
+#endif
+ { NULL, 0, NULL, '\0' }
+};
+
+#ifdef NO_LINT
+#define do_lint 0
+#define do_lint_old 0
+#endif
+
+/* main --- process args, parse program, run it, clean up */
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ char *scan;
+ /* the + on the front tells GNU getopt not to rearrange argv */
+ const char *optlist = "+F:f:v:W;m:D";
+ int stopped_early = FALSE;
+ int old_optind;
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+ int i;
+ int stdio_problem = FALSE;
+
+ /* do these checks early */
+ if (getenv("TIDYMEM") != NULL)
+ do_tidy_mem = TRUE;
+
+ if (getenv("WHINY_USERS") != NULL)
+ whiny_users = TRUE;
+
+#ifdef HAVE_MCHECK_H
+ if (do_tidy_mem)
+ mtrace();
+#endif /* HAVE_MCHECK_H */
+
+#if defined(LC_CTYPE)
+ setlocale(LC_CTYPE, "");
+#endif
+#if defined(LC_COLLATE)
+ setlocale(LC_COLLATE, "");
+#endif
+#if defined(LC_MESSAGES)
+ setlocale(LC_MESSAGES, "");
+#endif
+#if defined(LC_NUMERIC)
+ /*
+ * Force the issue here. According to POSIX 2001, decimal
+ * point is used for parsing source code and for command-line
+ * assignments and the locale value for processing input,
+ * number to string conversion, and printing output.
+ */
+ setlocale(LC_NUMERIC, "C");
+#endif
+#if defined(LC_TIME)
+ setlocale(LC_TIME, "");
+#endif
+
+#ifdef MBS_SUPPORT
+ /*
+ * In glibc, MB_CUR_MAX is actually a function. This value is
+ * tested *a lot* in many speed-critical places in gawk. Caching
+ * this value once makes a speed difference.
+ */
+ gawk_mb_cur_max = MB_CUR_MAX;
+ /* Without MBS_SUPPORT, gawk_mb_cur_max is 1. */
+#endif
+
+ (void) bindtextdomain(PACKAGE, LOCALEDIR);
+ (void) textdomain(PACKAGE);
+
+ (void) signal(SIGFPE, catchsig);
+ (void) signal(SIGSEGV, catchsig);
+#ifdef SIGBUS
+ (void) signal(SIGBUS, catchsig);
+#endif
+
+ myname = gawk_name(argv[0]);
+ argv[0] = (char *) myname;
+ os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
+
+ /* remove sccs gunk */
+ if (strncmp(version_string, "@(#)", 4) == 0)
+ version_string += 4;
+
+ if (argc < 2)
+ usage(1, stderr);
+
+ /* Robustness: check that file descriptors 0, 1, 2 are open */
+ init_fds();
+
+ /* init array handling. */
+ array_init();
+
+ /* we do error messages ourselves on invalid options */
+ opterr = FALSE;
+
+ /* option processing. ready, set, go! */
+ for (optopt = 0, old_optind = 1;
+ (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
+ optopt = 0, old_optind = optind) {
+ if (do_posix)
+ opterr = TRUE;
+
+ switch (c) {
+ case 'F':
+ preassigns_add(PRE_ASSIGN_FS, optarg);
+ break;
+
+ case 'S':
+ disallow_var_assigns = TRUE;
+ /* fall through */
+ case 'f':
+ /*
+ * a la MKS awk, allow multiple -f options.
+ * this makes function libraries real easy.
+ * most of the magic is in the scanner.
+ *
+ * The following is to allow for whitespace at the end
+ * of a #! /bin/gawk line in an executable file
+ */
+ scan = optarg;
+ if (argv[optind-1] != optarg)
+ while (ISSPACE(*scan))
+ scan++;
+ srcfiles_add(SOURCEFILE,
+ (*scan == '\0' ? argv[optind++] : optarg));
+ break;
+
+ case 'v':
+ preassigns_add(PRE_ASSIGN, optarg);
+ break;
+
+ case 'm':
+ /*
+ * Research awk extension.
+ * -mf nnn set # fields, gawk ignores
+ * -mr nnn set record length, ditto
+ */
+ if (do_lint)
+ lintwarn(_("`-m[fr]' option irrelevant in gawk"));
+ if (optarg[0] != 'r' && optarg[0] != 'f')
+ warning(_("-m option usage: `-m[fr] nnn'"));
+ /*
+ * Set fixed length records for Tandem,
+ * ignored on other platforms (see io.c:get_a_record).
+ */
+ if (optarg[0] == 'r') {
+ if (ISDIGIT(optarg[1]))
+ MRL = atoi(optarg+1);
+ else {
+ MRL = atoi(argv[optind]);
+ optind++;
+ }
+ } else if (optarg[1] == '\0')
+ optind++;
+ break;
+
+ case 'W': /* gawk specific options - now in getopt_long */
+ fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
+ argv[0], optarg);
+ break;
+
+ /* These can only come from long form options */
+ case 'C':
+ copyleft();
+ break;
+
+ case 'd':
+ do_dump_vars = TRUE;
+ if (optarg != NULL && optarg[0] != '\0')
+ varfile = optarg;
+ break;
+
+ case 'l':
+#ifndef NO_LINT
+ do_lint = LINT_ALL;
+ if (optarg != NULL) {
+ if (strcmp(optarg, "fatal") == 0)
+ lintfunc = r_fatal;
+ else if (strcmp(optarg, "invalid") == 0)
+ do_lint = LINT_INVALID;
+ }
+#endif
+ break;
+
+ case 'p':
+ do_profiling = TRUE;
+ if (optarg != NULL)
+ set_prof_file(optarg);
+ else
+ set_prof_file(DEFAULT_PROFILE);
+ break;
+
+ case 's':
+ if (optarg[0] == '\0')
+ warning(_("empty argument to `--source' ignored"));
+ else
+ srcfiles_add(CMDLINE, optarg);
+ break;
+
+ case 'u':
+ usage(0, stdout); /* per coding stds */
+ break;
+
+ case 'V':
+ version();
+ break;
+
+ case 0:
+ /*
+ * getopt_long found an option that sets a variable
+ * instead of returning a letter. Do nothing, just
+ * cycle around for the next one.
+ */
+ break;
+
+ case 'D':
+#ifdef GAWKDEBUG
+ yydebug = 2;
+ break;
+#endif
+ /* if not debugging, fall through */
+
+ case '?':
+ default:
+ /*
+ * New behavior. If not posix, an unrecognized
+ * option stops argument processing so that it can
+ * go into ARGV for the awk program to see. This
+ * makes use of ``#! /bin/gawk -f'' easier.
+ *
+ * However, it's never simple. If optopt is set,
+ * an option that requires an argument didn't get the
+ * argument. We care because if opterr is 0, then
+ * getopt_long won't print the error message for us.
+ */
+ if (! do_posix
+ && (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
+ /*
+ * can't just do optind--. In case of an
+ * option with >= 2 letters, getopt_long
+ * won't have incremented optind.
+ */
+ optind = old_optind;
+ stopped_early = TRUE;
+ goto out;
+ } else if (optopt != '\0')
+ /* Use 1003.2 required message format */
+ fprintf(stderr,
+ _("%s: option requires an argument -- %c\n"),
+ myname, optopt);
+ /* else
+ let getopt print error message for us */
+ break;
+ }
+ if (c == 'S') /* --exec ends option processing */
+ break;
+ }
+out:
+
+ if (do_nostalgia)
+ nostalgia();
+
+ /* check for POSIXLY_CORRECT environment variable */
+ if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
+ do_posix = TRUE;
+ if (do_lint)
+ lintwarn(
+ _("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
+ }
+
+ if (do_posix) {
+ if (do_traditional) /* both on command line */
+ warning(_("`--posix' overrides `--traditional'"));
+ else
+ do_traditional = TRUE;
+ /*
+ * POSIX compliance also implies
+ * no GNU extensions either.
+ */
+ }
+
+ if (do_traditional && do_non_decimal_data) {
+ do_non_decimal_data = FALSE;
+ warning(_("`--posix'/`--traditional' overrides `--non-decimal-data'"));
+ }
+
+ if (do_lint && os_is_setuid())
+ warning(_("running %s setuid root may be a security problem"), myname);
+
+ /*
+ * Force profiling if this is pgawk.
+ * Don't bother if the command line already set profiling up.
+ */
+ if (! do_profiling)
+ init_profiling(& do_profiling, DEFAULT_PROFILE);
+
+ /* load group set */
+ init_groupset();
+
+ /* initialize the null string */
+ Nnull_string = make_string("", 0);
+ Nnull_string->numbr = 0.0;
+ Nnull_string->type = Node_val;
+ Nnull_string->flags = (PERM|STRCUR|STRING|NUMCUR|NUMBER);
+
+ /*
+ * Tell the regex routines how they should work.
+ * Do this before initializing variables, since
+ * they could want to do a regexp compile.
+ */
+ resetup();
+
+ /* Set up the special variables */
+ init_vars();
+
+ /* Set up the field variables */
+ init_fields();
+
+ /* Now process the pre-assignments */
+ for (i = 0; i <= numassigns; i++)
+ if (preassigns[i].stype == PRE_ASSIGN)
+ (void) arg_assign(preassigns[i].val, TRUE);
+ else /* PRE_ASSIGN_FS */
+ cmdline_fs(preassigns[i].val);
+ free(preassigns);
+
+ if ((BINMODE & 1) != 0)
+ if (os_setbinmode(fileno(stdin), O_BINARY) == -1)
+ fatal(_("can't set binary mode on stdin (%s)"), strerror(errno));
+ if ((BINMODE & 2) != 0) {
+ if (os_setbinmode(fileno(stdout), O_BINARY) == -1)
+ fatal(_("can't set binary mode on stdout (%s)"), strerror(errno));
+ if (os_setbinmode(fileno(stderr), O_BINARY) == -1)
+ fatal(_("can't set binary mode on stderr (%s)"), strerror(errno));
+ }
+
+#ifdef GAWKDEBUG
+ setbuf(stdout, (char *) NULL); /* make debugging easier */
+#endif
+ if (isatty(fileno(stdout)))
+ output_is_tty = TRUE;
+ /* No -f or --source options, use next arg */
+ if (numfiles == -1) {
+ if (optind > argc - 1 || stopped_early) /* no args left or no program */
+ usage(1, stderr);
+ srcfiles_add(CMDLINE, argv[optind]);
+ optind++;
+ }
+
+ init_args(optind, argc, (char *) myname, argv);
+ (void) tokexpand();
+
+#if defined(LC_NUMERIC)
+ /*
+ * FRAGILE! CAREFUL!
+ * Pre-initing the variables with arg_assign() can change the
+ * locale. Force it to C before parsing the program.
+ */
+ setlocale(LC_NUMERIC, "C");
+#endif
+
+ /* Read in the program */
+ if (yyparse() != 0 || errcount != 0)
+ exit(1);
+
+ free(srcfiles);
+
+ if (do_intl)
+ exit(0);
+
+ if (do_lint && begin_block == NULL && expression_value == NULL
+ && end_block == NULL)
+ lintwarn(_("no program text at all!"));
+
+ if (do_lint)
+ shadow_funcs();
+
+ init_profiling_signals();
+
+#if defined(LC_NUMERIC)
+ /* See comment above. */
+ setlocale(LC_NUMERIC, "");
+#endif
+
+#if defined(HAVE_LOCALE_H)
+ loc = *localeconv(); /* Make a local copy of locale numeric info */
+#endif
+
+ /* Whew. Finally, run the program. */
+ if (begin_block != NULL) {
+ in_begin_rule = TRUE;
+ (void) interpret(begin_block);
+ }
+ in_begin_rule = FALSE;
+ if (! exiting && (expression_value != NULL || end_block != NULL))
+ do_input();
+ if (end_block != NULL) {
+ in_end_rule = TRUE;
+ (void) interpret(end_block);
+ }
+ in_end_rule = FALSE;
+ /*
+ * This used to be:
+ *
+ * if (close_io() != 0 && ! exiting && exit_val == 0)
+ * exit_val = 1;
+ *
+ * Other awks don't care about problems closing open files
+ * and pipes, in that it doesn't affect their exit status.
+ * So we no longer do either.
+ */
+ (void) close_io(& stdio_problem);
+ /*
+ * However, we do want to exit non-zero if there was a problem
+ * with stdout/stderr, so we reinstate a slightly different
+ * version of the above:
+ */
+ if (stdio_problem && ! exiting && exit_val == 0)
+ exit_val = 1;
+
+ if (do_profiling) {
+ dump_prog(begin_block, expression_value, end_block);
+ dump_funcs();
+ }
+
+ if (do_dump_vars)
+ dump_vars(varfile);
+
+ if (do_tidy_mem)
+ release_all_vars();
+
+ exit(exit_val); /* more portable */
+ return exit_val; /* to suppress warnings */
+}
+
+/* add_src --- add one element to *srcfiles or *preassigns */
+
+static void
+add_src(struct src **data, long *num, long *alloc, enum srctype stype, char *val)
+{
+#define INIT_SRC 4
+
+ ++*num;
+
+ if (*data == NULL) {
+ emalloc(*data, struct src *, INIT_SRC * sizeof(struct src), "add_src");
+ *alloc = INIT_SRC;
+ } else if (*num >= *alloc) {
+ (*alloc) *= 2;
+ erealloc(*data, struct src *, (*alloc) * sizeof(struct src), "add_src");
+ }
+
+ (*data)[*num].stype = stype;
+ (*data)[*num].val = val;
+
+#undef INIT_SRC
+}
+
+/* usage --- print usage information and exit */
+
+static void
+usage(int exitval, FILE *fp)
+{
+
+ /* Not factoring out common stuff makes it easier to translate. */
+ fprintf(fp, _("Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"),
+ myname);
+ fprintf(fp, _("Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"),
+ myname, quote, quote);
+
+ /* GNU long options info. This is too many options. */
+
+ fputs(_("POSIX options:\t\tGNU long options:\n"), fp);
+ fputs(_("\t-f progfile\t\t--file=progfile\n"), fp);
+ fputs(_("\t-F fs\t\t\t--field-separator=fs\n"), fp);
+ fputs(_("\t-v var=val\t\t--assign=var=val\n"), fp);
+ fputs(_("\t-m[fr] val\n"), fp);
+ fputs(_("\t-W compat\t\t--compat\n"), fp);
+ fputs(_("\t-W copyleft\t\t--copyleft\n"), fp);
+ fputs(_("\t-W copyright\t\t--copyright\n"), fp);
+ fputs(_("\t-W dump-variables[=file]\t--dump-variables[=file]\n"), fp);
+ fputs(_("\t-W exec=file\t\t--exec=file\n"), fp);
+ fputs(_("\t-W gen-po\t\t--gen-po\n"), fp);
+ fputs(_("\t-W help\t\t\t--help\n"), fp);
+ fputs(_("\t-W lint[=fatal]\t\t--lint[=fatal]\n"), fp);
+ fputs(_("\t-W lint-old\t\t--lint-old\n"), fp);
+ fputs(_("\t-W non-decimal-data\t--non-decimal-data\n"), fp);
+#ifdef NOSTALGIA
+ fputs(_("\t-W nostalgia\t\t--nostalgia\n"), fp);
+#endif
+#ifdef GAWKDEBUG
+ fputs(_("\t-W parsedebug\t\t--parsedebug\n"), fp);
+#endif
+ fputs(_("\t-W profile[=file]\t--profile[=file]\n"), fp);
+ fputs(_("\t-W posix\t\t--posix\n"), fp);
+ fputs(_("\t-W re-interval\t\t--re-interval\n"), fp);
+ fputs(_("\t-W source=program-text\t--source=program-text\n"), fp);
+ fputs(_("\t-W traditional\t\t--traditional\n"), fp);
+ fputs(_("\t-W usage\t\t--usage\n"), fp);
+ fputs(_("\t-W version\t\t--version\n"), fp);
+
+
+ /* This is one string to make things easier on translators. */
+ fputs(_("\nTo report bugs, see node `Bugs' in `gawk.info', which is\n\
+section `Reporting Problems and Bugs' in the printed version.\n\n"), fp);
+
+ /* ditto */
+ fputs(_("gawk is a pattern scanning and processing language.\n\
+By default it reads standard input and writes standard output.\n\n"), fp);
+
+ /* ditto */
+ fputs(_("Examples:\n\tgawk '{ sum += $1 }; END { print sum }' file\n\
+\tgawk -F: '{ print $1 }' /etc/passwd\n"), fp);
+
+ fflush(fp);
+
+ if (ferror(fp)) {
+ if (fp == stdout)
+ warning(_("error writing standard output (%s)"), strerror(errno));
+ exit(1);
+ }
+
+ exit(exitval);
+}
+
+/* copyleft --- print out the short GNU copyright information */
+
+static void
+copyleft()
+{
+ static const char blurb_part1[] =
+ N_("Copyright (C) 1989, 1991-%d Free Software Foundation.\n\
+\n\
+This program is free software; you can redistribute it and/or modify\n\
+it under the terms of the GNU General Public License as published by\n\
+the Free Software Foundation; either version 2 of the License, or\n\
+(at your option) any later version.\n\
+\n");
+ static const char blurb_part2[] =
+ N_("This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
+GNU General Public License for more details.\n\
+\n");
+ static const char blurb_part3[] =
+ N_("You should have received a copy of the GNU General Public License\n\
+along with this program; if not, write to the Free Software\n\
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n");
+
+ /* multiple blurbs are needed for some brain dead compilers. */
+ printf(_(blurb_part1), UPDATE_YEAR); /* Last update year */
+ fputs(_(blurb_part2), stdout);
+ fputs(_(blurb_part3), stdout);
+ fflush(stdout);
+
+ if (ferror(stdout)) {
+ warning(_("error writing standard output (%s)"), strerror(errno));
+ exit(1);
+ }
+
+ exit(0);
+}
+
+/* cmdline_fs --- set FS from the command line */
+
+static void
+cmdline_fs(char *str)
+{
+ register NODE **tmp;
+
+ tmp = get_lhs(FS_node, (Func_ptr *) 0, FALSE);
+ unref(*tmp);
+ /*
+ * Only if in full compatibility mode check for the stupid special
+ * case so -F\t works as documented in awk book even though the shell
+ * hands us -Ft. Bleah!
+ *
+ * Thankfully, Posix didn't propagate this "feature".
+ */
+ if (str[0] == 't' && str[1] == '\0') {
+ if (do_lint)
+ lintwarn(_("-Ft does not set FS to tab in POSIX awk"));
+ if (do_traditional && ! do_posix)
+ str[0] = '\t';
+ }
+ *tmp = make_str_node(str, strlen(str), SCAN); /* do process escapes */
+ set_FS();
+}
+
+/* init_args --- set up ARGV from stuff on the command line */
+
+static void
+init_args(int argc0, int argc, char *argv0, char **argv)
+{
+ int i, j;
+ NODE **aptr;
+
+ ARGV_node = install("ARGV", node((NODE *) NULL, Node_var_array, (NODE *) NULL));
+ aptr = assoc_lookup(ARGV_node, tmp_number(0.0), FALSE);
+ *aptr = make_string(argv0, strlen(argv0));
+ (*aptr)->flags |= MAYBE_NUM;
+ for (i = argc0, j = 1; i < argc; i++) {
+ aptr = assoc_lookup(ARGV_node, tmp_number((AWKNUM) j), FALSE);
+ *aptr = make_string(argv[i], strlen(argv[i]));
+ (*aptr)->flags |= MAYBE_NUM;
+ j++;
+ }
+ ARGC_node = install("ARGC",
+ node(make_number((AWKNUM) j), Node_var, (NODE *) NULL));
+}
+
+/*
+ * Set all the special variables to their initial values.
+ * Note that some of the variables that have set_FOO routines should
+ * *N*O*T* have those routines called upon initialization, and thus
+ * they have NULL entries in that field. This is notably true of FS
+ * and IGNORECASE.
+ */
+struct varinit {
+ NODE **spec;
+ const char *name;
+ NODETYPE type;
+ const char *strval;
+ AWKNUM numval;
+ Func_ptr assign;
+};
+static const struct varinit varinit[] = {
+{&CONVFMT_node, "CONVFMT", Node_CONVFMT, "%.6g", 0, set_CONVFMT },
+{&NF_node, "NF", Node_NF, NULL, -1, NULL },
+{&FIELDWIDTHS_node, "FIELDWIDTHS", Node_FIELDWIDTHS, "", 0, NULL },
+{&NR_node, "NR", Node_NR, NULL, 0, set_NR },
+{&FNR_node, "FNR", Node_FNR, NULL, 0, set_FNR },
+{&FS_node, "FS", Node_FS, " ", 0, NULL },
+{&RS_node, "RS", Node_RS, "\n", 0, set_RS },
+{&IGNORECASE_node, "IGNORECASE", Node_IGNORECASE, NULL, 0, NULL },
+{&FILENAME_node, "FILENAME", Node_var, "", 0, NULL },
+{&OFS_node, "OFS", Node_OFS, " ", 0, set_OFS },
+{&ORS_node, "ORS", Node_ORS, "\n", 0, set_ORS },
+{&OFMT_node, "OFMT", Node_OFMT, "%.6g", 0, set_OFMT },
+{&RLENGTH_node, "RLENGTH", Node_var, NULL, 0, NULL },
+{&RSTART_node, "RSTART", Node_var, NULL, 0, NULL },
+{&SUBSEP_node, "SUBSEP", Node_SUBSEP, "\034", 0, NULL },
+{&ARGIND_node, "ARGIND", Node_var, NULL, 0, NULL },
+{&ERRNO_node, "ERRNO", Node_var, NULL, 0, NULL },
+{&RT_node, "RT", Node_var, "", 0, NULL },
+{&BINMODE_node, "BINMODE", Node_BINMODE, NULL, 0, NULL },
+{&LINT_node, "LINT", Node_LINT, NULL, 0, NULL },
+{&TEXTDOMAIN_node, "TEXTDOMAIN", Node_TEXTDOMAIN, "messages", 0, set_TEXTDOMAIN },
+{0, NULL, Node_illegal, NULL, 0, NULL },
+};
+
+/* init_vars --- actually initialize everything in the symbol table */
+
+static void
+init_vars()
+{
+ register const struct varinit *vp;
+
+ for (vp = varinit; vp->name; vp++) {
+ *(vp->spec) = install((char *) vp->name,
+ node(vp->strval == NULL ? make_number(vp->numval)
+ : make_string((char *) vp->strval,
+ strlen(vp->strval)),
+ vp->type, (NODE *) NULL));
+ if (vp->assign)
+ (*(vp->assign))();
+ }
+
+ /* Set up deferred variables (loaded only when accessed). */
+ if (! do_traditional)
+ register_deferred_variable("PROCINFO", load_procinfo);
+ register_deferred_variable("ENVIRON", load_environ);
+}
+
+/* load_environ --- populate the ENVIRON array */
+
+static NODE *
+load_environ()
+{
+#if ! defined(TANDEM)
+#if ! (defined(MSDOS) && !defined(DJGPP)) && ! defined(OS2) && ! (defined(VMS) && defined(__DECC))
+ extern char **environ;
+#endif
+ register char *var, *val;
+ NODE **aptr;
+ register int i;
+#endif /* TANDEM */
+
+ ENVIRON_node = install("ENVIRON",
+ node((NODE *) NULL, Node_var_array, (NODE *) NULL));
+#if ! defined(TANDEM)
+ for (i = 0; environ[i] != NULL; i++) {
+ static char nullstr[] = "";
+
+ var = environ[i];
+ val = strchr(var, '=');
+ if (val != NULL)
+ *val++ = '\0';
+ else
+ val = nullstr;
+ aptr = assoc_lookup(ENVIRON_node, tmp_string(var, strlen(var)),
+ FALSE);
+ *aptr = make_string(val, strlen(val));
+ (*aptr)->flags |= MAYBE_NUM;
+
+ /* restore '=' so that system() gets a valid environment */
+ if (val != nullstr)
+ *--val = '=';
+ }
+ /*
+ * Put AWKPATH into ENVIRON if it's not there.
+ * This allows querying it from within awk programs.
+ */
+ if (getenv("AWKPATH") == NULL) {
+ aptr = assoc_lookup(ENVIRON_node, tmp_string("AWKPATH", 7), FALSE);
+ *aptr = make_string(defpath, strlen(defpath));
+ }
+#endif /* TANDEM */
+ return ENVIRON_node;
+}
+
+/* load_procinfo --- populate the PROCINFO array */
+
+static NODE *
+load_procinfo()
+{
+ int i;
+ NODE **aptr;
+ char name[100];
+ AWKNUM value;
+
+ PROCINFO_node = install("PROCINFO",
+ node((NODE *) NULL, Node_var_array, (NODE *) NULL));
+
+#ifdef GETPGRP_VOID
+#define getpgrp_arg() /* nothing */
+#else
+#define getpgrp_arg() getpid()
+#endif
+
+ value = getpgrp(getpgrp_arg());
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("pgrpid", 6), FALSE);
+ *aptr = make_number(value);
+
+ /*
+ * could put a lot of this into a table, but then there's
+ * portability problems declaring all the functions. so just
+ * do it the slow and stupid way. sigh.
+ */
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("version", 7), FALSE);
+ *aptr = make_string(VERSION, strlen(VERSION));
+
+ value = getpid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE);
+ *aptr = make_number(value);
+
+ value = getppid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE);
+ *aptr = make_number(value);
+
+ value = getuid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("uid", 3), FALSE);
+ *aptr = make_number(value);
+
+ value = geteuid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("euid", 4), FALSE);
+ *aptr = make_number(value);
+
+ value = getgid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("gid", 3), FALSE);
+ *aptr = make_number(value);
+
+ value = getegid();
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("egid", 4), FALSE);
+ *aptr = make_number(value);
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("FS", 2), FALSE);
+ *aptr = (using_fieldwidths() ? make_string("FIELDWIDTHS", 11) :
+ make_string("FS", 2) );
+
+#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
+ for (i = 0; i < ngroups; i++) {
+ sprintf(name, "group%d", i + 1);
+ value = groupset[i];
+ aptr = assoc_lookup(PROCINFO_node, tmp_string(name, strlen(name)), FALSE);
+ *aptr = make_number(value);
+ }
+ if (groupset) {
+ free(groupset);
+ groupset = NULL;
+ }
+#endif
+ return PROCINFO_node;
+}
+
+/* arg_assign --- process a command-line assignment */
+
+int
+arg_assign(char *arg, int initing)
+{
+ char *cp, *cp2;
+ int badvar;
+ Func_ptr after_assign = NULL;
+ NODE *var;
+ NODE *it;
+ NODE **lhs;
+
+ if (! initing && disallow_var_assigns)
+ return FALSE; /* --exec */
+
+ cp = strchr(arg, '=');
+
+ if (cp == NULL) {
+ if (! initing)
+ return FALSE; /* This is file name, not assignment. */
+
+ fprintf(stderr,
+ _("%s: `%s' argument to `-v' not in `var=value' form\n\n"),
+ myname, arg);
+ usage(1, stderr);
+ }
+
+ *cp++ = '\0';
+
+ /* first check that the variable name has valid syntax */
+ badvar = FALSE;
+ if (! ISALPHA(arg[0]) && arg[0] != '_')
+ badvar = TRUE;
+ else
+ for (cp2 = arg+1; *cp2; cp2++)
+ if (! ISALNUM(*cp2) && *cp2 != '_') {
+ badvar = TRUE;
+ break;
+ }
+
+ if (badvar) {
+ if (initing)
+ fatal(_("`%s' is not a legal variable name"), arg);
+
+ if (do_lint)
+ lintwarn(_("`%s' is not a variable name, looking for file `%s=%s'"),
+ arg, arg, cp);
+ } else {
+ /*
+ * Recent versions of nawk expand escapes inside assignments.
+ * This makes sense, so we do it too.
+ */
+ it = make_str_node(cp, strlen(cp), SCAN);
+ it->flags |= MAYBE_NUM;
+#ifdef LC_NUMERIC
+ setlocale(LC_NUMERIC, "C");
+ (void) force_number(it);
+ setlocale(LC_NUMERIC, "");
+#endif /* LC_NUMERIC */
+ var = variable(arg, FALSE, Node_var);
+ lhs = get_lhs(var, &after_assign, FALSE);
+ unref(*lhs);
+ *lhs = it;
+ if (after_assign != NULL)
+ (*after_assign)();
+ }
+
+ *--cp = '='; /* restore original text of ARGV */
+
+ return ! badvar;
+}
+
+/* catchsig --- catch signals */
+
+static RETSIGTYPE
+catchsig(int sig)
+{
+ if (sig == SIGFPE) {
+ fatal(_("floating point exception"));
+ } else if (sig == SIGSEGV
+#ifdef SIGBUS
+ || sig == SIGBUS
+#endif
+ ) {
+ set_loc(__FILE__, __LINE__);
+ msg(_("fatal error: internal error"));
+ /* fatal won't abort() if not compiled for debugging */
+ abort();
+ } else
+ cant_happen();
+ /* NOTREACHED */
+}
+
+/* nostalgia --- print the famous error message and die */
+
+static void
+nostalgia()
+{
+ /*
+ * N.B.: This string is not gettextized, on purpose.
+ * So there.
+ */
+ fprintf(stderr, "awk: bailing out near line 1\n");
+ fflush(stderr);
+ abort();
+}
+
+/* version --- print version message */
+
+static void
+version()
+{
+ printf("%s\n", version_string);
+ /*
+ * Per GNU coding standards, print copyright info,
+ * then exit successfully, do nothing else.
+ */
+ copyleft();
+ exit(0);
+}
+
+/* init_fds --- check for 0, 1, 2, open on /dev/null if possible */
+
+static void
+init_fds()
+{
+ struct stat sbuf;
+ int fd;
+ int newfd;
+ char const *const opposite_mode[] = {"w", "r", "r"};
+
+ /* maybe no stderr, don't bother with error mesg */
+ for (fd = 0; fd <= 2; fd++) {
+ if (fstat(fd, &sbuf) < 0) {
+#if MAKE_A_HEROIC_EFFORT
+ if (do_lint)
+ lintwarn(_("no pre-opened fd %d"), fd);
+#endif
+ newfd = devopen("/dev/null", opposite_mode[fd]);
+ /* turn off some compiler warnings "set but not used" */
+ newfd += 0;
+#ifdef MAKE_A_HEROIC_EFFORT
+ if (do_lint && newfd < 0)
+ lintwarn(_("could not pre-open /dev/null for fd %d"), fd);
+#endif
+ }
+ }
+}
+
+/* init_groupset --- initialize groupset */
+
+static void
+init_groupset()
+{
+#if defined(HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
+#ifdef GETGROUPS_NOT_STANDARD
+ /* For systems that aren't standards conformant, use old way. */
+ ngroups = NGROUPS_MAX;
+#else
+ /*
+ * If called with 0 for both args, return value is
+ * total number of groups.
+ */
+ ngroups = getgroups(0, NULL);
+#endif
+ if (ngroups == -1)
+ fatal(_("could not find groups: %s"), strerror(errno));
+ else if (ngroups == 0)
+ return;
+
+ /* fill in groups */
+ emalloc(groupset, GETGROUPS_T *, ngroups * sizeof(GETGROUPS_T), "init_groupset");
+
+ ngroups = getgroups(ngroups, groupset);
+ if (ngroups == -1)
+ fatal(_("could not find groups: %s"), strerror(errno));
+#endif
+}
--- /dev/null
+/*
+ * mbsupport.h --- Localize determination of whether we have multibyte stuff.
+ */
+
+/*
+ * Copyright (C) 2004, 2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * This file is needed because we test for i18n support in 3 different
+ * places, and we want a consistent definition in all of them. Following
+ * the ``Don't Repeat Yourself'' principle from "The Pragmatic Programmer",
+ * we centralize the tests here.
+ *
+ * This test is the union of all the current tests.
+ */
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_ISWCTYPE) \
+ && defined(HAVE_LOCALE_H) \
+ && defined(HAVE_MBRLEN) \
+ && defined(HAVE_MBRTOWC) \
+ && defined(HAVE_WCHAR_H) \
+ && defined(HAVE_WCRTOMB) \
+ && defined(HAVE_WCSCOLL) \
+ && defined(HAVE_WCTYPE) \
+ && defined(HAVE_WCTYPE_H) \
+ && defined(HAVE_WCTYPE_T) \
+ && defined(HAVE_WINT_T) \
+ && defined(HAVE_ISWLOWER) \
+ && defined(HAVE_ISWUPPER) \
+ && defined(HAVE_TOWLOWER) \
+ && defined(HAVE_TOWUPPER) \
+ && (defined(HAVE_STDLIB_H) && defined(MB_CUR_MAX)) \
+/* We can handle multibyte strings. */
+# define MBS_SUPPORT 1
+#else
+# undef MBS_SUPPORT
+#endif
--- /dev/null
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-02-08.22
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Tue Jul 26 21:27:46 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strtod.c (gawk_strtod) [ENABLE_NLS]: Removed from conditional
+ paralleling change to main.c.
+ * stroul.c (strtoul): Same.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon May 3 09:24:21 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strtoul.c: New file.
+
+Sun May 2 18:03:54 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strtod.c (gawk_strtod): Check for locale's decimal point
+ instead of hard-wiring period.
+
+Tue Jan 20 10:38:48 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * memmove.c: New file.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Mon Feb 3 20:37:09 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * strftime.c: Restore use of TIME_T_IN_SYS_TYPES_H to control
+ inclusion of <sys/types.h>.
+ (TYPE_SIGNED): Add workaround to avoid diagnostic from Compaq C V6.4.
+ (my_strftime) [case 's']: Likewise; exclude negative number handling
+ if TIME_T_UNSIGNED is defined.
+
+Mon Jan 27 12:09:50 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * strtod.c (gawk_strtod): Cleanup, changing the logic
+ so that ptr is correct. Fixes the bug that 0e0 is not
+ recognized as numeric.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Tue Dec 4 17:56:46 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strftime.c: Replaced with glibc version.
+ * strftime.3: Removed
+
+Fri Aug 3 09:01:19 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ ChangeLog created.
+
+ * strtod.c (strtod): Fixed test at end for failure to
+ be a little smarter.
--- /dev/null
+/*
+ * memcmp --- compare strings.
+ *
+ * We use our own routine since it has to act like strcmp() for return
+ * value, and the BSD manual says bcmp() only returns zero/non-zero.
+ */
+
+int
+memcmp (s1, s2, l)
+register char *s1, *s2;
+register int l;
+{
+ for (; l-- > 0; s1++, s2++) {
+ if (*s1 != *s2)
+ return (*s1 - *s2);
+ }
+ return (0);
+}
--- /dev/null
+/*
+ * memcpy --- copy strings.
+ *
+ * We supply this routine for those systems that aren't standard yet.
+ */
+
+char *
+memcpy (dest, src, l)
+register char *dest, *src;
+register int l;
+{
+ register char *ret = dest;
+
+ while (l--)
+ *dest++ = *src++;
+
+ return ret;
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+#endif
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef int word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/* ADR: 1/2004. For gawk, we need memmove(). */
+#define MEMMOVE 1
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+#ifdef MEMCOPY
+void *
+memcpy(dst0, src0, length)
+#else
+#ifdef MEMMOVE
+void *
+memmove(dst0, src0, length)
+#else
+void
+bcopy(src0, dst0, length)
+#endif
+#endif
+ void *dst0;
+ const void *src0;
+ register size_t length;
+{
+ register char *dst = dst0;
+ register const char *src = src0;
+ register size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (int)src; /* only need low bits */
+ if ((t | (int)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (int)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (int)src;
+ if ((t | (int)dst) & wmask) {
+ if ((t ^ (int)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ return (dst0);
+#else
+ return;
+#endif
+}
+#undef wsize
+#undef wmask
+#undef MEMMOVE
+#undef TLOOP
+#undef TLOOP1
--- /dev/null
+/*
+ * memset --- initialize memory
+ *
+ * We supply this routine for those systems that aren't standard yet.
+ */
+
+void *
+memset(dest, val, l)
+void *dest;
+register int val;
+register size_t l;
+{
+ register char *ret = dest;
+ register char *d = dest;
+
+ while (l--)
+ *d++ = val;
+
+ return ((void *) ret);
+}
--- /dev/null
+/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Eggert (eggert@twinsun.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* Define this to have a standalone program to test this implementation of
+ mktime. */
+/* #define DEBUG 1 */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _LIBC
+# define HAVE_LIMITS_H 1
+# define HAVE_LOCALTIME_R 1
+# define STDC_HEADERS 1
+#endif
+
+/* Assume that leap seconds are possible, unless told otherwise.
+ If the host has a `zic' command with a `-L leapsecondfilename' option,
+ then it supports leap seconds; otherwise it probably doesn't. */
+#ifndef LEAP_SECONDS_POSSIBLE
+#define LEAP_SECONDS_POSSIBLE 1
+#endif
+
+#ifndef VMS
+#include <sys/types.h> /* Some systems define `time_t' here. */
+#else
+#include <stddef.h>
+#endif
+#include <time.h>
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#if DEBUG
+#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+/* Make it work even if the system's libc has its own mktime routine. */
+#define mktime my_mktime
+#endif /* DEBUG */
+
+#ifndef __P
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif /* GCC. */
+#endif /* Not __P. */
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef INT_MIN
+#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
+#endif
+#ifndef INT_MAX
+#define INT_MAX (~0 - INT_MIN)
+#endif
+
+#ifndef TIME_T_MIN
+#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
+ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
+#endif
+#ifndef TIME_T_MAX
+#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
+#endif
+
+#define TM_YEAR_BASE 1900
+#define EPOCH_YEAR 1970
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+ except every 100th isn't, and every 400th is). */
+#define __isleap(year) \
+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+/* How many days come before each month (0-12). */
+const unsigned short int __mon_yday[2][13] =
+ {
+ /* Normal years. */
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ /* Leap years. */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+ };
+
+static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
+time_t __mktime_internal __P ((struct tm *,
+ struct tm *(*) (const time_t *, struct tm *),
+ time_t *));
+
+
+static struct tm *my_localtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+my_localtime_r (t, tp)
+ const time_t *t;
+ struct tm *tp;
+{
+ struct tm *l = localtime (t);
+ if (! l)
+ return 0;
+ *tp = *l;
+ return tp;
+}
+
+
+/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
+ measured in seconds, ignoring leap seconds.
+ YEAR uses the same numbering as TM->tm_year.
+ All values are in range, except possibly YEAR.
+ If overflow occurs, yield the low order bits of the correct answer. */
+static time_t
+ydhms_tm_diff (year, yday, hour, min, sec, tp)
+ int year, yday, hour, min, sec;
+ const struct tm *tp;
+{
+ /* Compute intervening leap days correctly even if year is negative.
+ Take care to avoid int overflow. time_t overflow is OK, since
+ only the low order bits of the correct time_t answer are needed.
+ Don't convert to time_t until after all divisions are done, since
+ time_t might be unsigned. */
+ int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
+ int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
+ int a100 = a4 / 25 - (a4 % 25 < 0);
+ int b100 = b4 / 25 - (b4 % 25 < 0);
+ int a400 = a100 >> 2;
+ int b400 = b100 >> 2;
+ int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+ time_t years = year - (time_t) tp->tm_year;
+ time_t days = (365 * years + intervening_leap_days
+ + (yday - tp->tm_yday));
+ return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+ + (min - tp->tm_min))
+ + (sec - tp->tm_sec));
+}
+
+
+static time_t localtime_offset;
+
+/* Convert *TP to a time_t value. */
+time_t
+mktime (tp)
+ struct tm *tp;
+{
+#ifdef _LIBC
+ /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
+ time zone names contained in the external variable `tzname' shall
+ be set as if the tzset() function had been called. */
+ __tzset ();
+#endif
+
+ return __mktime_internal (tp, my_localtime_r, &localtime_offset);
+}
+
+/* Convert *TP to a time_t value, inverting
+ the monotonic and mostly-unit-linear conversion function CONVERT.
+ Use *OFFSET to keep track of a guess at the offset of the result,
+ compared to what the result would be for UTC without leap seconds.
+ If *OFFSET's guess is correct, only one CONVERT call is needed. */
+time_t
+__mktime_internal (tp, convert, offset)
+ struct tm *tp;
+ struct tm *(*convert) __P ((const time_t *, struct tm *));
+ time_t *offset;
+{
+ time_t t, dt, t0;
+ struct tm tm;
+
+ /* The maximum number of probes (calls to CONVERT) should be enough
+ to handle any combinations of time zone rule changes, solar time,
+ and leap seconds. Posix.1 prohibits leap seconds, but some hosts
+ have them anyway. */
+ int remaining_probes = 4;
+
+ /* Time requested. Copy it in case CONVERT modifies *TP; this can
+ occur if TP is localtime's returned value and CONVERT is localtime. */
+ int sec = tp->tm_sec;
+ int min = tp->tm_min;
+ int hour = tp->tm_hour;
+ int mday = tp->tm_mday;
+ int mon = tp->tm_mon;
+ int year_requested = tp->tm_year;
+ int isdst = tp->tm_isdst;
+
+ /* Ensure that mon is in range, and set year accordingly. */
+ int mon_remainder = mon % 12;
+ int negative_mon_remainder = mon_remainder < 0;
+ int mon_years = mon / 12 - negative_mon_remainder;
+ int year = year_requested + mon_years;
+
+ /* The other values need not be in range:
+ the remaining code handles minor overflows correctly,
+ assuming int and time_t arithmetic wraps around.
+ Major overflows are caught at the end. */
+
+ /* Calculate day of year from year, month, and day of month.
+ The result need not be in range. */
+ int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
+ [mon_remainder + 12 * negative_mon_remainder])
+ + mday - 1);
+
+#if LEAP_SECONDS_POSSIBLE
+ /* Handle out-of-range seconds specially,
+ since ydhms_tm_diff assumes every minute has 60 seconds. */
+ int sec_requested = sec;
+ if (sec < 0)
+ sec = 0;
+ if (59 < sec)
+ sec = 59;
+#endif
+
+ /* Invert CONVERT by probing. First assume the same offset as last time.
+ Then repeatedly use the error to improve the guess. */
+
+ tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
+ tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
+
+ for (t = t0 + *offset;
+ (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
+ t += dt)
+ if (--remaining_probes == 0)
+ return -1;
+
+ /* Check whether tm.tm_isdst has the requested value, if any. */
+ if (0 <= isdst && 0 <= tm.tm_isdst)
+ {
+ int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
+ if (dst_diff)
+ {
+ /* Move two hours in the direction indicated by the disagreement,
+ probe some more, and switch to a new time if found.
+ The largest known fallback due to daylight savings is two hours:
+ once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
+ time_t ot = t - 2 * 60 * 60 * dst_diff;
+ while (--remaining_probes != 0)
+ {
+ struct tm otm;
+ if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
+ (*convert) (&ot, &otm))))
+ {
+ t = ot;
+ tm = otm;
+ break;
+ }
+ if ((ot += dt) == t)
+ break; /* Avoid a redundant probe. */
+ }
+ }
+ }
+
+ *offset = t - t0;
+
+#if LEAP_SECONDS_POSSIBLE
+ if (sec_requested != tm.tm_sec)
+ {
+ /* Adjust time to reflect the tm_sec requested, not the normalized value.
+ Also, repair any damage from a false match due to a leap second. */
+ t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
+ (*convert) (&t, &tm);
+ }
+#endif
+
+ if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
+ {
+ /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
+ so check for major overflows. A gross check suffices,
+ since if t has overflowed, it is off by a multiple of
+ TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
+ the difference that is bounded by a small value. */
+
+ double dyear = (double) year_requested + mon_years - tm.tm_year;
+ double dday = 366 * dyear + mday;
+ double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
+
+ if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
+ return -1;
+ }
+
+ *tp = tm;
+ return t;
+}
+
+#ifdef weak_alias
+weak_alias (mktime, timelocal)
+#endif
+\f
+#if DEBUG
+
+static int
+not_equal_tm (a, b)
+ struct tm *a;
+ struct tm *b;
+{
+ return ((a->tm_sec ^ b->tm_sec)
+ | (a->tm_min ^ b->tm_min)
+ | (a->tm_hour ^ b->tm_hour)
+ | (a->tm_mday ^ b->tm_mday)
+ | (a->tm_mon ^ b->tm_mon)
+ | (a->tm_year ^ b->tm_year)
+ | (a->tm_mday ^ b->tm_mday)
+ | (a->tm_yday ^ b->tm_yday)
+ | (a->tm_isdst ^ b->tm_isdst));
+}
+
+static void
+print_tm (tp)
+ struct tm *tp;
+{
+ printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
+ tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
+ tp->tm_hour, tp->tm_min, tp->tm_sec,
+ tp->tm_yday, tp->tm_wday, tp->tm_isdst);
+}
+
+static int
+check_result (tk, tmk, tl, tml)
+ time_t tk;
+ struct tm tmk;
+ time_t tl;
+ struct tm tml;
+{
+ if (tk != tl || not_equal_tm (&tmk, &tml))
+ {
+ printf ("mktime (");
+ print_tm (&tmk);
+ printf (")\nyields (");
+ print_tm (&tml);
+ printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int status = 0;
+ struct tm tm, tmk, tml;
+ time_t tk, tl;
+ char trailer;
+
+ if ((argc == 3 || argc == 4)
+ && (sscanf (argv[1], "%d-%d-%d%c",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
+ == 3)
+ && (sscanf (argv[2], "%d:%d:%d%c",
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
+ == 3))
+ {
+ tm.tm_year -= TM_YEAR_BASE;
+ tm.tm_mon--;
+ tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
+ tmk = tm;
+ tl = mktime (&tmk);
+ tml = *localtime (&tl);
+ printf ("mktime returns %ld == ", (long) tl);
+ print_tm (&tmk);
+ printf ("\n");
+ status = check_result (tl, tmk, tl, tml);
+ }
+ else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
+ {
+ time_t from = atol (argv[1]);
+ time_t by = atol (argv[2]);
+ time_t to = atol (argv[3]);
+
+ if (argc == 4)
+ for (tl = from; tl <= to; tl += by)
+ {
+ tml = *localtime (&tl);
+ tmk = tml;
+ tk = mktime (&tmk);
+ status |= check_result (tk, tmk, tl, tml);
+ }
+ else
+ for (tl = from; tl <= to; tl += by)
+ {
+ /* Null benchmark. */
+ tml = *localtime (&tl);
+ tmk = tml;
+ tk = tl;
+ status |= check_result (tk, tmk, tl, tml);
+ }
+ }
+ else
+ printf ("Usage:\
+\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
+\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
+\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
+ argv[0], argv[0], argv[0]);
+
+ return status;
+}
+
+#endif /* DEBUG */
+\f
+/*
+Local Variables:
+compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
+End:
+*/
--- /dev/null
+/*
+ * strchr --- search a string for a character
+ *
+ * We supply this routine for those systems that aren't standard yet.
+ */
+
+#if 0
+#include <stdio.h>
+#endif
+
+char *
+strchr(str, c)
+register const char *str, c;
+{
+ if (c == '\0') {
+ /* thanks to Mike Brennan ... */
+ do {
+ if (*str == c)
+ return (char *) str;
+ } while (*str++);
+ } else {
+ for (; *str; str++)
+ if (*str == c)
+ return (char *) str;
+ }
+
+ return NULL;
+}
+
+/*
+ * strrchr --- find the last occurrence of a character in a string
+ *
+ * We supply this routine for those systems that aren't standard yet.
+ */
+
+char *
+strrchr(str, c)
+register const char *str, c;
+{
+ register const char *save = NULL;
+
+ for (; *str; str++)
+ if (*str == c)
+ save = str;
+
+ return (char *) save;
+}
--- /dev/null
+/* strerror.c --- ANSI C compatible system error routine
+
+ Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if 0
+#include <stdio.h>
+#endif
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(n)
+int n;
+{
+ static char mesg[30];
+
+ if (n < 0 || n >= sys_nerr) {
+ sprintf(mesg, "Unknown error (%d)", n);
+ return mesg;
+ } else
+ return sys_errlist[n];
+}
--- /dev/null
+/* Copyright (C) 1991-1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# define HAVE_LIMITS_H 1
+# define HAVE_MBLEN 1
+# define HAVE_MBRLEN 1
+# define HAVE_STRUCT_ERA_ENTRY 1
+# define HAVE_TM_GMTOFF 1
+# define HAVE_TM_ZONE 1
+# define HAVE_TZNAME 1
+# define HAVE_TZSET 1
+# define MULTIBYTE_IS_FORMAT_SAFE 1
+# define STDC_HEADERS 1
+# include "../locale/localeinfo.h"
+#endif
+
+#if defined emacs && !defined HAVE_BCOPY
+# define HAVE_MEMCPY 1
+#endif
+
+#include <ctype.h>
+#ifdef TIME_T_IN_SYS_TYPES
+#include <sys/types.h> /* Some systems define `time_t' here. */
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_TZNAME
+extern char *tzname[];
+#endif
+
+/* Do multibyte processing if multibytes are supported, unless
+ multibyte sequences are safe in formats. Multibyte sequences are
+ safe if they cannot contain byte sequences that look like format
+ conversion specifications. The GNU C Library uses UTF8 multibyte
+ encoding, which is safe for formats, but strftime.c can be used
+ with other C libraries that use unsafe encodings. */
+#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
+
+#if DO_MULTIBYTE
+# if HAVE_MBRLEN
+# include <wchar.h>
+# else
+ /* Simulate mbrlen with mblen as best we can. */
+# define mbstate_t int
+# define mbrlen(s, n, ps) mblen (s, n)
+# define mbsinit(ps) (*(ps) == 0)
+# endif
+ static const mbstate_t mbstate_zero;
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#if STDC_HEADERS
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef COMPILE_WIDE
+# include <endian.h>
+# define CHAR_T wchar_t
+# define UCHAR_T unsigned int
+# define L_(Str) L##Str
+# define NLW(Sym) _NL_W##Sym
+
+# define MEMCPY(d, s, n) __wmemcpy (d, s, n)
+# define STRLEN(s) __wcslen (s)
+
+#else
+# define CHAR_T char
+# define UCHAR_T unsigned char
+# define L_(Str) Str
+# define NLW(Sym) Sym
+
+# if !defined STDC_HEADERS && !defined HAVE_MEMCPY
+# define MEMCPY(d, s, n) bcopy ((s), (d), (n))
+# else
+# define MEMCPY(d, s, n) memcpy ((d), (s), (n))
+# endif
+# define STRLEN(s) strlen (s)
+
+# ifdef _LIBC
+# define MEMPCPY(d, s, n) __mempcpy (d, s, n)
+# else
+# ifndef HAVE_MEMPCPY
+# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
+# endif
+# endif
+#endif
+
+#ifndef __P
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+# define __P(args) args
+# else
+# define __P(args) ()
+# endif /* GCC. */
+#endif /* Not __P. */
+
+#ifndef PTR
+# ifdef __STDC__
+# define PTR void *
+# else
+# define PTR char *
+# endif
+#endif
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+/* Test for checking whether a given type is signed or not.
+ Some compilers issue a diagnostic about suspicious construct for
+ a test that will always fail when comparing a value that can't be
+ negative against 0 using `<' or `<=' operator. */
+/* #define TYPE_SIGNED(t) ((t) -1 < 0) */
+#define TYPE_SIGNED(t) ((t) -1 < 1)
+
+#ifndef INT_STRLEN_BOUND
+/* Bound on length of the string representing an integer value of type t.
+ Subtract one for the sign bit if t is signed;
+ 302 / 1000 is log10 (2) rounded up;
+ add one for integer division truncation;
+ add one more for a minus sign if t is signed. */
+#define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
+#endif
+
+#define TM_YEAR_BASE 1900
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+ except every 100th isn't, and every 400th is). */
+# define __isleap(year) \
+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+
+#ifdef _LIBC
+# define my_strftime_gmtime_r __gmtime_r
+# define my_strftime_localtime_r __localtime_r
+# define tzname __tzname
+# define tzset __tzset
+#else
+
+/* If we're a strftime substitute in a GNU program, then prefer gmtime
+ to gmtime_r, since many gmtime_r implementations are buggy.
+ Similarly for localtime_r. */
+
+# if ! HAVE_TM_GMTOFF
+static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+my_strftime_gmtime_r (t, tp)
+ const time_t *t;
+ struct tm *tp;
+{
+ struct tm *l = gmtime (t);
+ if (! l)
+ return 0;
+ *tp = *l;
+ return tp;
+}
+# endif /* ! HAVE_TM_GMTOFF */
+
+static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+my_strftime_localtime_r (t, tp)
+ const time_t *t;
+ struct tm *tp;
+{
+ struct tm *l = localtime (t);
+ if (! l)
+ return 0;
+ *tp = *l;
+ return tp;
+}
+#endif /* ! defined _LIBC */
+
+
+#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
+/* Some systems lack the `memset' function and we don't want to
+ introduce additional dependencies. */
+/* The SGI compiler reportedly barfs on the trailing null
+ if we use a string constant as the initializer. 28 June 1997, rms. */
+static const CHAR_T spaces[16] = /* " " */
+{
+ L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
+ L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
+};
+static const CHAR_T zeroes[16] = /* "0000000000000000" */
+{
+ L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
+ L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
+};
+
+# define memset_space(P, Len) \
+ do { \
+ int _len = (Len); \
+ \
+ do \
+ { \
+ int _this = _len > 16 ? 16 : _len; \
+ (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
+ _len -= _this; \
+ } \
+ while (_len > 0); \
+ } while (0)
+
+# define memset_zero(P, Len) \
+ do { \
+ int _len = (Len); \
+ \
+ do \
+ { \
+ int _this = _len > 16 ? 16 : _len; \
+ (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
+ _len -= _this; \
+ } \
+ while (_len > 0); \
+ } while (0)
+#else
+# ifdef COMPILE_WIDE
+# define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
+# define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
+# else
+# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
+# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
+# endif
+#endif
+
+#define add(n, f) \
+ do \
+ { \
+ int _n = (n); \
+ int _delta = width - _n; \
+ int _incr = _n + (_delta > 0 ? _delta : 0); \
+ if ((size_t) _incr >= maxsize - i) \
+ return 0; \
+ if (p) \
+ { \
+ if (_delta > 0) \
+ { \
+ if (pad == L_('0')) \
+ memset_zero (p, _delta); \
+ else \
+ memset_space (p, _delta); \
+ } \
+ f; \
+ p += _n; \
+ } \
+ i += _incr; \
+ } while (0)
+
+#define cpy(n, s) \
+ add ((n), \
+ if (to_lowcase) \
+ memcpy_lowcase (p, (s), _n LOCALE_ARG); \
+ else if (to_uppcase) \
+ memcpy_uppcase (p, (s), _n LOCALE_ARG); \
+ else \
+ MEMCPY ((PTR) p, (const PTR) (s), _n))
+
+#ifdef COMPILE_WIDE
+# ifndef USE_IN_EXTENDED_LOCALE_MODEL
+# undef __mbsrtowcs_l
+# define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
+# endif
+# define widen(os, ws, l) \
+ { \
+ mbstate_t __st; \
+ const char *__s = os; \
+ memset (&__st, '\0', sizeof (__st)); \
+ l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
+ ws = alloca ((l + 1) * sizeof (wchar_t)); \
+ (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
+ }
+#endif
+
+/* For gawk */
+#undef TOLOWER
+#undef TOUPPER
+#undef ISDIGIT
+
+#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
+/* We use this code also for the extended locale handling where the
+ function gets as an additional argument the locale which has to be
+ used. To access the values we have to redefine the _NL_CURRENT
+ macro. */
+# define strftime __strftime_l
+# define wcsftime __wcsftime_l
+# undef _NL_CURRENT
+# define _NL_CURRENT(category, item) \
+ (current->values[_NL_ITEM_INDEX (item)].string)
+# define LOCALE_PARAM , loc
+# define LOCALE_ARG , loc
+# define LOCALE_PARAM_DECL __locale_t loc;
+# define LOCALE_PARAM_PROTO , __locale_t loc
+# define HELPER_LOCALE_ARG , current
+#else
+# define LOCALE_PARAM
+# define LOCALE_PARAM_PROTO
+# define LOCALE_ARG
+# define LOCALE_PARAM_DECL
+# ifdef _LIBC
+# define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
+# else
+# define HELPER_LOCALE_ARG
+# endif
+#endif
+
+#ifdef COMPILE_WIDE
+# ifdef USE_IN_EXTENDED_LOCALE_MODEL
+# define TOUPPER(Ch, L) __towupper_l (Ch, L)
+# define TOLOWER(Ch, L) __towlower_l (Ch, L)
+# else
+# define TOUPPER(Ch, L) towupper (Ch)
+# define TOLOWER(Ch, L) towlower (Ch)
+# endif
+#else
+# ifdef _LIBC
+# ifdef USE_IN_EXTENDED_LOCALE_MODEL
+# define TOUPPER(Ch, L) __toupper_l (Ch, L)
+# define TOLOWER(Ch, L) __tolower_l (Ch, L)
+# else
+# define TOUPPER(Ch, L) toupper (Ch)
+# define TOLOWER(Ch, L) tolower (Ch)
+# endif
+# else
+# define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
+# define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
+# endif
+#endif
+/* We don't use `isdigit' here since the locale dependent
+ interpretation is not what we want here. We only need to accept
+ the arabic digits in the ASCII range. One day there is perhaps a
+ more reliable way to accept other sets of digits. */
+#define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
+
+static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
+ size_t len LOCALE_PARAM_PROTO));
+
+static CHAR_T *
+memcpy_lowcase (dest, src, len LOCALE_PARAM)
+ CHAR_T *dest;
+ const CHAR_T *src;
+ size_t len;
+ LOCALE_PARAM_DECL
+{
+ while (len-- > 0)
+ dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
+ return dest;
+}
+
+static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
+ size_t len LOCALE_PARAM_PROTO));
+
+static CHAR_T *
+memcpy_uppcase (dest, src, len LOCALE_PARAM)
+ CHAR_T *dest;
+ const CHAR_T *src;
+ size_t len;
+ LOCALE_PARAM_DECL
+{
+ while (len-- > 0)
+ dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
+ return dest;
+}
+
+
+#if ! HAVE_TM_GMTOFF
+/* Yield the difference between *A and *B,
+ measured in seconds, ignoring leap seconds. */
+# define tm_diff ftime_tm_diff
+static int tm_diff __P ((const struct tm *, const struct tm *));
+static int
+tm_diff (a, b)
+ const struct tm *a;
+ const struct tm *b;
+{
+ /* Compute intervening leap days correctly even if year is negative.
+ Take care to avoid int overflow in leap day calculations,
+ but it's OK to assume that A and B are close to each other. */
+ int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+ int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+ int a100 = a4 / 25 - (a4 % 25 < 0);
+ int b100 = b4 / 25 - (b4 % 25 < 0);
+ int a400 = a100 >> 2;
+ int b400 = b100 >> 2;
+ int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+ int years = a->tm_year - b->tm_year;
+ int days = (365 * years + intervening_leap_days
+ + (a->tm_yday - b->tm_yday));
+ return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+#endif /* ! HAVE_TM_GMTOFF */
+
+
+
+/* The number of days from the first day of the first ISO week of this
+ year to the year day YDAY with week day WDAY. ISO weeks start on
+ Monday; the first ISO week has the year's first Thursday. YDAY may
+ be as small as YDAY_MINIMUM. */
+#define ISO_WEEK_START_WDAY 1 /* Monday */
+#define ISO_WEEK1_WDAY 4 /* Thursday */
+#define YDAY_MINIMUM (-366)
+static int iso_week_days __P ((int, int));
+#ifdef __GNUC__
+__inline__
+#endif
+static int
+iso_week_days (yday, wday)
+ int yday;
+ int wday;
+{
+ /* Add enough to the first operand of % to make it nonnegative. */
+ int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
+ return (yday
+ - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
+ + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
+}
+
+
+#if !(defined _NL_CURRENT || HAVE_STRFTIME)
+static CHAR_T const weekday_name[][10] =
+ {
+ L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
+ L_("Thursday"), L_("Friday"), L_("Saturday")
+ };
+static CHAR_T const month_name[][10] =
+ {
+ L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
+ L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
+ L_("November"), L_("December")
+ };
+#endif
+
+
+#ifdef emacs
+# define my_strftime emacs_strftimeu
+# define ut_argument , ut
+# define ut_argument_spec int ut;
+# define ut_argument_spec_iso , int ut
+#else
+# ifdef COMPILE_WIDE
+# define my_strftime wcsftime
+# define nl_get_alt_digit _nl_get_walt_digit
+# else
+# define my_strftime strftime
+# define nl_get_alt_digit _nl_get_alt_digit
+# endif
+# define ut_argument
+# define ut_argument_spec
+# define ut_argument_spec_iso
+/* We don't have this information in general. */
+# define ut 0
+#endif
+
+#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
+ /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
+ Work around this bug by copying *tp before it might be munged. */
+ size_t _strftime_copytm __P ((char *, size_t, const char *,
+ const struct tm * ut_argument_spec_iso));
+ size_t
+ my_strftime (s, maxsize, format, tp ut_argument)
+ CHAR_T *s;
+ size_t maxsize;
+ const CHAR_T *format;
+ const struct tm *tp;
+ ut_argument_spec
+ {
+ struct tm tmcopy;
+ tmcopy = *tp;
+ return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
+ }
+# undef my_strftime
+# define my_strftime _strftime_copytm
+#endif
+
+
+/* Write information from TP into S according to the format
+ string FORMAT, writing no more that MAXSIZE characters
+ (including the terminating '\0') and returning number of
+ characters written. If S is NULL, nothing will be written
+ anywhere, so to determine how many characters would be
+ written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
+size_t
+my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
+ CHAR_T *s;
+ size_t maxsize;
+ const CHAR_T *format;
+ const struct tm *tp;
+ ut_argument_spec
+ LOCALE_PARAM_DECL
+{
+#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
+ struct locale_data *const current = loc->__locales[LC_TIME];
+#endif
+
+ int hour12 = tp->tm_hour;
+#ifdef _NL_CURRENT
+ /* We cannot make the following values variables since we must delay
+ the evaluation of these values until really needed since some
+ expressions might not be valid in every situation. The `struct tm'
+ might be generated by a strptime() call that initialized
+ only a few elements. Dereference the pointers only if the format
+ requires this. Then it is ok to fail if the pointers are invalid. */
+# define a_wkday \
+ ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
+# define f_wkday \
+ ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
+# define a_month \
+ ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
+# define f_month \
+ ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
+# define ampm \
+ ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
+ ? NLW(PM_STR) : NLW(AM_STR)))
+
+# define aw_len STRLEN (a_wkday)
+# define am_len STRLEN (a_month)
+# define ap_len STRLEN (ampm)
+#else
+# if !HAVE_STRFTIME
+# define f_wkday (weekday_name[tp->tm_wday])
+# define f_month (month_name[tp->tm_mon])
+# define a_wkday f_wkday
+# define a_month f_month
+# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
+
+ size_t aw_len = 3;
+ size_t am_len = 3;
+ size_t ap_len = 2;
+# endif
+#endif
+ const char *zone;
+ size_t i = 0;
+ CHAR_T *p = s;
+ const CHAR_T *f;
+#if DO_MULTIBYTE && !defined COMPILE_WIDE
+ const char *format_end = NULL;
+#endif
+
+ zone = NULL;
+#if HAVE_TM_ZONE
+ /* The POSIX test suite assumes that setting
+ the environment variable TZ to a new value before calling strftime()
+ will influence the result (the %Z format) even if the information in
+ TP is computed with a totally different time zone.
+ This is bogus: though POSIX allows bad behavior like this,
+ POSIX does not require it. Do the right thing instead. */
+ zone = (const char *) tp->tm_zone;
+#endif
+#if HAVE_TZNAME
+ if (ut)
+ {
+ if (! (zone && *zone))
+ zone = "GMT";
+ }
+ else
+ {
+ /* POSIX.1 requires that local time zone information is used as
+ though strftime called tzset. */
+# if HAVE_TZSET
+ tzset ();
+# endif
+ }
+#endif
+
+ if (hour12 > 12)
+ hour12 -= 12;
+ else
+ if (hour12 == 0)
+ hour12 = 12;
+
+ for (f = format; *f != '\0'; ++f)
+ {
+ int pad = 0; /* Padding for number ('-', '_', or 0). */
+ int modifier; /* Field modifier ('E', 'O', or 0). */
+ int digits; /* Max digits for numeric format. */
+ int number_value; /* Numeric value to be printed. */
+ int negative_number; /* 1 if the number is negative. */
+ const CHAR_T *subfmt;
+ CHAR_T *bufp;
+ CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
+ ? INT_STRLEN_BOUND (time_t)
+ : INT_STRLEN_BOUND (int))];
+ int width = -1;
+ int to_lowcase = 0;
+ int to_uppcase = 0;
+ int change_case = 0;
+ int format_char;
+
+#if DO_MULTIBYTE && !defined COMPILE_WIDE
+ switch (*f)
+ {
+ case L_('%'):
+ break;
+
+ case L_('\b'): case L_('\t'): case L_('\n'):
+ case L_('\v'): case L_('\f'): case L_('\r'):
+ case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
+ case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
+ case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
+ case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
+ case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
+ case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
+ case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
+ case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
+ case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
+ case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
+ case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
+ case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
+ case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
+ case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
+ case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
+ case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
+ case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
+ case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
+ case L_('~'):
+ /* The C Standard requires these 98 characters (plus '%') to
+ be in the basic execution character set. None of these
+ characters can start a multibyte sequence, so they need
+ not be analyzed further. */
+ add (1, *p = *f);
+ continue;
+
+ default:
+ /* Copy this multibyte sequence until we reach its end, find
+ an error, or come back to the initial shift state. */
+ {
+ mbstate_t mbstate = mbstate_zero;
+ size_t len = 0;
+ size_t fsize;
+
+ if (! format_end)
+ format_end = f + strlen (f) + 1;
+ fsize = format_end - f;
+
+ do
+ {
+ size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
+
+ if (bytes == 0)
+ break;
+
+ if (bytes == (size_t) -2)
+ {
+ len += strlen (f + len);
+ break;
+ }
+
+ if (bytes == (size_t) -1)
+ {
+ len++;
+ break;
+ }
+
+ len += bytes;
+ }
+ while (! mbsinit (&mbstate));
+
+ cpy (len, f);
+ f += len - 1;
+ continue;
+ }
+ }
+
+#else /* ! DO_MULTIBYTE */
+
+ /* Either multibyte encodings are not supported, they are
+ safe for formats, so any non-'%' byte can be copied through,
+ or this is the wide character version. */
+ if (*f != L_('%'))
+ {
+ add (1, *p = *f);
+ continue;
+ }
+
+#endif /* ! DO_MULTIBYTE */
+
+ /* Check for flags that can modify a format. */
+ while (1)
+ {
+ switch (*++f)
+ {
+ /* This influences the number formats. */
+ case L_('_'):
+ case L_('-'):
+ case L_('0'):
+ pad = *f;
+ continue;
+
+ /* This changes textual output. */
+ case L_('^'):
+ to_uppcase = 1;
+ continue;
+ case L_('#'):
+ change_case = 1;
+ continue;
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ /* As a GNU extension we allow to specify the field width. */
+ if (ISDIGIT (*f))
+ {
+ width = 0;
+ do
+ {
+ if (width > INT_MAX / 10
+ || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
+ /* Avoid overflow. */
+ width = INT_MAX;
+ else
+ {
+ width *= 10;
+ width += *f - L_('0');
+ }
+ ++f;
+ }
+ while (ISDIGIT (*f));
+ }
+
+ /* Check for modifiers. */
+ switch (*f)
+ {
+ case L_('E'):
+ case L_('O'):
+ modifier = *f++;
+ break;
+
+ default:
+ modifier = 0;
+ break;
+ }
+
+ /* Now do the specified format. */
+ format_char = *f;
+ switch (format_char)
+ {
+#define DO_NUMBER(d, v) \
+ digits = d > width ? d : width; \
+ number_value = v; goto do_number
+#define DO_NUMBER_SPACEPAD(d, v) \
+ digits = d > width ? d : width; \
+ number_value = v; goto do_number_spacepad
+
+ case L_('%'):
+ if (modifier != 0)
+ goto bad_format;
+ add (1, *p = *f);
+ break;
+
+ case L_('a'):
+ if (modifier != 0)
+ goto bad_format;
+ if (change_case)
+ {
+ to_uppcase = 1;
+ to_lowcase = 0;
+ }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+ cpy (aw_len, a_wkday);
+ break;
+#else
+ goto underlying_strftime;
+#endif
+
+ case 'A':
+ if (modifier != 0)
+ goto bad_format;
+ if (change_case)
+ {
+ to_uppcase = 1;
+ to_lowcase = 0;
+ }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+ cpy (STRLEN (f_wkday), f_wkday);
+ break;
+#else
+ goto underlying_strftime;
+#endif
+
+ case L_('b'):
+ case L_('h'):
+ if (change_case)
+ {
+ to_uppcase = 1;
+ to_lowcase = 0;
+ }
+ if (modifier != 0)
+ goto bad_format;
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+ cpy (am_len, a_month);
+ break;
+#else
+ goto underlying_strftime;
+#endif
+
+ case L_('B'):
+ if (modifier != 0)
+ goto bad_format;
+ if (change_case)
+ {
+ to_uppcase = 1;
+ to_lowcase = 0;
+ }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+ cpy (STRLEN (f_month), f_month);
+ break;
+#else
+ goto underlying_strftime;
+#endif
+
+ case L_('c'):
+ if (modifier == L_('O'))
+ goto bad_format;
+#ifdef _NL_CURRENT
+ if (! (modifier == 'E'
+ && (*(subfmt =
+ (const CHAR_T *) _NL_CURRENT (LC_TIME,
+ NLW(ERA_D_T_FMT)))
+ != '\0')))
+ subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# else
+ subfmt = L_("%a %b %e %H:%M:%S %Y");
+# endif
+#endif
+
+ subformat:
+ {
+ CHAR_T *old_start = p;
+ size_t len = my_strftime (NULL, (size_t) -1, subfmt,
+ tp ut_argument LOCALE_ARG);
+ add (len, my_strftime (p, maxsize - i, subfmt,
+ tp ut_argument LOCALE_ARG));
+
+ if (to_uppcase)
+ while (old_start < p)
+ {
+ *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
+ ++old_start;
+ }
+ }
+ break;
+
+#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
+ underlying_strftime:
+ {
+ /* The relevant information is available only via the
+ underlying strftime implementation, so use that. */
+ char ufmt[4];
+ char *u = ufmt;
+ char ubuf[1024]; /* enough for any single format in practice */
+ size_t len;
+ /* Make sure we're calling the actual underlying strftime.
+ In some cases, config.h contains something like
+ "#define strftime rpl_strftime". */
+# ifdef strftime
+# undef strftime
+ size_t strftime ();
+# endif
+
+ *u++ = '%';
+ if (modifier != 0)
+ *u++ = modifier;
+ *u++ = format_char;
+ *u = '\0';
+ len = strftime (ubuf, sizeof ubuf, ufmt, tp);
+ if (len == 0 && ubuf[0] != '\0')
+ return 0;
+ cpy (len, ubuf);
+ }
+ break;
+#endif
+
+ case L_('C'):
+ if (modifier == L_('O'))
+ goto bad_format;
+ if (modifier == L_('E'))
+ {
+#if HAVE_STRUCT_ERA_ENTRY
+ struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ if (era)
+ {
+# ifdef COMPILE_WIDE
+ size_t len = __wcslen (era->era_wname);
+ cpy (len, era->era_wname);
+# else
+ size_t len = strlen (era->era_name);
+ cpy (len, era->era_name);
+# endif
+ break;
+ }
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# endif
+#endif
+ }
+
+ {
+ int year = tp->tm_year + TM_YEAR_BASE;
+ DO_NUMBER (1, year / 100 - (year % 100 < 0));
+ }
+
+ case L_('x'):
+ if (modifier == L_('O'))
+ goto bad_format;
+#ifdef _NL_CURRENT
+ if (! (modifier == L_('E')
+ && (*(subfmt =
+ (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
+ != L_('\0'))))
+ subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
+ goto subformat;
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# else
+ /* Fall through. */
+# endif
+#endif
+ case L_('D'):
+ if (modifier != 0)
+ goto bad_format;
+ subfmt = L_("%m/%d/%y");
+ goto subformat;
+
+ case L_('d'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, tp->tm_mday);
+
+ case L_('e'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER_SPACEPAD (2, tp->tm_mday);
+
+ /* All numeric formats set DIGITS and NUMBER_VALUE and then
+ jump to one of these two labels. */
+
+ do_number_spacepad:
+ /* Force `_' flag unless overwritten by `0' flag. */
+ if (pad != L_('0'))
+ pad = L_('_');
+
+ do_number:
+ /* Format the number according to the MODIFIER flag. */
+
+ if (modifier == L_('O') && 0 <= number_value)
+ {
+#ifdef _NL_CURRENT
+ /* Get the locale specific alternate representation of
+ the number NUMBER_VALUE. If none exist NULL is returned. */
+ const CHAR_T *cp = nl_get_alt_digit (number_value
+ HELPER_LOCALE_ARG);
+
+ if (cp != NULL)
+ {
+ size_t digitlen = STRLEN (cp);
+ if (digitlen != 0)
+ {
+ cpy (digitlen, cp);
+ break;
+ }
+ }
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# endif
+#endif
+ }
+ {
+ unsigned int u = number_value;
+
+ bufp = buf + sizeof (buf) / sizeof (buf[0]);
+ negative_number = number_value < 0;
+
+ if (negative_number)
+ u = -u;
+
+ do
+ *--bufp = u % 10 + L_('0');
+ while ((u /= 10) != 0);
+ }
+
+ do_number_sign_and_padding:
+ if (negative_number)
+ *--bufp = L_('-');
+
+ if (pad != L_('-'))
+ {
+ int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
+ - bufp);
+
+ if (padding > 0)
+ {
+ if (pad == L_('_'))
+ {
+ if ((size_t) padding >= maxsize - i)
+ return 0;
+
+ if (p)
+ memset_space (p, padding);
+ i += padding;
+ width = width > padding ? width - padding : 0;
+ }
+ else
+ {
+ if ((size_t) digits >= maxsize - i)
+ return 0;
+
+ if (negative_number)
+ {
+ ++bufp;
+
+ if (p)
+ *p++ = L_('-');
+ ++i;
+ }
+
+ if (p)
+ memset_zero (p, padding);
+ i += padding;
+ width = 0;
+ }
+ }
+ }
+
+ cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
+ break;
+
+ case L_('F'):
+ if (modifier != 0)
+ goto bad_format;
+ subfmt = L_("%Y-%m-%d");
+ goto subformat;
+
+ case L_('H'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, tp->tm_hour);
+
+ case L_('I'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, hour12);
+
+ case L_('k'): /* GNU extension. */
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER_SPACEPAD (2, tp->tm_hour);
+
+ case L_('l'): /* GNU extension. */
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER_SPACEPAD (2, hour12);
+
+ case L_('j'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (3, 1 + tp->tm_yday);
+
+ case L_('M'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, tp->tm_min);
+
+ case L_('m'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, tp->tm_mon + 1);
+
+ case L_('n'):
+ add (1, *p = L_('\n'));
+ break;
+
+ case L_('P'):
+ to_lowcase = 1;
+#if !defined _NL_CURRENT && HAVE_STRFTIME
+ format_char = L_('p');
+#endif
+ /* FALLTHROUGH */
+
+ case L_('p'):
+ if (change_case)
+ {
+ to_uppcase = 0;
+ to_lowcase = 1;
+ }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+ cpy (ap_len, ampm);
+ break;
+#else
+ goto underlying_strftime;
+#endif
+
+ case L_('R'):
+ subfmt = L_("%H:%M");
+ goto subformat;
+
+ case L_('r'):
+#ifdef _NL_CURRENT
+ if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
+ NLW(T_FMT_AMPM)))
+ == L_('\0'))
+#endif
+ subfmt = L_("%I:%M:%S %p");
+ goto subformat;
+
+ case L_('S'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, tp->tm_sec);
+
+ case L_('s'): /* GNU extension. */
+ {
+ struct tm ltm;
+ time_t t;
+
+ ltm = *tp;
+ t = mktime (<m);
+
+ /* Generate string value for T using time_t arithmetic;
+ this works even if sizeof (long) < sizeof (time_t). */
+
+ bufp = buf + sizeof (buf) / sizeof (buf[0]);
+#ifndef TIME_T_UNSIGNED
+ negative_number = t < 0;
+#endif
+
+ do
+ {
+ int d = t % 10;
+ t /= 10;
+
+#ifndef TIME_T_UNSIGNED
+ if (negative_number)
+ {
+ d = -d;
+
+ /* Adjust if division truncates to minus infinity. */
+ if (0 < -1 % 10 && d < 0)
+ {
+ t++;
+ d += 10;
+ }
+ }
+#endif
+
+ *--bufp = d + L_('0');
+ }
+ while (t != 0);
+
+ digits = 1;
+ goto do_number_sign_and_padding;
+ }
+
+ case L_('X'):
+ if (modifier == L_('O'))
+ goto bad_format;
+#ifdef _NL_CURRENT
+ if (! (modifier == L_('E')
+ && (*(subfmt =
+ (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
+ != L_('\0'))))
+ subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
+ goto subformat;
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# else
+ /* Fall through. */
+# endif
+#endif
+ case L_('T'):
+ subfmt = L_("%H:%M:%S");
+ goto subformat;
+
+ case L_('t'):
+ add (1, *p = L_('\t'));
+ break;
+
+ case L_('u'):
+ DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
+
+ case L_('U'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
+
+ case L_('V'):
+ case L_('g'):
+ case L_('G'):
+ if (modifier == L_('E'))
+ goto bad_format;
+ {
+ int year = tp->tm_year + TM_YEAR_BASE;
+ int days = iso_week_days (tp->tm_yday, tp->tm_wday);
+
+ if (days < 0)
+ {
+ /* This ISO week belongs to the previous year. */
+ year--;
+ days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
+ tp->tm_wday);
+ }
+ else
+ {
+ int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
+ tp->tm_wday);
+ if (0 <= d)
+ {
+ /* This ISO week belongs to the next year. */
+ year++;
+ days = d;
+ }
+ }
+
+ switch (*f)
+ {
+ case L_('g'):
+ DO_NUMBER (2, (year % 100 + 100) % 100);
+
+ case L_('G'):
+ DO_NUMBER (1, year);
+
+ default:
+ DO_NUMBER (2, days / 7 + 1);
+ }
+ }
+
+ case L_('W'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
+
+ case L_('w'):
+ if (modifier == L_('E'))
+ goto bad_format;
+
+ DO_NUMBER (1, tp->tm_wday);
+
+ case L_('Y'):
+ if (modifier == 'E')
+ {
+#if HAVE_STRUCT_ERA_ENTRY
+ struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ if (era)
+ {
+# ifdef COMPILE_WIDE
+ subfmt = era->era_wformat;
+# else
+ subfmt = era->era_format;
+# endif
+ goto subformat;
+ }
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# endif
+#endif
+ }
+ if (modifier == L_('O'))
+ goto bad_format;
+ else
+ DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
+
+ case L_('y'):
+ if (modifier == L_('E'))
+ {
+#if HAVE_STRUCT_ERA_ENTRY
+ struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ if (era)
+ {
+ int delta = tp->tm_year - era->start_date[0];
+ DO_NUMBER (1, (era->offset
+ + delta * era->absolute_direction));
+ }
+#else
+# if HAVE_STRFTIME
+ goto underlying_strftime;
+# endif
+#endif
+ }
+ DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
+
+ case L_('Z'):
+ if (change_case)
+ {
+ to_uppcase = 0;
+ to_lowcase = 1;
+ }
+
+#if HAVE_TZNAME
+ /* The tzset() call might have changed the value. */
+ if (!(zone && *zone) && tp->tm_isdst >= 0)
+ zone = tzname[tp->tm_isdst];
+#endif
+ if (! zone)
+ zone = "";
+
+#ifdef COMPILE_WIDE
+ {
+ /* The zone string is always given in multibyte form. We have
+ to transform it first. */
+ wchar_t *wczone;
+ size_t len;
+ widen (zone, wczone, len);
+ cpy (len, wczone);
+ }
+#else
+ cpy (strlen (zone), zone);
+#endif
+ break;
+
+ case L_('z'):
+ if (tp->tm_isdst < 0)
+ break;
+
+ {
+ int diff;
+#if HAVE_TM_GMTOFF
+ diff = tp->tm_gmtoff;
+#else
+ if (ut)
+ diff = 0;
+ else
+ {
+ struct tm gtm;
+ struct tm ltm;
+ time_t lt;
+
+ ltm = *tp;
+ lt = mktime (<m);
+
+ if (lt == (time_t) -1)
+ {
+ /* mktime returns -1 for errors, but -1 is also a
+ valid time_t value. Check whether an error really
+ occurred. */
+ struct tm tm;
+
+ if (! my_strftime_localtime_r (<, &tm)
+ || ((ltm.tm_sec ^ tm.tm_sec)
+ | (ltm.tm_min ^ tm.tm_min)
+ | (ltm.tm_hour ^ tm.tm_hour)
+ | (ltm.tm_mday ^ tm.tm_mday)
+ | (ltm.tm_mon ^ tm.tm_mon)
+ | (ltm.tm_year ^ tm.tm_year)))
+ break;
+ }
+
+ if (! my_strftime_gmtime_r (<, >m))
+ break;
+
+ diff = tm_diff (<m, >m);
+ }
+#endif
+
+ if (diff < 0)
+ {
+ add (1, *p = L_('-'));
+ diff = -diff;
+ }
+ else
+ add (1, *p = L_('+'));
+
+ diff /= 60;
+ DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
+ }
+
+ case L_('\0'): /* GNU extension: % at end of format. */
+ --f;
+ /* Fall through. */
+ default:
+ /* Unknown format; output the format, including the '%',
+ since this is most likely the right thing to do if a
+ multibyte string has been misparsed. */
+ bad_format:
+ {
+ int flen;
+ for (flen = 1; f[1 - flen] != L_('%'); flen++)
+ continue;
+ cpy (flen, &f[1 - flen]);
+ }
+ break;
+ }
+ }
+
+ if (p && maxsize != 0)
+ *p = L_('\0');
+ return i;
+}
+#ifdef _LIBC
+libc_hidden_def (my_strftime)
+#endif
+
+
+#ifdef emacs
+/* For Emacs we have a separate interface which corresponds to the normal
+ strftime function and does not have the extra information whether the
+ TP arguments comes from a `gmtime' call or not. */
+size_t
+emacs_strftime (s, maxsize, format, tp)
+ char *s;
+ size_t maxsize;
+ const char *format;
+ const struct tm *tp;
+{
+ return my_strftime (s, maxsize, format, tp, 0);
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef atarist
+#include <sys/types.h>
+#else
+#define u_char unsigned char
+#endif
+
+/* This rather ugly macro is for VMS C */
+#ifdef C
+#undef C
+#endif
+#define C(c) ((u_char)c)
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
+ C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
+ C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
+ C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
+ C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
+ C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
+ C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
+ C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
+};
+
+#undef C
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return(cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while ((long)(--n) >= 0 && cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return((long)n < 0 ? 0 : cm[*us1] - cm[*--us2]);
+}
--- /dev/null
+/*
+ * gawk wrapper for strtod
+ */
+/*
+ * Stupid version of System V strtod(3) library routine.
+ * Does no overflow/underflow checking.
+ *
+ * A real number is defined to be
+ * optional leading white space
+ * optional sign
+ * string of digits with optional decimal point
+ * optional 'e' or 'E'
+ * followed by optional sign or space
+ * followed by an integer
+ *
+ * if ptr is not NULL a pointer to the character terminating the
+ * scan is returned in *ptr. If no number formed, *ptr is set to str
+ * and 0 is returned.
+ *
+ * For speed, we don't do the conversion ourselves. Instead, we find
+ * the end of the number and then call atof() to do the dirty work.
+ * This bought us a 10% speedup on a sample program at uunet.uu.net.
+ *
+ * Fall 2000: Changed to enforce C89 semantics, so that 0x... returns 0.
+ * C99 has hexadecimal floating point numbers.
+ *
+ * Summer 2001. Try to make it smarter, so that a string like "0000"
+ * doesn't look like we failed. Sigh.
+ *
+ * Xmass 2002. Fix a bug in ptr determination, eg. for "0e0".
+ *
+ * Spring 2004. Update for I18N. Oh joy.
+ */
+
+#if 0
+#include <ctype.h>
+#endif
+
+extern double atof();
+
+double
+gawk_strtod(s, ptr)
+register const char *s;
+register const char **ptr;
+{
+ const char *start = s; /* save original start of string */
+ const char *begin = NULL; /* where the number really begins */
+ int dig = 0;
+ int dig0 = 0;
+
+ /* optional white space */
+ while (isspace(*s))
+ s++;
+
+ begin = s;
+
+ /* optional sign */
+ if (*s == '+' || *s == '-')
+ s++;
+
+ /* string of digits with optional decimal point */
+ while (*s == '0') {
+ s++;
+ dig0++;
+ }
+ while (isdigit(*s)) {
+ s++;
+ dig++;
+ }
+
+ if (
+#if defined(HAVE_LOCALE_H)
+ loc.decimal_point != NULL
+ ? *s == loc.decimal_point[0]
+ : *s == '.'
+#else
+ *s == '.'
+#endif
+ ) {
+ s++;
+ while (*s == '0') {
+ s++;
+ dig0++;
+ }
+ while (isdigit(*s)) {
+ s++;
+ dig++;
+ }
+ }
+
+ dig0 += dig; /* any digit has appeared */
+
+ /*
+ * optional 'e' or 'E'
+ * if a digit (or at least zero) was seen
+ * followed by optional sign
+ * followed by an integer
+ */
+ if (dig0
+ && (*s == 'e' || *s == 'E')
+ && (isdigit(s[1])
+ || ((s[1] == '-' || s[1] == '+') && isdigit(s[2])))) {
+ s++;
+ if (*s == '+' || *s == '-')
+ s++;
+ while (isdigit(*s))
+ s++;
+ }
+
+ /* In case we haven't found a number, set ptr to start. */
+ if (ptr)
+ *ptr = (dig0 ? s : start);
+
+ /* Go for it. */
+ return (dig ? atof(begin) : 0.0);
+}
+
+#ifdef TEST
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ double d;
+ char *p;
+
+ for (argc--, argv++; argc; argc--, argv++) {
+ d = strtod (*argv, & p);
+ printf ("%lf [%s]\n", d, p);
+ }
+
+ return 0;
+}
+#endif
--- /dev/null
+/*
+ * Very simple implementation of strtoul() for gawk,
+ * for old systems. Descriptive prose from the Linux man page.
+ *
+ * May 2004
+ */
+
+/* #define TEST 1 */
+
+#ifdef TEST
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#define TRUE 1
+#define FALSE 0
+#define strtoul mystrtoul
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX (~ 0UL)
+#endif
+
+unsigned long int
+strtoul(nptr, endptr, base)
+const char *nptr;
+char **endptr;
+int base;
+{
+ static char lower[] = "abcdefghijklmnopqrstuvwxyz";
+
+ unsigned long result = 0UL;
+ char *nptr_orig = (char *) nptr;
+ int neg = FALSE;
+ char *cp, c;
+ int val;
+ int sawdigs = FALSE;
+
+ /*
+ * The strtoul() function converts the initial part of the
+ * string in nptr to an unsigned long integer value according
+ * to the given base, which must be between 2 and 36 inclusive,
+ * or be the special value 0.
+ */
+
+ if ((base != 0 && (base < 2 || base > 36)) || nptr == NULL) {
+ if (endptr != NULL)
+ *endptr = nptr_orig;
+ errno = EINVAL;
+ return 0;
+ }
+
+ /*
+ * The string must [sic] begin with an arbitrary amount of white space
+ * (as determined by isspace(3)) followed by a single optional
+ * `+' or `-' sign.
+ */
+ while (isspace(*nptr))
+ nptr++;
+
+ if (*nptr == '+')
+ nptr++;
+ else if (*nptr == '-') {
+ nptr++;
+ neg = TRUE;
+ }
+
+ /*
+ * If base is zero or 16, the string may then include a `0x' prefix,
+ * and the number will be read in base 16; otherwise, a zero base is
+ * taken as 10 (decimal) unless the next character is `0', in which
+ * case it is taken as 8 (octal).
+ */
+ if ((base == 0 || base == 16)
+ && nptr[0] == '0'
+ && (nptr[1] == 'x' || nptr[1] == 'X')) {
+ base = 16; /* force it */
+ nptr += 2; /* skip 0x */
+ } else if ((base == 0 || base == 8) && nptr[0] == '0') {
+ base = 8;
+ nptr++;
+ } else if (base == 0)
+ base = 10;
+
+ /*
+ * The remainder of the string is converted to an unsigned long int
+ * value in the obvious manner, stopping at the first character
+ * which is not a valid digit in the given base. (In bases above 10,
+ * the letter `A' in either upper or lower case represents 10,
+ * `B' represents 11, and so forth, with `Z' representing 35.)
+ */
+ for (; *nptr != '\0'; nptr++) {
+ c = *nptr;
+#if defined(HAVE_LOCALE_H)
+ if (base == 10
+ && loc.thousands_sep != NULL
+ && loc.thousands_sep[0] != '\0'
+ && c == loc.thousands_sep[0])
+ continue;
+#endif
+ switch (c) {
+ case '0': case '1': case '2':
+ case '3': case '4': case '5':
+ case '6': case '7': case '8':
+ case '9':
+ val = c - '0';
+ if (val >= base) /* even base 2 allowed ... */
+ goto out;
+ result *= base;
+ result += val;
+ sawdigs = TRUE;
+ break;
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
+ c += 'a' - 'A'; /* downcase */
+ /* fall through */
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z':
+ cp = strchr(lower, c);
+ val = cp - lower;
+ val += 10; /* 'a' == 10 */
+ if (val >= base)
+ goto out;
+ result *= base;
+ result += val;
+ sawdigs = TRUE;
+ break;
+ default:
+ goto out;
+ }
+ }
+out:
+ /*
+ * If endptr is not NULL, strtoul() stores the address of the
+ * first invalid character in *endptr. If there were no digits
+ * at all, strtoul() stores the original value of nptr in *endptr
+ * (and returns 0). In particular, if *nptr is not `\0' but
+ * **endptr is `\0' on return, the entire string is valid.
+ */
+ if (endptr != NULL) {
+ if (! sawdigs) {
+ *endptr = nptr_orig;
+ return 0;
+ } else
+ *endptr = (char *) nptr;
+ }
+
+ /*
+ * RETURN VALUE
+ * The strtoul() function returns either the result of the
+ * conversion or, if there was a leading minus sign, the
+ * negation of the result of the conversion, unless the original
+ * (non-negated) value would overflow; in the latter case,
+ * strtoul() returns ULONG_MAX and sets the global variable errno
+ * to ERANGE.
+ */
+
+ /*
+ * ADR: This computation is probably bogus. If it's a
+ * problem, upgrade to a modern system.
+ */
+ if (neg && result == ULONG_MAX) {
+ errno = ERANGE;
+ return ULONG_MAX;
+ } else if (neg)
+ result = -result;
+
+ return result;
+}
+
+#ifdef TEST
+#undef strtoul
+int main(void)
+{
+ char *endptr;
+ unsigned long res1, res2;
+
+ res1 = strtoul("0xdeadBeeF", & endptr, 0),
+ res2 = mystrtoul("0xdeadBeeF", & endptr, 0),
+printf("(real,my)strtoul(\"0xdeadBeeF\", & endptr, 0) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul("0101101", & endptr, 2),
+ res2 = mystrtoul("0101101", & endptr, 2),
+printf("(real,my)strtoul(\"0101101\", & endptr, 2) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul("01011012", & endptr, 2),
+ res2 = mystrtoul("01011012", & endptr, 2),
+printf("(real,my)strtoul(\"01011012\", & endptr, 2) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul(" +42a", & endptr, 0),
+ res2 = mystrtoul(" +42a", & endptr, 0),
+printf("(real,my)strtoul(\" +42a\", & endptr, 0) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul("0377", & endptr, 0),
+ res2 = mystrtoul("0377", & endptr, 0),
+printf("(real,my)strtoul(\"0377\", & endptr, 0) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul("Z", & endptr, 36),
+ res2 = mystrtoul("Z", & endptr, 36),
+printf("(real,my)strtoul(\"Z\", & endptr, 36) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+
+ res1 = strtoul("qZ*", & endptr, 36),
+ res2 = mystrtoul("qZ*", & endptr, 36),
+printf("(real,my)strtoul(\"qZ*\", & endptr, 36) is %lu, %lu *endptr = %d\n",
+ res1, res2, *endptr);
+}
+#endif
--- /dev/null
+/* system.c --- replacement system() for systems missing one
+
+ Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+extern void fatal();
+
+int
+system(s)
+char *s;
+{
+ fatal("system() not supported on this system");
+ return 0;
+}
--- /dev/null
+/*
+ * tzset.c
+ *
+ * Quick and dirty emulation of tzset(), tzname[], and daylight
+ * for old BSD systems without it.
+ *
+ * Thanks to Rick Adams, rick@uunet.uu.net, for the basics.
+ *
+ * BUGS:
+ * Totally ignores the value of the TZ environment variable.
+ */
+
+#if 0
+#include <time.h>
+#endif
+#include <sys/time.h>
+
+static char tz1[1024];
+static char tz2[1024];
+
+/* external variables */
+char *tzname[2] = {
+ tz1, tz2
+};
+int daylight;
+
+extern char *timezone();
+
+void
+tzset()
+{
+ struct timeval tp;
+ struct timezone tz;
+
+ (void) gettimeofday(&tp, &tz);
+ (void) strcpy(tz1, timezone(tz.tz_minuteswest, 0));
+ (void) strcpy(tz2, timezone(tz.tz_minuteswest, 1));
+ daylight = tz.tz_dsttime;
+}
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit 0
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+/*
+ * msg.c - routines for error messages
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+int sourceline = 0;
+char *source = NULL;
+
+static const char *srcfile = NULL;
+static int srcline;
+
+/* err --- print an error message with source line and file and record */
+
+/* VARARGS2 */
+void
+err(const char *s, const char *emsg, va_list argp)
+{
+ char *file;
+
+ (void) fflush(stdout);
+ (void) fprintf(stderr, "%s: ", myname);
+#ifdef GAWKDEBUG
+ if (srcfile != NULL) {
+ fprintf(stderr, "%s:%d:", srcfile, srcline);
+ srcfile = NULL;
+ }
+#endif /* GAWKDEBUG */
+ if (sourceline != 0) {
+ if (source != NULL)
+ (void) fprintf(stderr, "%s:", source);
+ else
+ (void) fprintf(stderr, _("cmd. line:"));
+
+ (void) fprintf(stderr, "%d: ", sourceline);
+ }
+ if (FNR > 0) {
+ file = FILENAME_node->var_value->stptr;
+ (void) putc('(', stderr);
+ if (file)
+ (void) fprintf(stderr, "FILENAME=%s ", file);
+ (void) fprintf(stderr, "FNR=%ld) ", FNR);
+ }
+ (void) fprintf(stderr, "%s", s);
+ vfprintf(stderr, emsg, argp);
+ (void) fprintf(stderr, "\n");
+ (void) fflush(stderr);
+}
+
+/* msg --- take a varargs error message and print it */
+
+/*
+ * Function identifier purposely indented to avoid mangling
+ * by ansi2knr. Sigh.
+ */
+
+void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ msg(const char *mesg, ...)
+#else
+/*VARARGS0*/
+ msg(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, mesg);
+#else
+ char *mesg;
+
+ va_start(args);
+ mesg = va_arg(args, char *);
+#endif
+ err("", mesg, args);
+ va_end(args);
+}
+
+/* warning --- print a warning message */
+
+void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ warning(const char *mesg, ...)
+#else
+/*VARARGS0*/
+ warning(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, mesg);
+#else
+ char *mesg;
+
+ va_start(args);
+ mesg = va_arg(args, char *);
+#endif
+ err(_("warning: "), mesg, args);
+ va_end(args);
+}
+
+void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ error(const char *mesg, ...)
+#else
+/*VARARGS0*/
+ error(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, mesg);
+#else
+ char *mesg;
+
+ va_start(args);
+ mesg = va_arg(args, char *);
+#endif
+ err(_("error: "), mesg, args);
+ va_end(args);
+}
+
+/* set_loc --- set location where a fatal error happened */
+
+void
+set_loc(const char *file, int line)
+{
+ srcfile = file;
+ srcline = line;
+
+ /* This stupid line keeps some compilers happy: */
+ file = srcfile; line = srcline;
+}
+
+/* fatal --- print an error message and die */
+
+void
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ r_fatal(const char *mesg, ...)
+#else
+/*VARARGS0*/
+ r_fatal(va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start(args, mesg);
+#else
+ char *mesg;
+
+ va_start(args);
+ mesg = va_arg(args, char *);
+#endif
+ err(_("fatal: "), mesg, args);
+ va_end(args);
+#ifdef GAWKDEBUG
+ abort();
+#endif
+ exit(2);
+}
--- /dev/null
+/*
+ * node.c -- routines for node management
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/* r_force_number --- force a value to be numeric */
+
+AWKNUM
+r_force_number(register NODE *n)
+{
+ register char *cp;
+ register char *cpend;
+ char save;
+ char *ptr;
+ unsigned int newflags;
+ extern double strtod();
+
+#ifdef GAWKDEBUG
+ if (n == NULL)
+ cant_happen();
+ if (n->type != Node_val)
+ cant_happen();
+ if (n->flags == 0)
+ cant_happen();
+ if (n->flags & NUMCUR)
+ return n->numbr;
+#endif
+
+ /* all the conditionals are an attempt to avoid the expensive strtod */
+
+ /* Note: only set NUMCUR if we actually convert some digits */
+
+ n->numbr = 0.0;
+
+ if (n->stlen == 0) {
+ if (0 && do_lint)
+ lintwarn(_("can't convert string to float"));
+ return 0.0;
+ }
+
+ cp = n->stptr;
+ if (ISALPHA(*cp)) {
+ if (0 && do_lint)
+ lintwarn(_("can't convert string to float"));
+ return 0.0;
+ }
+
+ cpend = cp + n->stlen;
+ while (cp < cpend && ISSPACE(*cp))
+ cp++;
+ if (cp == cpend || ISALPHA(*cp)) {
+ if (0 && do_lint)
+ lintwarn(_("can't convert string to float"));
+ return 0.0;
+ }
+
+ if (n->flags & MAYBE_NUM) {
+ newflags = NUMBER;
+ n->flags &= ~MAYBE_NUM;
+ } else
+ newflags = 0;
+ if (cpend - cp == 1) {
+ if (ISDIGIT(*cp)) {
+ n->numbr = (AWKNUM)(*cp - '0');
+ n->flags |= newflags;
+ n->flags |= NUMCUR;
+ } else if (0 && do_lint)
+ lintwarn(_("can't convert string to float"));
+ return n->numbr;
+ }
+
+ if (do_non_decimal_data) {
+ errno = 0;
+ if (! do_traditional && isnondecimal(cp, TRUE)) {
+ n->numbr = nondec2awknum(cp, cpend - cp);
+ n->flags |= NUMCUR;
+ goto finish;
+ }
+ }
+
+ errno = 0;
+ save = *cpend;
+ *cpend = '\0';
+ n->numbr = (AWKNUM) strtod((const char *) cp, &ptr);
+
+ /* POSIX says trailing space is OK for NUMBER */
+ while (ISSPACE(*ptr))
+ ptr++;
+ *cpend = save;
+finish:
+ /* the >= should be ==, but for SunOS 3.5 strtod() */
+ if (errno == 0 && ptr >= cpend) {
+ n->flags |= newflags;
+ n->flags |= NUMCUR;
+ } else {
+ if (0 && do_lint && ptr < cpend)
+ lintwarn(_("can't convert string to float"));
+ errno = 0;
+ }
+
+ return n->numbr;
+}
+
+/*
+ * the following lookup table is used as an optimization in force_string
+ * (more complicated) variations on this theme didn't seem to pay off, but
+ * systematic testing might be in order at some point
+ */
+static const char *const values[] = {
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+};
+#define NVAL (sizeof(values)/sizeof(values[0]))
+
+/* format_val --- format a numeric value based on format */
+
+NODE *
+format_val(const char *format, int index, register NODE *s)
+{
+ char buf[BUFSIZ];
+ register char *sp = buf;
+ double val;
+ char *orig, *trans, save;
+
+ if (! do_traditional && (s->flags & INTLSTR) != 0) {
+ save = s->stptr[s->stlen];
+ s->stptr[s->stlen] = '\0';
+
+ orig = s->stptr;
+ trans = dgettext(TEXTDOMAIN, orig);
+
+ s->stptr[s->stlen] = save;
+ return tmp_string(trans, strlen(trans));
+ }
+
+ /* not an integral value, or out of range */
+ if ((val = double_to_int(s->numbr)) != s->numbr
+ || val < LONG_MIN || val > LONG_MAX) {
+ /*
+ * Once upon a time, if GFMT_WORKAROUND wasn't defined,
+ * we just blindly did this:
+ * sprintf(sp, format, s->numbr);
+ * s->stlen = strlen(sp);
+ * s->stfmt = (char) index;
+ * but that's no good if, e.g., OFMT is %s. So we punt,
+ * and just always format the value ourselves.
+ */
+
+ NODE *dummy, *r;
+ unsigned short oflags;
+ extern NODE **fmt_list; /* declared in eval.c */
+
+ /* create dummy node for a sole use of format_tree */
+ getnode(dummy);
+ dummy->type = Node_expression_list;
+ dummy->lnode = s;
+ dummy->rnode = NULL;
+ oflags = s->flags;
+ s->flags |= PERM; /* prevent from freeing by format_tree() */
+ r = format_tree(format, fmt_list[index]->stlen, dummy, 2);
+ s->flags = oflags;
+ s->stfmt = (char) index;
+ s->stlen = r->stlen;
+ if ((s->flags & STRCUR) != 0)
+ free(s->stptr);
+ s->stptr = r->stptr;
+ freenode(r); /* Do not free_temp(r)! We want */
+ freenode(dummy); /* to keep s->stptr == r->stpr. */
+
+ goto no_malloc;
+ } else {
+ /* integral value */
+ /* force conversion to long only once */
+ register long num = (long) val;
+ if (num < NVAL && num >= 0) {
+ sp = (char *) values[num];
+ s->stlen = 1;
+ } else {
+ (void) sprintf(sp, "%ld", num);
+ s->stlen = strlen(sp);
+ }
+ s->stfmt = -1;
+ }
+ emalloc(s->stptr, char *, s->stlen + 2, "format_val");
+ memcpy(s->stptr, sp, s->stlen+1);
+no_malloc:
+ s->stref = 1;
+ s->flags |= STRCUR;
+#if defined MBS_SUPPORT
+ if ((s->flags & WSTRCUR) != 0) {
+ assert(s->wstptr != NULL);
+ free(s->wstptr);
+ s->wstptr = NULL;
+ s->wstlen = 0;
+ s->flags &= ~WSTRCUR;
+ }
+#endif
+ return s;
+}
+
+/* r_force_string --- force a value to be a string */
+
+NODE *
+r_force_string(register NODE *s)
+{
+ NODE *ret;
+#ifdef GAWKDEBUG
+ if (s == NULL)
+ cant_happen();
+ if (s->type != Node_val)
+ cant_happen();
+ if (s->stref <= 0)
+ cant_happen();
+ if ((s->flags & STRCUR) != 0
+ && (s->stfmt == -1 || s->stfmt == CONVFMTidx))
+ return s;
+#endif
+
+ ret = format_val(CONVFMT, CONVFMTidx, s);
+ return ret;
+}
+
+/*
+ * dupnode:
+ * Duplicate a node. (For strings, "duplicate" means crank up the
+ * reference count.)
+ */
+
+NODE *
+r_dupnode(NODE *n)
+{
+ register NODE *r;
+
+#ifndef DUPNODE_MACRO
+ if ((n->flags & TEMP) != 0) {
+ n->flags &= ~TEMP;
+ n->flags |= MALLOC;
+ return n;
+ }
+ if ((n->flags & PERM) != 0)
+ return n;
+#endif
+ if ((n->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR)) {
+ if (n->stref < LONG_MAX)
+ n->stref++;
+ else
+ n->flags |= PERM;
+ return n;
+ } else if ((n->flags & MALLOC) != 0 && n->type == Node_ahash) {
+ if (n->ahname_ref < LONG_MAX)
+ n->ahname_ref++;
+ else
+ n->flags |= PERM;
+ return n;
+ }
+ getnode(r);
+ *r = *n;
+ r->flags &= ~(PERM|TEMP|FIELD);
+ r->flags |= MALLOC;
+#if defined MBS_SUPPORT
+ r->wstptr = NULL;
+#endif /* defined MBS_SUPPORT */
+ if (n->type == Node_val && (n->flags & STRCUR) != 0) {
+ r->stref = 1;
+ emalloc(r->stptr, char *, r->stlen + 2, "dupnode");
+ memcpy(r->stptr, n->stptr, r->stlen);
+ r->stptr[r->stlen] = '\0';
+#if defined MBS_SUPPORT
+ if ((n->flags & WSTRCUR) != 0) {
+ r->wstlen = n->wstlen;
+ emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) * (r->wstlen + 2), "dupnode");
+ memcpy(r->wstptr, n->wstptr, r->wstlen * sizeof(wchar_t));
+ r->wstptr[r->wstlen] = L'\0';
+ r->flags |= WSTRCUR;
+ }
+#endif /* defined MBS_SUPPORT */
+ } else if (n->type == Node_ahash && (n->flags & MALLOC) != 0) {
+ r->ahname_ref = 1;
+ emalloc(r->ahname_str, char *, r->ahname_len + 2, "dupnode");
+ memcpy(r->ahname_str, n->ahname_str, r->ahname_len);
+ r->ahname_str[r->ahname_len] = '\0';
+ }
+ return r;
+}
+
+/* copy_node --- force a brand new copy of a node to be allocated */
+
+NODE *
+copynode(NODE *old)
+{
+ NODE *new;
+ int saveflags;
+
+ assert(old != NULL);
+ saveflags = old->flags;
+ old->flags &= ~(MALLOC|PERM);
+ new = dupnode(old);
+ old->flags = saveflags;
+ return new;
+}
+
+/* mk_number --- allocate a node with defined number */
+
+NODE *
+mk_number(AWKNUM x, unsigned int flags)
+{
+ register NODE *r;
+
+ getnode(r);
+ r->type = Node_val;
+ r->numbr = x;
+ r->flags = flags;
+#ifdef GAWKDEBUG
+ r->stref = 1;
+ r->stptr = NULL;
+ r->stlen = 0;
+#if defined MBS_SUPPORT
+ r->wstptr = NULL;
+ r->wstlen = 0;
+ r->flags &= ~WSTRCUR;
+#endif /* MBS_SUPPORT */
+#endif /* GAWKDEBUG */
+ return r;
+}
+
+/* make_str_node --- make a string node */
+
+NODE *
+make_str_node(char *s, unsigned long len, int flags)
+{
+ register NODE *r;
+
+ getnode(r);
+ r->type = Node_val;
+ r->flags = (STRING|STRCUR|MALLOC);
+#if defined MBS_SUPPORT
+ r->wstptr = NULL;
+ r->wstlen = 0;
+#endif
+ if (flags & ALREADY_MALLOCED)
+ r->stptr = s;
+ else {
+ emalloc(r->stptr, char *, len + 2, s);
+ memcpy(r->stptr, s, len);
+ }
+ r->stptr[len] = '\0';
+
+ if ((flags & SCAN) != 0) { /* scan for escape sequences */
+ const char *pf;
+ register char *ptm;
+ register int c;
+ register const char *end;
+#ifdef MBS_SUPPORT
+ mbstate_t cur_state;
+
+ memset(& cur_state, 0, sizeof(cur_state));
+#endif
+
+ end = &(r->stptr[len]);
+ for (pf = ptm = r->stptr; pf < end;) {
+#ifdef MBS_SUPPORT
+ /*
+ * Keep multibyte characters together. This avoids
+ * problems if a subsequent byte of a multibyte
+ * character happens to be a backslash.
+ */
+ if (gawk_mb_cur_max > 1) {
+ int mblen = mbrlen(pf, end-pf, &cur_state);
+
+ if (mblen > 1) {
+ int i;
+
+ for (i = 0; i < mblen; i++)
+ *ptm++ = *pf++;
+ continue;
+ }
+ }
+#endif
+ c = *pf++;
+ if (c == '\\') {
+ c = parse_escape(&pf);
+ if (c < 0) {
+ if (do_lint)
+ lintwarn(_("backslash at end of string"));
+ c = '\\';
+ }
+ *ptm++ = c;
+ } else
+ *ptm++ = c;
+ }
+ len = ptm - r->stptr;
+ erealloc(r->stptr, char *, len + 1, "make_str_node");
+ r->stptr[len] = '\0';
+ r->flags |= PERM;
+ }
+ r->stlen = len;
+ r->stref = 1;
+ r->stfmt = -1;
+
+ return r;
+}
+
+/* tmp_string --- allocate a temporary string */
+
+NODE *
+tmp_string(char *s, size_t len)
+{
+ register NODE *r;
+
+ r = make_string(s, len);
+ r->flags |= TEMP;
+ return r;
+}
+
+/* more_nodes --- allocate more nodes */
+
+#define NODECHUNK 100
+
+NODE *nextfree = NULL;
+
+NODE *
+more_nodes()
+{
+ register NODE *np;
+
+ /* get more nodes and initialize list */
+ emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "more_nodes");
+ memset(nextfree, 0, NODECHUNK * sizeof(NODE));
+ for (np = nextfree; np <= &nextfree[NODECHUNK - 1]; np++) {
+ np->nextp = np + 1;
+ }
+ --np;
+ np->nextp = NULL;
+ np = nextfree;
+ nextfree = nextfree->nextp;
+ return np;
+}
+
+#ifdef MEMDEBUG
+#undef freenode
+/* freenode --- release a node back to the pool */
+
+void
+freenode(NODE *it)
+{
+#ifdef MPROF
+ it->stref = 0;
+ free((char *) it);
+#else /* not MPROF */
+#ifndef NO_PROFILING
+ it->exec_count = 0;
+#endif
+ /* add it to head of freelist */
+ it->nextp = nextfree;
+ nextfree = it;
+#endif /* not MPROF */
+}
+#endif /* GAWKDEBUG */
+
+/* unref --- remove reference to a particular node */
+
+void
+unref(register NODE *tmp)
+{
+ if (tmp == NULL)
+ return;
+ if ((tmp->flags & PERM) != 0)
+ return;
+ tmp->flags &= ~TEMP;
+ if ((tmp->flags & MALLOC) != 0) {
+ if (tmp->type == Node_ahash) {
+ if (tmp->ahname_ref > 1) {
+ tmp->ahname_ref--;
+ return;
+ }
+ free(tmp->ahname_str);
+ } else if ((tmp->flags & STRCUR) != 0) {
+ if (tmp->stref > 1) {
+ tmp->stref--;
+ return;
+ }
+ free(tmp->stptr);
+#if defined MBS_SUPPORT
+ if (tmp->wstptr != NULL) {
+ assert((tmp->flags & WSTRCUR) != 0);
+ free(tmp->wstptr);
+ }
+ tmp->flags &= ~WSTRCUR;
+ tmp->wstptr = NULL;
+ tmp->wstlen = 0;
+#endif
+ }
+ freenode(tmp);
+ return;
+ }
+ if ((tmp->flags & FIELD) != 0) {
+ freenode(tmp);
+ return;
+ }
+}
+
+/*
+ * parse_escape:
+ *
+ * Parse a C escape sequence. STRING_PTR points to a variable containing a
+ * pointer to the string to parse. That pointer is updated past the
+ * characters we use. The value of the escape sequence is returned.
+ *
+ * A negative value means the sequence \ newline was seen, which is supposed to
+ * be equivalent to nothing at all.
+ *
+ * If \ is followed by a null character, we return a negative value and leave
+ * the string pointer pointing at the null character.
+ *
+ * If \ is followed by 000, we return 0 and leave the string pointer after the
+ * zeros. A value of 0 does not mean end of string.
+ *
+ * Posix doesn't allow \x.
+ */
+
+int
+parse_escape(const char **string_ptr)
+{
+ register int c = *(*string_ptr)++;
+ register int i;
+ register int count;
+
+ switch (c) {
+ case 'a':
+ return BELL;
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case 'v':
+ return '\v';
+ case '\n':
+ return -2;
+ case 0:
+ (*string_ptr)--;
+ return -1;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ i = c - '0';
+ count = 0;
+ while (++count < 3) {
+ if ((c = *(*string_ptr)++) >= '0' && c <= '7') {
+ i *= 8;
+ i += c - '0';
+ } else {
+ (*string_ptr)--;
+ break;
+ }
+ }
+ return i;
+ case 'x':
+ if (do_lint) {
+ static int didwarn = FALSE;
+
+ if (! didwarn) {
+ didwarn = TRUE;
+ lintwarn(_("POSIX does not allow `\\x' escapes"));
+ }
+ }
+ if (do_posix)
+ return ('x');
+ if (! ISXDIGIT((*string_ptr)[0])) {
+ warning(_("no hex digits in `\\x' escape sequence"));
+ return ('x');
+ }
+ i = 0;
+ for (;;) {
+ /* do outside test to avoid multiple side effects */
+ c = *(*string_ptr)++;
+ if (ISXDIGIT(c)) {
+ i *= 16;
+ if (ISDIGIT(c))
+ i += c - '0';
+ else if (ISUPPER(c))
+ i += c - 'A' + 10;
+ else
+ i += c - 'a' + 10;
+ } else {
+ (*string_ptr)--;
+ break;
+ }
+ }
+ return i;
+ case '\\':
+ case '"':
+ return c;
+ default:
+ {
+ static short warned[256];
+ unsigned char uc = (unsigned char) c;
+
+ /* N.B.: use unsigned char here to avoid Latin-1 problems */
+
+ if (! warned[uc]) {
+ warned[uc] = TRUE;
+
+ warning(_("escape sequence `\\%c' treated as plain `%c'"), uc, uc);
+ }
+ }
+ return c;
+ }
+}
+
+/* isnondecimal --- return true if number is not a decimal number */
+
+int
+isnondecimal(const char *str, int use_locale)
+{
+ int dec_point = '.';
+#if defined(HAVE_LOCALE_H)
+ /*
+ * loc.decimal_point may not have been initialized yet,
+ * so double check it before using it.
+ */
+ if (use_locale && loc.decimal_point != NULL && loc.decimal_point[0] != '\0')
+ dec_point = loc.decimal_point[0]; /* XXX --- assumes one char */
+#endif
+
+ if (str[0] != '0')
+ return FALSE;
+
+ /* leading 0x or 0X */
+ if (str[1] == 'x' || str[1] == 'X')
+ return TRUE;
+
+ /*
+ * Numbers with '.', 'e', or 'E' are decimal.
+ * Have to check so that things like 00.34 are handled right.
+ *
+ * These beasts can have trailing whitespace. Deal with that too.
+ */
+ for (; *str != '\0'; str++) {
+ if (*str == 'e' || *str == 'E' || *str == dec_point)
+ return FALSE;
+ else if (! ISDIGIT(*str))
+ break;
+ }
+
+ return TRUE;
+}
+
+#if defined MBS_SUPPORT
+/* str2wstr --- convert a multibyte string to a wide string */
+
+NODE *
+str2wstr(NODE *n, size_t **ptr)
+{
+ size_t i, count, src_count;
+ char *sp;
+ mbstate_t mbs;
+ wchar_t wc, *wsp;
+
+ assert((n->flags & (STRING|STRCUR)) != 0);
+
+ if ((n->flags & WSTRCUR) != 0) {
+ if (ptr == NULL)
+ return n;
+ /* otherwise
+ fall through and recompute to fill in the array */
+ }
+
+ if (n->wstptr != NULL) {
+ free(n->wstptr);
+ n->wstptr = NULL;
+ n->wstlen = 0;
+ }
+
+ /*
+ * After consideration and consultation, this
+ * code trades space for time. We allocate
+ * an array of wchar_t that is n->stlen long.
+ * This is needed in the worst case anyway, where
+ * each input bytes maps to one wchar_t. The
+ * advantage is that we only have to convert the string
+ * once, instead of twice, once to find out how many
+ * wide characters, and then again to actually fill
+ * the info in. If there's a lot left over, we can
+ * realloc the wide string down in size.
+ */
+
+ emalloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->stlen + 2), "str2wstr");
+ wsp = n->wstptr;
+
+ /*
+ * For use by do_match, create and fill in an array.
+ * For each byte `i' in n->stptr (the original string),
+ * a[i] is equal to `j', where `j' is the corresponding wchar_t
+ * in the converted wide string.
+ *
+ * Create the array.
+ */
+ if (ptr != NULL) {
+ emalloc(*ptr, size_t *, sizeof(size_t) * n->stlen, "str2wstr");
+ memset(*ptr, 0, sizeof(size_t) * n->stlen);
+ }
+
+ sp = n->stptr;
+ src_count = n->stlen;
+ memset(& mbs, 0, sizeof(mbs));
+ for (i = 0; src_count > 0; i++) {
+ count = mbrtowc(& wc, sp, src_count, & mbs);
+ switch (count) {
+ case (size_t) -2:
+ case (size_t) -1:
+ case 0:
+ goto done;
+
+ default:
+ *wsp++ = wc;
+ src_count -= count;
+ while (count--) {
+ if (ptr != NULL)
+ (*ptr)[sp - n->stptr] = i;
+ sp++;
+ }
+ break;
+ }
+ }
+
+done:
+ *wsp = L'\0';
+ n->wstlen = i;
+ n->flags |= WSTRCUR;
+#define ARBITRARY_AMOUNT_TO_GIVE_BACK 100
+ if (n->stlen - n->wstlen > ARBITRARY_AMOUNT_TO_GIVE_BACK)
+ erealloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 2), "str2wstr");
+
+ return n;
+}
+
+#if 0
+static void
+dump_wstr(FILE *fp, const wchar_t *str, size_t len)
+{
+ if (str == NULL || len == 0)
+ return;
+
+ for (; len--; str++)
+ putc((int) *str, fp);
+}
+#endif
+
+/* wstrstr --- walk haystack, looking for needle, wide char version */
+
+const wchar_t *
+wstrstr(const wchar_t *haystack, size_t hs_len,
+ const wchar_t *needle, size_t needle_len)
+{
+ size_t i;
+
+ if (haystack == NULL || needle == NULL || needle_len > hs_len)
+ return NULL;
+
+ for (i = 0; i < hs_len; i++) {
+ if (haystack[i] == needle[0]
+ && i+needle_len-1 < hs_len
+ && haystack[i+needle_len-1] == needle[needle_len-1]) {
+ /* first & last chars match, check string */
+ if (memcmp(haystack+i, needle, sizeof(wchar_t) * needle_len) == 0) {
+ return haystack + i;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* wcasestrstr --- walk haystack, nocase look for needle, wide char version */
+
+const wchar_t *
+wcasestrstr(const wchar_t *haystack, size_t hs_len,
+ const wchar_t *needle, size_t needle_len)
+{
+ size_t i, j;
+
+ if (haystack == NULL || needle == NULL || needle_len > hs_len)
+ return NULL;
+
+ for (i = 0; i < hs_len; i++) {
+ if (towlower(haystack[i]) == towlower(needle[0])
+ && i+needle_len-1 < hs_len
+ && towlower(haystack[i+needle_len-1]) == towlower(needle[needle_len-1])) {
+ /* first & last chars match, check string */
+ const wchar_t *start;
+
+ start = haystack+i;
+ for (j = 0; j < needle_len; j++, start++) {
+ wchar_t h, n;
+
+ h = towlower(*start);
+ n = towlower(needle[j]);
+ if (h != n)
+ goto out;
+ }
+ return haystack + i;
+ }
+out: ;
+ }
+
+ return NULL;
+}
+#endif /* defined MBS_SUPPORT */
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Sun Jun 26 09:31:35 2005 Scott Deifik <scottd@amgen.com>
+
+ * Makefile: Decrease stack size for MSC.
+ * Makefile.tst (Maketests): Syncronized with what's happening in
+ the main dist.
+
+Thu Apr 28 23:08:51 2005 Scott Deifik <scottd@amgen.com>
+
+ * config.h, Makefile.tst: Synced to main distribution.
+
+Wed Feb 16 10:20:18 2005 Scott Deifik <scottd@amgen.com>
+
+ * Makefile: Decrease stack size for MSC.
+ * Makefile.tst: Syncronized with what's happening in the main dist.
+ * config.h: Improved for DJGPP.
+
+Wed Feb 9 14:38:38 2005 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: Syncronized with what's happening
+ in the main dist.
+
+Thu Feb 3 14:57:28 2005 Scott Deifik <scottd@amgen.com>
+
+ * config.h (SIZEOF_UNSIGNED_INT, SIZEOF_UNSIGNED_LONG): Add definitions.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Sun Jun 13 17:40:09 2004 Scott Deifik <scottd@amgen.com>
+
+ * Makefile: Reduce the stack size for MSC.
+ * Makefile.tst: Synchronized with main distribution.
+
+Sun Jun 13 17:39:47 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile (AWKOBJS2, PAWKOBJS2): Restore version.o.
+
+Tue Jun 1 22:31:36 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile (AWKOBJS2, PAWKOBJS2): Remove version.o.
+
+ Per Jim Meyering:
+ * popen.c (scriptify): Check `realloc' return value.
+
+Tue Mar 2 18:10:55 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile (LIBOJBS): Add `dfa$O' into list.
+ (main$O rule): Removed, since patchlev.h not part of dist
+ anymore.
+
+Tue Mar 2 18:09:54 2004 Scott Deifik <scottd@amgen.com>
+
+ * config.h (HAVE_ALLOCA_H): Undefine.
+ * Makefile (LMSC): Adjust stack size for MSC.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Thu Jun 26 15:00:20 2003 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.tst: Synchronized to main dist.
+
+Sun Jun 15 19:27:58 2003 Patrick T.J. McPhee <ptjm@interlog.com>
+
+ * config.h: Separate the ifdefs for os_system from ssize_t etc.
+
+Sun Jun 15 19:05:15 2003 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.tst: Synchronized to main dist.
+
+Mon Jun 9 17:12:24 2003 Patrick T.J. McPhee <ptjm@interlog.com>
+
+ * dlfcn.c, dlfcn.h, gawke32.def: New files.
+ * Makefile: Changes to allow dynamic linking of libraries
+ under Windows32.
+
+Sun May 11 15:19:52 2003 Scott Deifik <scottd@amgen.com>
+
+ * config.h: Update defs for ssize_t, intmax_t, uintmax_t.
+ * Makefile: Update compile options.
+ * gawkmisc.pc (memcpy_long, memset_long): New functions.
+ * Makefile.tst: Synchronized with test/Makefile.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Sun Feb 23 16:25:44 2003 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: Synchronized to main dist.
+
+Sun Feb 16 15:44:20 2003 Scott Deifik <scottd@amgen.com>
+
+ * config.h: Updated.
+
+Sun Feb 9 11:57:11 2003 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: Synchronized to main dist.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Sun Nov 24 18:37:31 2002 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: Synchronized to main dist.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Thu Apr 18 17:29:16 2002 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.tst (strftime): Remove comment on call to $(CMP).
+
+Sun Mar 10 17:05:35 2002 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.tst: More clean up and sync with ../test/Makefile.
+
+Thu Jan 3 15:20:17 2002 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.tst: Minor clean up and sync with ../test/Makefile.
+
+Wed Dec 19 16:01:58 2001 Peter J. Farley III <pjfarley@dorsai.org>
+
+ * gawkmisc.pc: Just use single quote for `quote' for all cases.
+
+Wed Dec 19 15:59:52 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * install.awk: Install gawkinet.info as well.
+ * awklib/igawk.awk: Bring in sync with awklib/eg/prog/igawk.sh.
+ * makefile (PRSPFILE, PRSP, PLDRSP, DO_PLNK, DO_PBIND, PLDJG): New
+ variables.
+ (djgpp, djgpp-debug): Set PLNK and PBIND.
+ (PBIND): Define to EMPTY as default.
+ (PAWKOBJS1, PAWKOBJS2, PGAWKOBJS): New variables.
+ (all): Add pgawk.exe.
+ (pgawk.exe, $(PRSPFILE)): New rules.
+ ($(ALLOBJS)): Add eval_p.o and profile_p.o to the list of files
+ that are dependent on awk.h, dfa.h, regex.h, and config.h.
+ (eval_p$O, profile_p$O): New dependencies.
+ (clean): Add pgawk and $(PRSPFILE) to files that are to be cleaned
+ up.
+
+Tue Dec 4 16:44:07 2001 Andreas Buening <andreas.buening@nexgo.de>
+
+ Updated OS/2 support.
+
+ * gawkmisc.pc (quote): Use single quote for __EMX__.
+ (os_arg_fixup): new OS/2 code.
+ (os_devopen): for OS/2 return -1.
+ (ispath): check for leading drive letter for __EMX__.
+ (os_close_on_exec): Add check for defined __EMX__.
+ (os_is_setuid): Add real code for __EMX__.
+ (_os2_is_abs_path): new function.
+ (_os2_unixroot): new function.
+ (_os2_unixroot_path): new function.
+
+Tue Sep 25 15:19:53 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_close_on_exec): If fd <= 2, return.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Tue Jan 30 10:56:05 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Per Kay Uwe Rommel, turn on HAVE_FCNTL_H for
+ all PC platforms so that BINMODE works on all.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawkmisc.pc (gawk_name): Support file names with mixed forward-
+ and back-slashes.
+ (orig_tty_mode): New variable.
+ (os_setbinmode): Save the original mode of the console device.
+ [__DJGPP__]: Allow the program to be interrupted with Ctrl-C even
+ though the console was switched to binary mode.
+ (os_restore_mode): New function.
+
+Wed Jan 17 10:59:32 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawkmisc.pc (os_close_on_exec) [__DJGPP__]: Don't print the
+ warning about failure to set close-on-exec bit, unless it's DJGPP
+ 2.04 or later.
+
+Wed Jan 3 19:11:00 2001 Darrel Hankerson <hankedr@auburn.edu>
+
+ * popen.c: write script files in binary only if the shell is
+ unix-like.
+ * Makefile: set threshold (-Gt) on MSC 16bit versions to obtain
+ sufficient stack. 3.0.91 builtin.c compiles with optimization,
+ in MSC[67], so remove the special compile
+
+Wed Jan 3 19:54:12 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h, gawkmisc.pc: Allow fcntl if DGJPP. From Scott.
+
+Sun Dec 3 16:53:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_setbinmode): new function.
+
+Sun Dec 3 14:56:38 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile, Makefile.tst, gawkmisc.pc: updated from Scottd.
+ * popen.c: updated from Darrell Hankerson.
+
+Wed Nov 22 11:47:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.rsp, pc_popen.c, pc_popen.h, Makefile, Makefile.tst,
+ gawkmisc.pc: Synched with diffs from Scott Deifik.
+ * config.h: Updated from main dist, best guess by me, will
+ probably need tweaking.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_is_setuid): new function.
+
+Thu Nov 5 16:50:09 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * gawkmisc.pc (os_devopen): handle "/dev/null".
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Close-on-exec changes:
+ gawkmisc.pc: (os_close_on_exec, os_isdir): new functions.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 21 16:44:54 2000 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: synchronized with main dist, again.
+
+Thu May 18 14:07:52 2000 Scott Deifik <scottd@amgen.com>
+
+ * Makefile, Makefile.tst: synchronized with main dist.
+ * config.h: Define HAVE_LIMITS_H as 1.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Sun Jun 27 12:27:00 1999 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * Makefile, Makefile.tst, ../README_d/README.pc: finalized.
+ * include/process.h: new file
+
+Fri May 21 00:00:00 1999 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * popen.c: MSC (on DOS/Windows32) and MINGW32 now honor SHELL.
+ * io.c: MINGW32 reports errno==0 after failure in redirect();
+ assume close_one() in this case.
+ * io.c: Add HAVE_POPEN_H and let pc/config.h deal with the mess.
+ (Can't move everything to config.h because of popen define.)
+
+Sun May 9 09:12:33 1999 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * Add 1999-04-30 changes from Eli Zaretskii <eliz@is.elta.co.il>
+ 1. Makefile (TAGS, tags): New targets.
+ 2. Makefile.tst (regtes): Pass the value of $CMP to the
+ regtest script.
+
+Thu Nov 18 03:48:32 1998 Scott Deifik <scottd@amgen.com>
+
+ * Readme.pc: More LFN-based comments.
+
+Thu Nov 12 21:01:24 1998 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * mingw32 target added with corresponding minor changes to getid.c,
+ io.c, and config.h.
+
+ * vcWin32 needed popen defines in config.h which were inadvertently
+ omitted from 3.0.3.
+
+ * README.pc updated to clarify the procedure for building
+ non-LFN versions on LFN systems, and to note that Windows32 gawk
+ may require Windows32 utilities.
+
+ * emxbnd target modified to accomodate older versions of emx.
+
+Thu Nov 08 09:11:44 1998 Scott Deifik <scottd@amgen.com>
+
+ * pc/Makefile: Stack reduced again for 16bit MSC versions.
+
+ * pc/Makefile.tst: Updated to keep in sync with new
+ test/Makefile.in. In addition, made to work in Windows 9x
+ with non-LFN tools.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Tue May 13 20:06:09 1997 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * vcWin32 target added. Some new tests for WIN32 in gawkmisc.c
+ io.c, and regex.c. Makefile changes for nmake, which can't
+ expand $($x).
+
+ * config.h updated for BITOPS and NONDECDATA (also in Makefile).
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Fri Jan 17 19:20:45 1997 Darrel Hankerson <hankedr@mail.auburn.edu>
+
+ * Makefile: add KUR's emxnt target for emx+RSXNT. Create awk.exe
+ "link" to gawk.exe for djgpp target. (Suggested by Eli Zaretskii.
+ Should be done as part of a smarter install, since awk.exe only
+ works with djgpp gawk.exe.) Separate djgpp-v1 into djgppv1
+ target. Install awk.exe if present.
+
+ * install.awk: install awk.exe if present (only for djgpp)
+
+ * config.h: additional include for emx+RSXNT.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Thu Aug 1 19:46:00 1996 Scott Deifik <scottd@amgen.com>
+
+ * Makefile: Changes for MSC 8.
+
+Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * ChangeLog created.
--- /dev/null
+# Makefile for gawk (GNU awk) Dec 2000
+#
+# - for GNU C (djgpp) [32bit executable for DOS]
+# - for GNU C (emx) [32bit executable for OS/2 or DOS or Windows32]
+# - for GNU C (mingw32) [Windows32 executable for Windows 9x/NT]
+# - for MS-Visual C/C++ 4.x [Windows32 executable for Windows 9x/NT]
+# - for Microsoft C 7 [16bit ececutable for DOS]
+# - for Microsoft C 6.00A [16bit executable for OS/2 or DOS]
+
+# Tested with GNU make and dmake-3.8 under OS/2 and DOS, and ndmake and
+# Microsoft nmake under DOS. Compiling with dmake under DOS may require the
+# DOS-only version of dmake (so that swapping works). nmake requires a
+# few edits in the configuration section below.
+
+default:
+ @echo "Enter $(MAK) target "
+ @echo " where 'target' is chosen from "
+ @echo " djgpp ... DOS 32-bit exe [GNU C, Delorie, v2] "
+ @echo " djgppv1 . DOS 32-bit exe [GNU C, Delorie, v1] "
+ @echo " emx ..... OS/2 32-bit exe [emx/gcc; uses emxlibc.dll] "
+ @echo " emxnt ... NT exe [emx/gcc with RSXNT] "
+ @echo " emxbnd .. OS/2 and DOS 32-bit exe [emx/gcc] "
+ @echo " mingw32 . Windows32 exe [Mingw32 GNU C] "
+ @echo " msc ..... DOS exe [Microsoft C 7 & 8 (AKA 1.52)] "
+ @echo " msc6 .... DOS exe [Microsoft C 6.00a] "
+ @echo " msc6os2 . OS/2 exe [Microsoft C 6.00a] "
+ @echo " msc6bnd . OS/2 and DOS exe [Microsoft C 6.00a] "
+ @echo " vcWin32 . Windows32 exe [Microsoft Visual C] "
+ @echo " ----------------------------------------------------- "
+ @echo " test .... Perform tests (see README_d/README.pc) "
+ @echo " install . Install gawk under $(prefix)/ "
+
+# Support dropped in 3.0
+# - for Microsoft C 5.1 [16bit executable for OS/2 or DOS]
+# @echo " msc51 DOS exe [Microsoft C 5.1] "
+# @echo " msc51bnd OS/2 and DOS exe [Microsoft C 5.1] "
+
+#======================= Configuration ==================================
+RSPFILE = gawk.rsp
+PRSPFILE = pgawk.rsp
+#
+# Choose method for passing arguments to the linker.
+#
+# If compiling under OS/2 or if make can pass long lines
+#LDRSP = $(GAWKOBJS)
+#LNKRSP = $(LDRSP)
+#
+# else if make == dmake
+# Response files for linker: dmake allows the macro expansion
+# $(macro_name:modifier_list:modifier_list:...)
+# The macro mktmp creates a temporary file for the linker.
+# The 't' modifier is for tokenization.
+#LDRSP = @$(mktmp $(<:t"\n"))
+#LNKRSP = @$(mktmp $(<:t"+\n") ) # Space before final paren req
+#
+# else use brain-dead approach (emxbnd will need 'tr').
+RSP = $(RSPFILE)
+PRSP = $(PRSPFILE)
+LDRSP = @$(RSP)
+PLDRSP = @$(PRSP)
+LNKRSP = $(LDRSP)
+#------------------------------------------------------------------------
+# Some makes do not define MAKE (and ndmake does not allow a define).
+# Define MAK to be your make command.
+#MAKE = dmake
+MAK = $(MAKE) $(MAKEFILE)
+#MAK = $(MAKE)
+#MAKEFILE = -f Makefile
+#MAK = make45 $(MAKEFILE)
+#------------------------------------------------------------------------
+# Define the base directory for the install. "make install" will install
+# in bin, lib/awk, man, and info under $(prefix)/. Most likely, you should
+# edit config.h so that $(prefix)/lib/awk appears as part of DEFPATH.
+#prefix =
+prefix = c:/gnu
+#
+# Define the install method. Method 1 is Unix-like (and requires cat,
+# cp, mkdir, sed, and sh); method 2 uses gawk and batch files.
+install = 1
+#------------------------------------------------------------------------
+# To work around command-line length problems, this makefile assumes
+# that $($X) can be expanded. If using a make (such as nmake) which
+# cannot handle such macros, define DO_LNK and DO_BIND for your target
+# as $(L<target>) and $(B<target>), resp.; e.g.,
+#DO_LNK = $(LvcWin32)
+#DO_PLNK = $(PLvcWin32)
+# and then comment the following:
+DO_LNK = $($(LNK))
+DO_BIND= $($(BIND))
+DO_PLNK = $($(PLNK))
+DO_PBIND= $($(PBIND))
+#------------------------------------------------------------------------
+# For dynamic extension support, uncomment these lines
+# pick the appropriate .def file entry for your compiler
+#DYN_FLAGS=-DDYNAMIC
+#DYN_EXP=gawk.exp
+#DYN_OBJ=dlfcn$O $(DYN_EXP)
+#DYN_MAKEXP=$(DMEvcWin32)
+#DYN_MAKEXP=$(DMEmingw32)
+#
+#========================================================================
+# End of general configuration. Some platform-specific configuration
+# notes appear below.
+
+#========================================================================
+#========================== DJGPP =======================================
+#========================================================================
+
+LDJG = $(CC) $(LF) -o gawk.exe $(LDRSP) $(LF2)
+PLDJG = $(CC) $(LF) -o pgawk.exe $(PLDRSP) $(LF2)
+BDJG = stubify -g awk.exe | stubedit awk.exe runfile=gawk
+
+djgpp:
+ $(MAK) all \
+ CC=gcc O=.o CF=-O2 \
+ LNK=LDJG PLNK=PLDJG LF=-s LF2=-lm \
+ BIND=BDJG PBIND=''
+
+djgpp-debug:
+ $(MAK) all \
+ CC=gcc O=.o CF='-O2 -g' \
+ LNK=LDJG PLNK=PLDJG LF2=-lm \
+ BIND=BDJG PBIND=''
+
+LDJGv1 = $(CC) $(LF) -o gawk $(LDRSP) $(LF2)
+#BDJGv1 = coff2exe -s /djgpp/bin/go32.exe gawk
+BDJGv1 = coff2exe gawk
+
+djgppv1:
+ $(MAK) all \
+ CC=gcc O=.o CF=-O \
+ LNK=LDJGv1 LF=-s LF2=-lm \
+ BIND=BDJGv1
+
+#========================================================================
+#========================== EMX =========================================
+#========================================================================
+
+# Link command for OS/2 versions.
+LEMX = $(CC) $(LF) -o $@ $(GAWKOBJS) gawk.def -lbsd $(LF2)
+
+# Link and bind for DOS and OS/2 versions.
+# emx-09 needs '-p' emx option here or in EMXOPT environ var.
+# The following works with 0.9a or newer
+LEMXBND = $(CC) $(LF) -o gawk $(LDRSP) gawk.def -lbsd $(LF2)
+BEMX = emxbind -bs gawk -p
+# The following works with 0.9c or newer
+#LEMXBND = $(CC) $(LF) -o a.out $(LDRSP) gawk.def -lbsd $(LF2)
+#BEMX = emxbind -bs -o $@ a.out -p
+#BEMX = emxbind -bs /emx/bin/emx.exe a.out $@ -p
+BEMXD = emxbind -b -o $@ a.out -p
+
+emx:
+ $(MAK) all \
+ "CC=gcc -Zomf" O=.obj "CF=-O -DOS2" \
+ LNK=LEMX "LF=-s -Zcrtdll -Zstack 512" RSP=
+
+emxnt:
+ $(MAK) all \
+ "CC=gcc -Zwin32 -Zcrtdll=rsxntcs" O=.o "CF=-O -DOS2" \
+ LNK=LEMX "LF=-s -Zstack 512" RSP=
+
+emxbnd:
+ $(MAK) all \
+ CC=gcc O=.o "CF=-O -DOS2 -DMSDOS" OBJ=popen.o \
+ LNK=LEMXBND \
+ BIND=BEMX "P=|tr \" \" \"\n\""
+
+emxbnd-debug:
+ $(MAK) all \
+ CC=gcc O=.o "CF=-g -DOS2 -DMSDOS" OBJ=popen.o \
+ LNK=LEMXBND \
+ BIND=BEMXD "P=|tr \" \" \"\n\""
+
+#========================================================================
+#========================== MINGW32 =====================================
+#========================================================================
+
+DMEmingw32 = dlltool -D gawk.exe -d gawkw32.def -e gawk.exp -l libgawk.a
+
+LMINGW32 = $(CC) $(LF) -o $@ $(GAWKOBJS) $(LF2)
+PLMINGW32 = $(CC) $(LF) -o $@ $(PGAWKOBJS) $(LF2)
+# The following might work around command-line length limitations:
+#LMINGW32 = $(CC) $(LF) -o $@ *.o $(LF2)
+
+mingw32:
+ $(MAK) all \
+ CC=gcc O=.o CF=-O OBJ=popen.o \
+ LNK=LMINGW32 PLNK=PLMINGW32 LF=-s RSP=
+
+#========================================================================
+#========================== MSC =========================================
+#========================================================================
+
+# stdargv, glob, and director are from Stewartson's sh. These provide
+# globbing and enhanced argument-passing. MSC setargv.obj is a
+# more limited alternative (and it will permit a bound version).
+#STDARGV = stdargv.obj glob.obj director.obj
+STDARGV = setargv.obj
+
+# Optimization and library options:
+# Os == optimize for size, Ot == optimize for speed, G2 == 286 or better
+#MSCOPT = -Gt3600 -Os -G2
+# MSC seems to be more stable with -Od than with -Ot, but then regexec.c gives
+# "code segment too large" error when compiling. Adding -G2y fixes this and
+# lets us keep the -Od.
+MSCOPT = -Gt3600 -Od -G2y
+# Alternate lib, does not use math coprocessor.
+#MSCLIB = llibca
+#MSCCL = -FPa
+# Emulator lib, uses math coprocessor if present.
+MSCLIB = llibce
+MSCCL = -FPi
+#MSCCL = -FPc
+
+# If the stack gets much smaller than 3000, the "longwrds" test fails.
+LMSC = link $(LF) $(LNKRSP) $(STDARGV)/NOE,$@,,/NOD:llibce $(MSCLIB)$(LF2)/STACK:0x2eb0,nul
+
+
+# CLMSC-linking works when building under OS/2
+CLMSC = $(CC) -o $@ $(LF) $(GAWKOBJS) $(STDARGV) $(LF2) -link /NOE/NOI/STACK:0x6f00
+
+BMSC = bind $@ /n DOSMAKEPIPE DOSCWAIT
+
+
+# Ugly hack: config.h defines __STDC__ if not defined on command-line.
+# OS/2 versions can't use -Za in getid.c. MSC7 uses stub headers in pc/
+# due to ANSI conflicts. MSC 5.1 defines __STDC__=0 regardless of ANSI flag.
+
+# dmake-3.8 runs out of memory under DOS. Request that dmake
+# swap itself out on these targets. Note that this won't have
+# any affect on the bound OS/2 and DOS version of dmake-3.8.
+
+.SWAP: msc msc-debug msc6 msc6os2 msc6bnd msc51 check
+
+msc:
+ $(MAK) all \
+ "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Ze -Ipc/include $(MSCOPT)" \
+ OBJ=popen.obj \
+ LNK=LMSC P=+
+Lmsc = $(LMSC) # for broken makes (nmake) which cannot expand $($X)
+Bmsc =
+
+msc-debug:
+ $(MAK) all \
+ "CC=cl $(MSCCL)" O=.obj "CF=-AL -Ze -Ipc/include -W2 -Zi -Od" \
+ OBJ=popen.obj \
+ LNK=LMSC LF2=/CO P=+
+
+msc6:
+# $(MAK) builtin.obj \
+# "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Za $(MSCOPT) -Od"
+ $(MAK) all \
+ "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Za $(MSCOPT)" \
+ OBJ=popen.obj \
+ LNK=LMSC P=+
+Lmsc6 = $(LMSC) # for broken makes (nmake) which cannot expand $($X)
+Bmsc6 =
+
+msc6os2:
+# $(MAK) builtin.obj \
+# "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -DOS2 -UMSDOS $(MSCOPT) -Od"
+ $(MAK) all \
+ "CC=cl $(MSCCL)" O=.obj "CF=-AL -DOS2 -UMSDOS $(MSCOPT)" \
+ LNK=LMSC "LF2=p,gawk.def" P=+
+
+msc6bnd:
+# $(MAK) builtin.obj \
+# "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -DOS2 $(MSCOPT) -Od"
+ $(MAK) all \
+ "CC=cl $(MSCCL)" O=.obj "CF=-AL -DOS2 $(MSCOPT)" \
+ OBJ=popen.obj \
+ LNK=LMSC "LF2=p,gawk.def" P=+ \
+ BIND=BMSC
+Lmsc6bnd = $(LMSC) # for broken makes (nmake) which cannot expand $($X)
+Bmsc6bnd = $(BMSC)
+
+
+# Windows '9x / NT
+DMEvcWin32 = lib /def:gawkw32.def /name:gawk.exe /out:gawk.lib
+LvcWin32 = link -nologo -subsystem:console -release -out:$@ $(LNKRSP)
+PLvcWin32 = link -nologo -subsystem:console -release -out:$@ $(PLDRSP)
+
+vcWin32:
+ $(MAK) all \
+ "CC=cl -nologo" O=.obj "CF=-o2 -DWIN32 -D__STDC__=0" \
+ OBJ=popen.obj \
+ LNK=LvcWin32
+
+
+# Support dropped in 3.0
+#msc51:
+# $(MAK) all \
+# "CC=cl $(MSCCL)" O=.obj "CF=-AL -Za -D_MSC_VER=510 $(MSCOPT)" \
+# OBJ=popen.obj \
+# LNK=LMSC P=+
+#
+#msc51bnd:
+# $(MAK) all \
+# "CC=cl -AL ($MSCCL)" O=.obj "CF=-DOS2 -D_MSC_VER=510 $(MSCOPT)" \
+# OBJ=popen.obj \
+# LNK=CLMSC "LF=-Lp -Fb" "LF2=gawk.def"
+
+#========================================================================
+
+# Define BIND for BINDless compiles, otherwise $($(BIND)) may break.
+BIND = EMPTY
+PBIND = EMPTY
+EMPTY=
+
+# bitwise operations (-DBITOPS) and non-decimal input data (-DNONDECDATA) are
+# undocumented in 3.0.3. They may be enabled in config.h, or added to CFLAGS.
+CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H $(DYN_FLAGS)
+
+# object files
+AWKOBJS1 = array$O builtin$O eval$O field$O gawkmisc$O io$O main$O
+AWKOBJS2 = ext$O msg$O node$O profile$O re$O version$O $(DYN_OBJ)
+PAWKOBJS1 = array$O builtin$O eval_p$O field$O gawkmisc$O io$O main$O
+PAWKOBJS2 = ext$O msg$O node$O profile_p$O re$O version$O $(DYN_OBJ)
+AWKOBJS = $(AWKOBJS1) $(AWKOBJS2)
+
+ALLOBJS = $(AWKOBJS) awkgram$O getid$O $(OBJ)
+
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS= getopt$O getopt1$O dfa$O regex$O random$O
+
+GAWKOBJS = $(ALLOBJS) $(LIBOBJS)
+PGAWKOBJS = $(PAWKOBJS1) $(PAWKOBJS2) $(LIBOBJS) awkgram$O getid$O $(OBJ)
+
+# clear out suffixes list
+# .SUFFIXES:
+.SUFFIXES: .c $O
+
+.c$O:
+ $(CC) -c $(CFLAGS) $<
+
+# rules to build gawk
+all : gawk.exe pgawk.exe
+
+gawk.exe:: $(GAWKOBJS) $(RSP)
+ $(DO_LNK)
+ $(DO_BIND)
+
+pgawk.exe:: $(PGAWKOBJS) $(PRSP)
+ $(DO_PLNK)
+ $(DO_PBIND)
+
+$(RSPFILE) : $(GAWKOBJS)
+ echo $(AWKOBJS1)$P > $@
+ echo $(AWKOBJS2)$P >> $@
+ echo awkgram$O getid$O $(OBJ) $(LIBOBJS)$P >> $@
+
+$(PRSPFILE) : $(PGAWKOBJS)
+ echo $(PAWKOBJS1)$P > $@
+ echo $(PAWKOBJS2)$P >> $@
+ echo awkgram$O getid$O $(OBJ) $(LIBOBJS)$P >> $@
+
+$(ALLOBJS) eval_p$O profile_p$O: awk.h regex.h config.h
+
+gawkmisc$O: pc/gawkmisc.pc
+
+getopt$O: getopt.h
+
+getopt1$O: getopt.h
+
+gawk.exp: gawkw32.def
+ $(DYN_MAKEXP)
+
+eval_p$O: eval.c
+
+profile_p$O: profile.c
+
+# A bug in ndmake requires the following rule
+awkgram$O: awk.h awkgram.c
+ $(CC) -c $(CFLAGS) awkgram.c
+
+awkgram.c: awkgram.y
+ bison -o $@ awkgram.y
+
+alloca$O: alloca.c
+
+
+install: install$(install)
+
+install1:
+ echo extproc sh $(prefix)/bin/igawk.cmd > igawk.cmd
+ echo shift >> igawk.cmd
+ cat pc/awklib/igawk >> igawk.cmd
+ sed "s;igawk;$(prefix)/bin/igawk;" pc/awklib/igawk.bat > igawk.bat
+ sh mkinstal.sh $(prefix)/bin
+ sh mkinstal.sh $(prefix)/lib/awk $(prefix)/man/man1 $(prefix)/info
+ cp *awk.exe igawk.bat igawk.cmd pc/awklib/igawk $(prefix)/bin
+ cp awklib/eg/lib/* pc/awklib/igawk.awk $(prefix)/lib/awk
+ cp doc/*.1 $(prefix)/man/man1
+ cp doc/gawk.info $(prefix)/info
+
+# install2 is equivalent to install1, but doesn't require cp, sed, etc.
+install2:
+ gawk -v prefix=$(prefix) -f install.awk
+
+clean:
+ rm -rf gawk pgawk *.exe gawk.map *.o *.obj core a.out $(RSPFILE) $(PRSPFILE) $(DYN_EXP)
+# cd doc && $(MAKE) clean
+# cd test && $(MAKE) clean
+# cd awklib && $(MAKE) clean
+
+awklib/eg: doc/gawk.texi
+ rm -fr awklib/eg
+ sh -c "cd awklib && ../gawk -f extract.awk ../doc/gawk.texi"
+
+check:
+ @echo "Running the tests requires several unix-like utilities. The"
+ @echo "recommendation is to copy pc/Makefile.tst to test/Makefile. Under"
+ @echo "DOS, it may be necessary to run make from the test directory."
+# The `-k' option to make should be unnecessary if using pc/Makefile.tst.
+ sh -c "cd test && $(MAK) -k AWK=../gawk.exe"
+# sh -c "cd test && $(MAK) AWK=../gawk.exe bigtest extra"
+
+test: check
+
+# for those who have the necessary tools:
+TAGS:
+ etags awk.h *.y custom.h *.c *.h
+
+tags:
+ ctags awk.h *.y custom.h *.c *.h
--- /dev/null
+# Makefile for GNU Awk test suite.
+#
+# Copyright (C) 1988-2004 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+# ============================================================================
+# MS-DOS & OS/2 Notes: READ THEM!
+# ============================================================================
+
+# As of version 2.91, efforts to make this makefile run in MS-DOS and OS/2
+# have started in earnest. The following steps need to be followed in order
+# to run this makefile:
+#
+# 1. The first thing that you will need to do is to convert all of the
+# files ending in ".ok" in the test directory, all of the files ending
+# in ".good" (or ".goo") in the test/reg directory, and mmap8k.in from
+# having a linefeed to having carriage return/linefeed at the end of each
+# line. There are various public domain UNIX to DOS converters and any
+# should work. Alternatively, you can use diff instead of cmp--most
+# versions of diff don't care about how the lines end.
+#
+# 2. You will need an sh-compatible shell. Please refer to the "README.pc"
+# file in the README_d directory for information about obtaining a copy.
+# You will also need various UNIX utilities. At a minimum, you will
+# need: rm, tr, cmp (or diff, see above), cat, wc, and sh.
+# You should also have a UNIX-compatible date program.
+#
+# The makefile has only been tested with dmake 3.8 and DJGPP Make 3.74 or
+# later. After making all of these changes, typing "dmake bigtest extra"
+# or "make bigtest extra" (with DJGPP Make) should run successfully.
+
+# The Bash shell (compiled with djgpp) works very well with the
+# MSC & djgpp-compiled gawks. It is currently the recommended shell to use
+# for testing, along with DJGPP make. See README.pc for
+# more information on OS/2 and DOS shells.
+
+# You will almost certainly need to change some of the values (MACROS)
+# defined on the next few lines.
+
+# This won't work unless you have "sh" and set SHELL equal to it (Make 3.74
+# or later which comes with DJGPP will work with SHELL=/bin/sh if you have
+# sh.exe anywhere on your PATH).
+#SHELL = e:\bin\sh.exe
+SHELL = /bin/sh
+
+# Point to gawk
+AWK = ../gawk.exe
+# Also point to gawk but for DOS commands needing backslashes. We need
+# the forward slash version too or 'arrayparam' fails.
+AWK2 = '..\gawk.exe'
+AWKPROG = ../gawk.exe
+
+# Set your cmp command here (you can use most versions of diff instead of cmp
+# if you don't want to convert the .ok files to the DOS CR/LF format).
+# This is also an issue for the "mmap8k" test. If it fails, make sure that
+# mmap8k.in has CR/LFs or that you've used diff.
+#
+# The following comment is for users of OSs which support long file names
+# (such as Windows 95) for all versions of gawk (both 16 & 32-bit).
+# If you use a shell which doesn't support long filenames, temporary files
+# created by this makefile will be truncated by your shell. "_argarra" is an
+# example of this. If $(CMP) is a DJGPP-compiled program, then it will fail
+# because it looks for the long filename (eg. _argarray). To fix this, you
+# need to set LFN=n in your shell's environment.
+# NOTE: Setting LFN in the makefile most probably won't help you because LFN
+# needs to be an environment variable.
+#CMP = cmp
+# See the comment above for why you might want to set CMP to "env LFN=n diff"
+#CMP = env LFN=n diff
+CMP = diff
+#CMP = diff -c
+#CMP = gcmp
+
+# Set your "cp" and "mkdir" commands here. Note: DOS's copy must take forward
+# slashes.
+#CP = cp
+#CP = : && command -c copy
+CP = command.com /c copy
+
+#MKDIR = mkdir
+#MKDIR = gmkdir
+#MKDIR = : && command -c mkdir
+MKDIR = command.com /c mkdir
+
+# Set your unix-style date function here
+#DATE = date
+DATE = gdate
+
+# MS-DOS and OS/2 use ; as a PATH delimiter
+PATH_SEPARATOR = ;
+
+# ============================================================================
+# You shouldn't need to modify anything below this line.
+# ============================================================================
+
+srcdir = .
+
+# Get rid of core files when cleaning
+CLEANFILES = core core.*
+
+# try to keep these sorted
+BASIC_TESTS = addcomma anchgsub argarray arrayparm arrayref arrymem1 \
+ arrayprm2 arrayprm3 arryref2 arryref3 arryref4 arryref5 arynasty \
+ arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
+ aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
+ clsflnam compare compare2 concat1 concat2 concat3 convfmt datanonl defref \
+ delarprm delarpm2 delfunc dynlj eofsplit exitval1 exitval2 fldchg fldchgnf fmttest fnamedat \
+ fnarray fnarray2 fnarydel fnaryscl fnasgnm fnmisc fnparydl \
+ fordel forsimp fsbs fsspcoln fsrs fstabplus funsemnl funsmnam funstack getline \
+ getline2 getline3 getlnbuf getnr2tb getnr2tm gsubasgn gsubtest \
+ gsubtst2 gsubtst3 gsubtst4 gsubtst5 hex hsprint inputred intest \
+ intprec iobug1 leaddig leadnl litoct longsub longwrds manglprm math membug1 \
+ messages minusstr mmap8k nasty nasty2 negexp nested nfldstr \
+ nfneg nfset nlfldsep nlinstr nlstrina noeffect nofmtch noloop1 \
+ noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
+ ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup paramtyp \
+ parseme pcntplus prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval psx96sub rand rebt8b1 rebt8b2 redfilnm regeq \
+ reindops reparse resplit rs rsnul1nl rsnulbig rsnulbig2 rstest1 \
+ rstest2 rstest3 rstest4 rstest5 rswhite scalar sclforin sclifin \
+ sortempty splitargv splitarr splitdef splitvar splitwht sprintfc \
+ strcat1 strtod subamp subsepnm subslash substr swaplns synerr1 tradanch \
+ tweakfld uninit2 uninit3 uninit4 uninitialized unterm wjposer1 \
+ zeroe0 zeroflag
+
+UNIX_TESTS = fflush getlnhd pid pipeio1 pipeio2 poundbang space strftlng
+GAWK_EXT_TESTS = argtest asort asorti backw badargs clos1way fieldwdth fsfwfs \
+ gensub gensub2 gnuops2 gnuops3 gnureops icasefs icasers igncdym igncfs ignrcase \
+ ignrcas2 lint match1 match2 manyfiles nondec posix procinfs \
+ printfbad1 regx8bit rebuf reint rsstart1 rsstart2 rsstart3 \
+ rstest6 shadow sort1 strtonum strftime whiny
+
+EXTRA_TESTS = regtest inftest
+INET_TESTS = inetechu inetecht inetdayu inetdayt
+
+# List of the tests which should be run with --lint option:
+NEED_LINT = defref noeffect nofmtch shadow uninit2 uninit3 uninit4 uninitialized
+
+# List of the files that appear in manual tests or are for reserve testing:
+GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk switch2.awk
+
+# Message stuff is to make it a little easier to follow.
+# Make the pass-fail last and dependent on others to avoid
+# spurious errors if `make -j' in effect.
+check: msg \
+ printlang \
+ basic-msg-start basic basic-msg-end \
+ unix-msg-start unix-tests unix-msg-end \
+ extend-msg-start gawk-extensions extend-msg-end \
+ pass-fail
+
+basic: $(BASIC_TESTS)
+
+unix-tests: $(UNIX_TESTS)
+
+gawk-extensions: $(GAWK_EXT_TESTS)
+
+#extra: $(EXTRA_TESTS) inet
+extra: $(EXTRA_TESTS) inetmesg
+
+inet: inetmesg $(INET_TESTS)
+
+msg::
+ @echo ''
+ @echo 'Any output from "cmp" is bad news, although some differences'
+ @echo 'in floating point values are probably benign -- in particular,'
+ @echo 'some systems may omit a leading zero and the floating point'
+ @echo 'precision may lead to slightly different output in a few cases.'
+
+printlang::
+ @$(AWK) -f $(srcdir)/printlang.awk
+
+basic-msg-start:
+ @echo "======== Starting basic tests ========"
+
+basic-msg-end:
+ @echo "======== Done with basic tests ========"
+
+unix-msg-start:
+ @echo "======== Starting Unix tests ========"
+
+unix-msg-end:
+ @echo "======== Done with Unix tests ========"
+
+extend-msg-start:
+ @echo "======== Starting gawk extension tests ========"
+
+extend-msg-end:
+ @echo "======== Done with gawk extension tests ========"
+
+# This test is a PITA because increasingly, /tmp is getting
+# mounted noexec. So, we'll test it locally. Sigh.
+#
+# More PITA; some systems have medium short limits on #! paths,
+# so this can still fail
+poundbang::
+ @echo $@
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @chmod +x ./_pbd.awk
+ @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ then : ; \
+ else \
+ sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ chmod +x ./_pbd.awk ; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@`; \
+ fi
+ @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+
+messages::
+ @echo $@
+ @$(AWK) -f $(srcdir)/messages.awk >out2 2>out3
+ @-$(CMP) $(srcdir)/out1.ok out1 && $(CMP) $(srcdir)/out2.ok out2 && $(CMP) $(srcdir)/out3.ok out3 && rm -f out1 out2 out3
+
+argarray::
+ @echo $@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) cp $(srcdir)/argarray.in . ;; \
+ esac
+ @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) rm -f ./argarray.in ;; \
+ esac
+ @-$(CMP) $(srcdir)/argarray.ok _$@ && rm -f _$@
+
+regtest::
+ @echo 'Some of the output from regtest is very system specific, do not'
+ @echo 'be distressed if your output differs from that distributed.'
+ @echo 'Manual inspection is called for.'
+ AWK=`pwd`/$(AWK) $(srcdir)/regtest.sh
+
+manyfiles::
+ @echo manyfiles
+ @rm -rf junk
+ @mkdir junk
+ @$(AWK) 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >_$@
+ @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
+ @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare::
+ @echo $@
+ @$(AWK) -f $(srcdir)/compare.awk 0 1 $(srcdir)/compare.in >_$@
+ @-$(CMP) $(srcdir)/compare.ok _$@ && rm -f _$@
+
+inftest::
+ @echo $@
+ @echo This test is very machine specific...
+ @echo This sometimes seems to cause problems for MSC gawk, so do not
+ @echo run it.
+# @$(AWK) -f $(srcdir)/inftest.awk | sed "s/inf/Inf/g" >_$@
+# @-$(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@
+
+getline2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
+ @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+
+awkpath::
+ @echo $@
+ @AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
+ @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+
+argtest::
+ @echo $@
+ @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
+ @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+
+badargs::
+ @echo $@
+ @-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
+ @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+
+nonl::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+
+strftime::
+ @echo This test could fail on slow machines or on a minute boundary,
+ @echo so if it does, double check the actual results:
+ @echo $@
+# @GAWKLOCALE=C; export GAWKLOCALE; \
+# TZ=GMT0; export TZ; \
+# (LC_ALL=C date) | $(AWK) -v OUTPUT=_$@ -f $(srcdir)/strftime.awk
+ @GAWKLOCALE=C; export GAWKLOCALE; \
+ TZ=GMT0; export TZ; \
+ (LC_ALL=C $(DATE)) | $(AWK) -v OUTPUT=_$@ -f $(srcdir)/strftime.awk
+ @-$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0
+
+litoct::
+ @echo $@
+ @echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
+ @-$(CMP) $(srcdir)/litoct.ok _$@ && rm -f _$@
+
+fflush::
+ @echo $@
+ @$(srcdir)/fflush.sh >_$@
+ @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+
+tweakfld::
+ @echo $@
+ @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @rm -f errors.cleanup
+ @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+
+mmap8k::
+ @echo $@
+ @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
+ @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+
+tradanch::
+ @echo $@
+ @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
+ @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+
+# AIX /bin/sh exec's the last command in a list, therefore issue a ":"
+# command so that pid.sh is fork'ed as a child before being exec'ed.
+pid::
+ @echo pid
+ @echo Expect pid to fail with DJGPP.
+ @AWKPATH=$(srcdir) AWK=$(AWKPROG) $(SHELL) $(srcdir)/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) $(srcdir)/pid.ok _`basename $@` && rm -f _`basename $@` _`basename $@`.in
+
+strftlng::
+ @echo $@
+ @TZ=UTC; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@
+ @if $(CMP) $(srcdir)/strftlng.ok _$@ >/dev/null 2>&1 ; then : ; else \
+ TZ=UTC0; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@ ; \
+ fi
+ @-$(CMP) $(srcdir)/strftlng.ok _$@ && rm -f _$@
+
+nors::
+ @echo $@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - $(srcdir)/nors.in > _$@
+ @-$(CMP) $(srcdir)/nors.ok _$@ && rm -f _$@
+
+reint::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
+ @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+
+pipeio1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @rm -f test1 test2
+ @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+
+pipeio2::
+ @echo $@
+ @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
+ @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+
+clobber::
+ @echo $@
+ @$(AWK) -f $(srcdir)/clobber.awk >_$@
+ @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @rm -f seq
+
+arynocls::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -v INPUT=$(srcdir)/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) $(srcdir)/arynocls.ok _$@ && rm -f _$@
+
+getlnbuf::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -f getlnbuf.awk $(srcdir)/getlnbuf.in > _$@
+ @-AWKPATH=$(srcdir) $(AWK) -f gtlnbufv.awk $(srcdir)/getlnbuf.in > _2$@
+ @-$(CMP) $(srcdir)/getlnbuf.ok _$@ && $(CMP) $(srcdir)/getlnbuf.ok _2$@ && rm -f _$@ _2$@
+
+inetmesg::
+ @echo These tests only work if your system supports the services
+ @echo "'discard'" at port 9 and "'daytimed'" at port 13. Check your
+ @echo file /etc/services and do "'netstat -a'".
+
+inetechu::
+ @echo This test is for establishing UDP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/udp/0/127.0.0.1/9"}'
+
+inetecht::
+ @echo This test is for establishing TCP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
+
+inetdayu::
+ @echo This test is for bidirectional UDP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/udp/0/127.0.0.1/13"; \
+ "/inet/udp/0/127.0.0.1/13" |& getline; print $0}'
+
+inetdayt::
+ @echo This test is for bidirectional TCP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13"; \
+ "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}'
+
+redfilnm::
+ @echo $@
+ @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
+ @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+
+leaddig::
+ @echo $@
+ @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
+ @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+
+gsubtst3::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+space::
+ @echo $@
+ @echo Expect space to fail with DJGPP.
+ @$(AWK) -f ' ' $(srcdir)/space.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf0::
+ @echo $@
+ @$(AWK) --posix -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig::
+ @echo $@
+ @ : Suppose that block size for pipe is at most 128kB:
+ @$(AWK) 'BEGIN { for (i = 1; i <= 128*64+1; i++) print "abcdefgh123456\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" }; { print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END{ print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig2::
+ @echo $@
+ @$(AWK) 'BEGIN { ORS = ""; n = "\n"; for (i = 1; i <= 10; i++) n = (n n); \
+ for (i = 1; i <= 128; i++) print n; print "abc\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" };{ print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END { print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+whiny::
+ @echo $@
+ @WHINY_USERS=1 $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcas2::
+ @echo $@
+ @GAWKLOCALE=en_US ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subamp::
+ @echo $@
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# This test makes sure gawk exits with a zero code.
+# Thus, unconditionally generate the exit code.
+exitval1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/exitval1.awk >_$@ 2>&1; echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsspcoln::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk 'FS=[ :]+' $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart3::
+ @echo $@
+ @head $(srcdir)/rsstart1.in | $(AWK) -f $(srcdir)/rsstart2.awk >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+Gt-dummy:
+# file Maketests, generated from Makefile.am by the Gentests program
+addcomma:
+ @echo addcomma
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+anchgsub:
+ @echo anchgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayparm:
+ @echo arrayparm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayref:
+ @echo arrayref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrymem1:
+ @echo arrymem1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm2:
+ @echo arrayprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm3:
+ @echo arrayprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref2:
+ @echo arryref2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref3:
+ @echo arryref3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref4:
+ @echo arryref4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref5:
+ @echo arryref5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arynasty:
+ @echo arynasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm1:
+ @echo aryprm1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm2:
+ @echo aryprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm3:
+ @echo aryprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm4:
+ @echo aryprm4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm5:
+ @echo aryprm5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm6:
+ @echo aryprm6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm7:
+ @echo aryprm7
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm8:
+ @echo aryprm8
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arysubnm:
+ @echo arysubnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asgext:
+ @echo asgext
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+back89:
+ @echo back89
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backgsub:
+ @echo backgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+childin:
+ @echo childin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clsflnam:
+ @echo clsflnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare2:
+ @echo compare2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat1:
+ @echo concat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat2:
+ @echo concat2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat3:
+ @echo concat3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+convfmt:
+ @echo convfmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+datanonl:
+ @echo datanonl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+defref:
+ @echo defref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarprm:
+ @echo delarprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarpm2:
+ @echo delarpm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delfunc:
+ @echo delfunc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+dynlj:
+ @echo dynlj
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+eofsplit:
+ @echo eofsplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+exitval2:
+ @echo exitval2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchg:
+ @echo fldchg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchgnf:
+ @echo fldchgnf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fmttest:
+ @echo fmttest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnamedat:
+ @echo fnamedat
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray:
+ @echo fnarray
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray2:
+ @echo fnarray2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarydel:
+ @echo fnarydel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnaryscl:
+ @echo fnaryscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnasgnm:
+ @echo fnasgnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnmisc:
+ @echo fnmisc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnparydl:
+ @echo fnparydl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fordel:
+ @echo fordel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+forsimp:
+ @echo forsimp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsbs:
+ @echo fsbs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsrs:
+ @echo fsrs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fstabplus:
+ @echo fstabplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsemnl:
+ @echo funsemnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsmnam:
+ @echo funsmnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funstack:
+ @echo funstack
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline:
+ @echo getline
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline3:
+ @echo getline3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tb:
+ @echo getnr2tb
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tm:
+ @echo getnr2tm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubasgn:
+ @echo gsubasgn
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtest:
+ @echo gsubtest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst2:
+ @echo gsubtst2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst4:
+ @echo gsubtst4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst5:
+ @echo gsubtst5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hex:
+ @echo hex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hsprint:
+ @echo hsprint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+inputred:
+ @echo inputred
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intest:
+ @echo intest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intprec:
+ @echo intprec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+iobug1:
+ @echo iobug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+leadnl:
+ @echo leadnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longsub:
+ @echo longsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longwrds:
+ @echo longwrds
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+manglprm:
+ @echo manglprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+math:
+ @echo math
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+membug1:
+ @echo membug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+minusstr:
+ @echo minusstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty:
+ @echo nasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty2:
+ @echo nasty2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+negexp:
+ @echo negexp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nested:
+ @echo nested
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfldstr:
+ @echo nfldstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfneg:
+ @echo nfneg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfset:
+ @echo nfset
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlfldsep:
+ @echo nlfldsep
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlinstr:
+ @echo nlinstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlstrina:
+ @echo nlstrina
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noeffect:
+ @echo noeffect
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nofmtch:
+ @echo nofmtch
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop1:
+ @echo noloop1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop2:
+ @echo noloop2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noparms:
+ @echo noparms
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nulrsend:
+ @echo nulrsend
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numindex:
+ @echo numindex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numsubstr:
+ @echo numsubstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+octsub:
+ @echo octsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmt:
+ @echo ofmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtbig:
+ @echo ofmtbig
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtfidl:
+ @echo ofmtfidl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmts:
+ @echo ofmts
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+onlynl:
+ @echo onlynl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnidx:
+ @echo opasnidx
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnslf:
+ @echo opasnslf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramdup:
+ @echo paramdup
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramtyp:
+ @echo paramtyp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+parseme:
+ @echo parseme
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+pcntplus:
+ @echo pcntplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prdupval:
+ @echo prdupval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prec:
+ @echo prec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf1:
+ @echo printf1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmarscl:
+ @echo prmarscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmreuse:
+ @echo prmreuse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prt1eval:
+ @echo prt1eval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prtoeval:
+ @echo prtoeval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+psx96sub:
+ @echo psx96sub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rand:
+ @echo rand
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b1:
+ @echo rebt8b1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b2:
+ @echo rebt8b2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regeq:
+ @echo regeq
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reindops:
+ @echo reindops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reparse:
+ @echo reparse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+resplit:
+ @echo resplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rs:
+ @echo rs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnul1nl:
+ @echo rsnul1nl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest1:
+ @echo rstest1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest2:
+ @echo rstest2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest3:
+ @echo rstest3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest4:
+ @echo rstest4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest5:
+ @echo rstest5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rswhite:
+ @echo rswhite
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+scalar:
+ @echo scalar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclforin:
+ @echo sclforin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclifin:
+ @echo sclifin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sortempty:
+ @echo sortempty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitargv:
+ @echo splitargv
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitarr:
+ @echo splitarr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitdef:
+ @echo splitdef
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitvar:
+ @echo splitvar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitwht:
+ @echo splitwht
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sprintfc:
+ @echo sprintfc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strcat1:
+ @echo strcat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtod:
+ @echo strtod
+ @echo Expect strtod to fail with DJGPP.
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subsepnm:
+ @echo subsepnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subslash:
+ @echo subslash
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+substr:
+ @echo substr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+swaplns:
+ @echo swaplns
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+synerr1:
+ @echo synerr1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit2:
+ @echo uninit2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit3:
+ @echo uninit3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit4:
+ @echo uninit4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninitialized:
+ @echo uninitialized
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+unterm:
+ @echo unterm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+wjposer1:
+ @echo wjposer1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroe0:
+ @echo zeroe0
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroflag:
+ @echo zeroflag
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getlnhd:
+ @echo getlnhd
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asort:
+ @echo asort
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asorti:
+ @echo asorti
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backw:
+ @echo backw
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo clos1way
+ @echo Expect clos1way to fail with DJGPP.
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fieldwdth:
+ @echo fieldwdth
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsfwfs:
+ @echo fsfwfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub:
+ @echo gensub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub2:
+ @echo gensub2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops2:
+ @echo gnuops2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops3:
+ @echo gnuops3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnureops:
+ @echo gnureops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasefs:
+ @echo icasefs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasers:
+ @echo icasers
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncdym:
+ @echo igncdym
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncfs:
+ @echo igncfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcase:
+ @echo ignrcase
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+lint:
+ @echo lint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match1:
+ @echo match1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match2:
+ @echo match2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nondec:
+ @echo nondec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+posix:
+ @echo posix
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+procinfs:
+ @echo procinfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printfbad1:
+ @echo printfbad1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regx8bit:
+ @echo regx8bit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebuf:
+ @echo rebuf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest6:
+ @echo rstest6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+shadow:
+ @echo shadow
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sort1:
+ @echo sort1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtonum:
+ @echo strtonum
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# end of file Maketests
+
+# Targets generated for other tests:
+
+$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
+ $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" *.awk *.in > $(srcdir)/Maketests
+
+clean:
+ rm -fr _* core core.* junk out1 out2 out3 strftime.ok test1 test2 seq *~
+
+# An attempt to print something that can be grepped for in build logs
+pass-fail:
+ @COUNT=`ls _* 2>/dev/null | wc -l` ; \
+ if test $$COUNT = 0 ; \
+ then echo ALL TESTS PASSED ; \
+ else echo $$COUNT TESTS FAILED ; \
+ fi
+
+# This target for my convenience to look at all the results
+diffout:
+ for i in _* ; \
+ do \
+ echo ============== $$i ============= ; \
+ diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ done | more
+
+# This target is for testing with electric fence.
+efence:
+ for i in $$(ls _* | sed 's;_\(.*\);\1;') ; \
+ do \
+ bad=$$(wc -l < _$$i) \
+ ok=$$(wc -l < $$i.ok) ; \
+ if (( $$bad == $$ok + 2 )) ; \
+ then \
+ rm _$$i ; \
+ fi ; \
+ done
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+#! /bin/sh
+
+# igawk --- like gawk but do @include processing
+# Arnold Robbins, arnold@gnu.ai.mit.edu, Public Domain
+# July 1993
+
+igs=${TMP:-/tmp}/igs$$
+ige=${TMP:-/tmp}/ige$$
+
+if [ "$1" = debug ]
+then
+ set -x
+ shift
+else
+ # cleanup on exit, hangup, interrupt, quit, termination
+ #trap 'rm -f $igs $ige' 0 1 2 3 15
+ trap 'rm -f $igs $ige' 0 2 15
+fi
+
+while [ $# -ne 0 ] # loop over arguments
+do
+ case $1 in
+ --) shift; break;;
+
+ -W) shift
+ set -- -W"$@"
+ continue;;
+
+ -[vF]) opts="$opts $1 '$2'"
+ shift;;
+
+ -[vF]*) opts="$opts '$1'" ;;
+
+ -f) echo @include "$2" >> $igs
+ shift;;
+
+ -f*) f=`echo "$1" | sed 's/-f//'`
+ echo @include "$f" >> $igs ;;
+
+ -?file=*) # -Wfile or --file
+ f=`echo "$1" | sed 's/-.file=//'`
+ echo @include "$f" >> $igs ;;
+
+ -?file) # get arg, $2
+ echo @include "$2" >> $igs
+ shift;;
+
+ -?source=*) # -Wsource or --source
+ t=`echo "$1" | sed 's/-.source=//'`
+ echo "$t" >> $igs ;;
+
+ -?source) # get arg, $2
+ echo "$2" >> $igs
+ shift;;
+
+ -?version)
+ echo igawk: version 1.0 1>&2
+ gawk --version
+ exit 0 ;;
+
+ -[W-]*) opts="$opts '$1'" ;;
+
+ *) break;;
+ esac
+
+ shift
+done
+
+if [ ! -s $igs ]
+then
+ if [ -z "$1" ]
+ then
+ echo igawk: no program! 1>&2
+ exit 1
+ else
+ echo "$1" > $igs
+ shift
+ fi
+fi
+
+# at this point, $igs has the program
+gawk -f igawk.awk $igs > $ige
+eval gawk -f '$ige' $opts -- "$@"
+
+exit $?
--- /dev/null
+# igawk.awk
+# process @include directives
+
+function pathto(file, i, t, junk)
+{
+ if (index(file, "/") != 0)
+ return file
+
+ for (i = 1; i <= ndirs; i++) {
+ t = (pathlist[i] "/" file)
+ if ((getline junk < t) > 0) {
+ # found it
+ close(t)
+ return t
+ }
+ }
+ return ""
+}
+BEGIN {
+ path = ENVIRON["AWKPATH"]
+ ndirs = split(path, pathlist, ";")
+ for (i = 1; i <= ndirs; i++) {
+ if (pathlist[i] == "")
+ pathlist[i] = "."
+ }
+ stackptr = 0
+ input[stackptr] = ARGV[1] # ARGV[1] is first file
+
+ for (; stackptr >= 0; stackptr--) {
+ while ((getline < input[stackptr]) > 0) {
+ if (tolower($1) != "@include") {
+ print
+ continue
+ }
+ fpath = pathto($2)
+ if (fpath == "") {
+ printf("igawk:%s:%d: cannot find %s\n",
+ input[stackptr], FNR, $2) > "/dev/stderr"
+ continue
+ }
+ if (! (fpath in processed)) {
+ processed[fpath] = input[stackptr]
+ input[++stackptr] = fpath # push onto stack
+ } else
+ print $2, "included in", input[stackptr],
+ "already included in",
+ processed[fpath] > "/dev/stderr"
+ }
+ close(input[stackptr])
+ }
+}
--- /dev/null
+@sh igawk %1 %2 %3 %4 %5 %6 %7 %8 %9
\ No newline at end of file
--- /dev/null
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+/*
+ * acconfig.h -- configuration definitions for gawk.
+ */
+
+/*
+ * Copyright (C) 1995-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define if type char is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+/* #undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to the type of elements in the array set by `getgroups'.
+ Usually this is either `int' or `gid_t'. */
+#define GETGROUPS_T gid_t
+
+/* Define if the `getpgrp' function takes no argument. */
+#define GETPGRP_VOID 1
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have a working `mmap' system call. */
+/* #undef HAVE_MMAP */
+
+/* Define if your struct stat has st_blksize. */
+#define HAVE_ST_BLKSIZE 1
+
+/* Define if you have the ANSI # stringizing operator in cpp. */
+#define HAVE_STRINGIZE 1
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define if your struct tm has tm_zone. */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+ tzname. */
+#define HAVE_TZNAME 1
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define as __inline if that's what the C compiler calls it. */
+#if defined (_MSC_VER)
+#define inline
+#endif
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+#define REGEX_MALLOC 1 /* use malloc instead of alloca in regex.c */
+#define SPRINTF_RET int /* return type of sprintf */
+/* #undef HAVE_MKTIME */ /* we have the mktime function */
+/* #undef HAVE_SOCKETS */ /* we have sockets on this system */
+/* #undef HAVE_PORTALS */ /* we have portals on /p on this system */
+/* #undef DYNAMIC */ /* allow dynamic addition of builtins */
+/* #undef STRTOD_NOT_C89 */ /* strtod doesn't have C89 semantics */
+
+/* Define if you have the __argz_count function. */
+#define HAVE___ARGZ_COUNT 1
+
+/* Define if you have the __argz_next function. */
+#define HAVE___ARGZ_NEXT 1
+
+/* Define if you have the __argz_stringify function. */
+#define HAVE___ARGZ_STRINGIFY 1
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the dcgettext function. */
+/* #undef HAVE_DCGETTEXT */
+
+/* Define if you have the fmod function. */
+#define HAVE_FMOD 1
+
+/* Define if you have the getcwd function. */
+/* #undef HAVE_GETCWD */
+
+/* Define if you have the getpagesize function. */
+/* #undef HAVE_GETPAGESIZE */
+
+/* Define if you have the memcmp function. */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memset function. */
+#define HAVE_MEMSET 1
+
+/* Define if you have the munmap function. */
+/* #undef HAVE_MUNMAP */
+
+/* Define if you have the putenv function. */
+/* #undef HAVE_PUTENV */
+
+/* Define if you have the setenv function. */
+/* #define HAVE_SETENV */
+
+/* Define if you have the setlocale function. */
+/* #undef HAVE_SETLOCALE */
+
+/* Define if you have the stpcpy function. */
+/* #undef HAVE_STPCPY */
+
+/* Define if you have the strcasecmp function. */
+/* #undef HAVE_STRCASECMP */
+
+/* Define if you have the strchr function. */
+#define HAVE_STRCHR 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define if you have the strtod function. */
+#define HAVE_STRTOD 1
+
+/* Define if you have the system function. */
+#define HAVE_SYSTEM 1
+
+/* Define if you have the tzset function. */
+#define HAVE_TZSET 1
+
+/* Define if you have the <argz.h> header file. */
+/* #undef HAVE_ARGZ_H */
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <libintl.h> header file. */
+/* #undef HAVE_LIBINTL_H */
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <locale.h> header file. */
+/* #undef HAVE_LOCALE_H */
+
+/* Define if you have the <malloc.h> header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <netdb.h> header file. */
+/* #undef HAVE_NETDB_H */
+
+/* Define if you have the <netinet/in.h> header file. */
+/* #undef HAVE_NETINET_IN_H */
+
+/* Define if you have the <nl_types.h> header file. */
+/* #undef HAVE_NL_TYPES_H */
+
+/* Define if you have the <signum.h> header file. */
+/* #undef HAVE_SIGNUM_H */
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+/* #undef HAVE_STDLIB_H */
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define if you have the <sys/time.h> header file. */
+#if defined(DJGPP)
+# define HAVE_SYS_TIME_H 1
+#endif
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#if defined(DJGPP)
+# define HAVE_UNISTD_H 1
+#endif
+
+/* Define if you have the i library (-li). */
+/* #undef HAVE_LIBI */
+
+/* Define if you have the intl library (-lintl). */
+/* #undef HAVE_LIBINTL */
+
+/* Define if you have the m library (-lm). */
+#define HAVE_LIBM 1
+
+/* Name of package */
+#define PACKAGE "gawk"
+
+/* Version number of package */
+#define VERSION "3.0.89"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to make ftello visible on some hosts (e.g. HP-UX 10.20). */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to make ftello visible on some hosts (e.g. glibc 2.1.3). */
+/* #undef _XOPEN_SOURCE */
+
+/* Define if compiler has function prototypes */
+#define PROTOTYPES 1
+
+/* Define to 1 if you have the stpcpy function. */
+/* #undef HAVE_STPCPY */
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+/* #undef HAVE_LC_MESSAGES */
+
+/* Define to 1 if NLS is requested. */
+/* #undef ENABLE_NLS */
+
+/* Define to 1 if you have gettext and don't want to use GNU gettext. */
+/* #undef HAVE_GETTEXT */
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+/* #undef HAVE_CATGETS */
+
+/* The size of `unsigned int' & `unsigned long', as computed by sizeof. */
+#if defined(DJGPP) || defined(_MSC_VER)
+# include <limits.h>
+#endif
+
+#if UINT_MAX == 65536
+# define SIZEOF_UNSIGNED_INT 2
+#endif
+
+#if UINT_MAX == 4294967295U
+# define SIZEOF_UNSIGNED_INT 4
+#endif
+
+#if ULONG_MAX == 4294967295UL
+# define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+/* Library search path */
+#define DEFPATH ".;c:/lib/awk;c:/gnu/lib/awk"
+
+#if defined (_MSC_VER)
+#if !defined(__STDC__)
+# define __STDC__ 1
+#endif
+#undef HAVE_UNISTD_H
+#undef HAVE_SYS_PARAM_H
+#undef HAVE_RANDOM
+/* msc strftime is incomplete, use supplied version */
+#undef HAVE_STRFTIME
+/* #define HAVE_TM_ZONE */
+#define altzone timezone
+#endif
+
+# define HAVE_POPEN_H
+
+#if defined(_MSC_VER) && defined(MSDOS)
+#define system(s) os_system(s)
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define ssize_t long int /* DJGPP has ssize_t */
+#define intmax_t long
+#define uintmax_t unsigned long
+#endif
+
+#if defined (_MSC_VER) || defined(__EMX__)
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+
+#if defined(DJGPP)
+# define HAVE_LIMITS_H 1
+# undef HAVE_POPEN_H
+#define intmax_t long long
+#define uintmax_t unsigned long long
+#endif
+
+#if defined(__WIN32__) && defined(__CRTRSXNT__)
+#include <crtrsxnt.h>
+#endif
+
+/* For vcWin32 */
+#if defined(WIN32) && defined(_MSC_VER)
+#define alloca _alloca
+#define system(s) os_system(s)
+#endif
+
+#if defined(__MINGW32__)
+#undef HAVE_SYS_PARAM_H
+#endif
+
+
+/* #define NO_LINT 1 */
--- /dev/null
+/*\r
+** dlfcn.c -- limited implementation of posix dynamic loading functions\r
+*/\r
+\r
+/*\r
+ * Copyright (C) 2003 the Free Software Foundation, Inc.\r
+ * \r
+ * This file is part of GAWK, the GNU implementation of the\r
+ * AWK Programming Language.\r
+ * \r
+ * GAWK is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * GAWK is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+\r
+#include <dlfcn.h>\r
+#include <errno.h>\r
+#include <windows.h>\r
+\r
+/* open the library file. We currently ignore flags. */\r
+void *dlopen(const char * libname, int flags)\r
+{\r
+ HMODULE libH;\r
+\r
+\r
+ /* if libname is specified, we need to load a library of that name */\r
+ if (libname) {\r
+ libH = LoadLibrary(libname);\r
+ }\r
+\r
+ /* otherwise, we're supposed to return a handle to global symbol\r
+ * information, which includes the executable and all libraries loaded\r
+ * with RTLD_GLOBAL. For our purposes, it doesn't really matter, so\r
+ * we simply return the handle to the .exe */\r
+ else {\r
+ libH = GetModuleHandle(NULL);\r
+ }\r
+\r
+ return (void *)libH;\r
+}\r
+\r
+\r
+/* don't need the library any more */\r
+int dlclose(void * libH)\r
+{\r
+ int rc;\r
+\r
+ if (FreeLibrary((HMODULE)libH)) {\r
+ rc = 0;\r
+ }\r
+ else {\r
+ rc = -1;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/* find the symbol */\r
+void *dlsym(void * /*restrict*/ libH, const char * /*restrict*/ fnName)\r
+{\r
+ return (void *)GetProcAddress((HMODULE)libH, fnName);\r
+}\r
+\r
+char *dlerror(void)\r
+{\r
+ static char errbuf[1024];\r
+\r
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),\r
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errbuf, sizeof(errbuf), NULL);\r
+\r
+ return errbuf;\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+** dlfcn.h -- limited implementation of posix dynamic loading functions\r
+*/\r
+\r
+/*\r
+ * Copyright (C) 2003 the Free Software Foundation, Inc.\r
+ * \r
+ * This file is part of GAWK, the GNU implementation of the\r
+ * AWK Programming Language.\r
+ * \r
+ * GAWK is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * GAWK is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+\r
+#ifndef _DLFCN_H\r
+#define _DLFCN_H\r
+\r
+/* symbols required by susv3. These are not supported here (everything is\r
+ * RTLD_NOW, RTLD_GLOBAL) */\r
+#define RTLD_LAZY 0\r
+#define RTLD_NOW 1\r
+#define RTLD_GLOBAL 0\r
+#define RTLD_LOCAL 2\r
+\r
+int dlclose(void *);\r
+char *dlerror(void);\r
+void *dlopen(const char *, int);\r
+void *dlsym(void * /*restrict*/, const char * /*restrict*/);\r
+\r
+#endif\r
--- /dev/null
+NAME gawk WINDOWCOMPAT NEWFILES\r
+DESCRIPTION 'GNU awk for OS/2'\r
--- /dev/null
+/*
+ * gawkmisc.c --- miscellaneous gawk routines that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991 - 2003 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Progamming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+char quote = '\'';
+char envsep = ';';
+
+# ifdef DEFPATH
+char *defpath = DEFPATH;
+# else
+char *defpath = ".;c:\\lib\\awk;c:\\gnu\\lib\\awk";
+# endif
+
+#ifdef __EMX__
+#include<io.h>
+
+static int _os2_is_abs_path(const char *dirname);
+static char* _os2_unixroot(const char *path);
+static const char* _os2_unixroot_path(const char *path);
+#endif
+
+/* gawk_name --- pull out the "gawk" part from how the OS called us */
+
+char *
+gawk_name(filespec)
+const char *filespec;
+{
+ char *p, *q;
+
+ p = (char *) filespec; /* Sloppy... */
+
+ /* OS/2 allows / for directory separator too */
+ if ((q = strrchr(p, '\\')) != NULL)
+ p = q + 1;
+ if ((q = strrchr(p, '/')) != NULL
+ && (p == NULL || q > p)) /* support mixed d:\foo/bar\gawk.exe */
+ p = q + 1;
+ if ((q = strchr(p, '.')) != NULL)
+ *q = '\0';
+ return strlwr(p);
+}
+
+
+/*
+ * memcpy_long() & memset_ulong() are 32-bit replacements for MSC which
+ * has a 16-bit size_t.
+ */
+char *
+memcpy_ulong (dest, src, l)
+register char *dest;
+register const char *src;
+register unsigned long l;
+{
+ register char *ret = dest;
+
+ while (l--)
+ *dest++ = *src++;
+
+ return ret;
+}
+
+
+void *
+memset_ulong(dest, val, l)
+void *dest;
+register int val;
+register unsigned long l;
+{
+ register char *ret = dest;
+ register char *d = dest;
+
+ while (l--)
+ *d++ = val;
+
+ return ((void *) ret);
+}
+
+
+/* os_arg_fixup --- fixup the command line */
+
+void
+os_arg_fixup(argcp, argvp)
+int *argcp;
+char ***argvp;
+{
+#ifdef __EMX__
+# ifdef initialize_main
+ initialize_main(argcp, argvp);
+# else
+ _wildcard(argcp, argvp);
+ _response(argcp, argvp);
+# endif
+
+ setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+ defpath = (char*) _os2_unixroot_path(defpath);
+#endif /* __EMX__ */
+ return;
+}
+
+/* os_devopen --- open special per-OS devices */
+
+int
+os_devopen(name, flag)
+const char *name;
+int flag;
+{
+#ifdef __EMX__
+ /* do not use open(name, flag) here !!! */
+ return -1;
+#else
+ if (strcmp(name, "/dev/null") == 0)
+ return open("NUL", flag);
+ /* FIXME: */
+ /* else if (strcmp(name, "/dev/tty") == 0)
+ * return open("???", flag);
+ */
+ return -1;
+#endif
+}
+
+/* optimal_bufsize --- determine optimal buffer size */
+
+size_t
+optimal_bufsize(fd, stb)
+int fd;
+struct stat *stb;
+{
+ /* force all members to zero in case OS doesn't use all of them. */
+ memset(stb, '\0', sizeof(struct stat));
+
+ /*
+ * DOS doesn't have the file system block size in the
+ * stat structure. So we have to make some sort of reasonable
+ * guess. We use stdio's BUFSIZ, since that is what it was
+ * meant for in the first place.
+ */
+#define DEFBLKSIZE BUFSIZ
+
+ if (fstat(fd, stb) == -1)
+ fatal("can't stat fd %d (%s)", fd, strerror(errno));
+ if (S_ISREG(stb->st_mode)
+ && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
+ return stb->st_size;
+ return DEFBLKSIZE;
+}
+
+/* ispath --- return true if path has directory components */
+
+int
+ispath(file)
+const char *file;
+{
+#ifdef __EMX__
+ return (strpbrk(file, "/\\") != NULL ||
+ (toupper(file[0]) >= 'A' && toupper(file[0]) <= 'Z' && file[1] == ':'));
+#else
+ for (; *file; file++) {
+ switch (*file) {
+ case '/':
+ case '\\':
+ case ':':
+ return 1;
+ }
+ }
+ return 0;
+#endif
+}
+
+/* isdirpunct --- return true if char is a directory separator */
+
+int
+isdirpunct(c)
+int c;
+{
+ return (strchr(":\\/", c) != NULL);
+}
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+const char *name, *what, *dir;
+{
+#if ! defined(_MSC_VER) && ! defined(__MINGW32__)
+# if (defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 4)) || defined __EMX__
+ if (fd <= 2) /* sanity */
+ return;
+
+ if (fcntl(fd, F_SETFD, 1) < 0)
+ warning("%s %s `%s': could not set close-on-exec: %s",
+ what, dir, name, strerror(errno));
+# endif
+#endif
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+#if ! defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+int
+os_isdir(fd)
+int fd;
+{
+ struct stat sbuf;
+
+ return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
+}
+
+/* os_is_setuid --- true if running setuid root */
+
+int
+os_is_setuid()
+{
+#ifdef __EMX__
+ long uid, euid;
+
+ uid = getuid();
+ euid = geteuid();
+
+ return (euid == 0 && euid != uid);
+#else
+ return 0;
+#endif
+}
+
+/* os_setbinmode --- set binary mode on file */
+
+#ifdef __DJGPP__
+#include <sys/exceptn.h>
+#endif
+static int orig_tty_mode = -1;
+
+int
+os_setbinmode(fd, mode)
+int fd, mode;
+{
+ int prev_mode = setmode(fd, mode);
+
+#ifdef __DJGPP__
+ if ((mode & O_BINARY) != 0)
+ __djgpp_set_ctrl_c(1); /* allow to interrupt with Ctrl-C */
+#endif
+ /* Save the original tty mode as we found it. */
+ if (orig_tty_mode == -1 && fd >= 0 && fd <= 2)
+ orig_tty_mode = prev_mode;
+ return prev_mode;
+}
+
+/* os_restore_mode --- restore the original mode of the console device */
+
+void
+os_restore_mode (fd)
+int fd;
+{
+ if (orig_tty_mode != -1) {
+ setmode(fd, orig_tty_mode);
+ }
+}
+
+
+#ifdef __EMX__
+# ifndef PATH_SEPARATOR
+# define PATH_SEPARATOR ';'
+# endif
+
+/* result is 0 if dirname is no absolute path, 1 otherwise */
+
+static int
+_os2_is_abs_path(const char *dirname)
+{
+ int result = 0;
+ if (dirname != NULL && dirname[0] != '\0') {
+ /* if dirname contains a valid drive letter like "c:" */
+ if (((dirname[0] >= 'A' && dirname[0] <= 'Z') || (dirname[0] >= 'a' && dirname[0] <= 'z'))
+ && dirname[1] == ':') dirname += 2; /* remove the drive letter */
+
+ if (dirname[0] == '/' || dirname[0] == '\\') result = 1; /* asbolute path */
+ }
+
+ return result;
+}
+
+
+/* path is assumed to be a list of directories separated by PATH_SEPARATOR.
+ This function determines if the first directory of path is on the
+ drive specified by the environment variable UNIXROOT.
+ If it is the case, NULL is returned, otherwise a new directory name
+ is allocated using the drive letter from UNIXROOT and returned as result.
+ If the first directory is a relative path NULL is returned, too.
+ The new directory name is allocated by malloc().
+ Example (UNIXROOT is set to "e:"):
+ "c:/usr/share" -> "e:/usr/share"
+ "e:/usr/share" -> NULL (already on the $UNIXROOT drive)
+ "/usr/share" -> "e:/usr/share"
+ "." -> NULL (not an absolute path)
+ "usr/share" -> NULL (not an absolute path)
+ "c:usr/share" -> NULL (not an absolute path)
+ "c:/usr/share;d:/etc" -> "e:/usr/share" (only the first directory in path is used) */
+
+static char*
+_os2_unixroot(const char *path)
+{
+ static const char *unixroot = NULL;
+ static int unixroot_init = 0;
+ char *result = NULL;
+
+ if (unixroot_init == 0) {
+ /* get $UNIXROOT only one time */
+ unixroot = getenv("UNIXROOT");
+
+ /* check whether unixroot is valid (must be "x:") */
+ if (unixroot != NULL) {
+ int drive = toupper(unixroot[0]);
+ if (drive < 'A' || drive > 'Z' || unixroot[1] != ':' || unixroot[2] != '\0')
+ unixroot = NULL; /* unixroot not valid */
+ }
+
+ unixroot_init = 1; /* initialized */
+ }
+
+ /* note: if unixroot != NULL then it contains a valid drive letter */
+ if (unixroot != NULL && _os2_is_abs_path(path)) {
+ /* dirname is an absolute path and unixroot is a drive letter, "c:" for example */
+ size_t old_path_len = strlen(path);
+
+ /* end points to the first ';' in path or to NULL */
+ const char *end = strchr(path, PATH_SEPARATOR);
+
+ /* dir_len is the length of the first directory in path */
+ size_t dir_len = (end) ? end - path : old_path_len;
+
+ if (toupper(unixroot[0]) != toupper(path[0]) || path[1] != ':') {
+ /* the first directory of path does not start with the string $UNIXROOT */
+ if (path[1] == ':') {
+ /* if there is a drive letter remove it */
+ dir_len -= 2;
+ path += 2;
+ }
+
+ result = malloc(dir_len + 3);
+ if (result) { /* do nothing if we are out of memory */
+ result[0] = unixroot[0];
+ result[1] = unixroot[1];
+ memcpy(result + 2, path, dir_len);
+ result[dir_len + 2] = '\0';
+ }
+ }
+ }
+ return result;
+}
+
+/* path is assumed to be a list of directories separated by PATH_SEPARATOR.
+ Every directory is processed. _os2_unixroot() is used to find out whether
+ these directories are on the drive specified by the environment variable
+ UNIXROOT. If this is not the case the same directory on the UNIXROOT drive
+ is added to the end of path. If path is a valid path this function returns a valid path, too.
+ Example ($UNIXROOT is set to "e:"):
+ ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc"
+ -> ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc;e:/usr/local;e:/usr/local;e:/etc" */
+
+static const char*
+_os2_unixroot_path(const char *path)
+{
+ char *result = NULL;
+ const char *p = path;
+ unsigned dir_count = 1;
+
+ if (path == NULL || path[0] == '\0') return NULL; /* empty path */
+
+ /* save number of path components in dir_count */
+ while(*p) {
+ if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR)
+ dir_count += 1;
+ }
+
+ {
+ const char *list[dir_count]; /* list of char pointers */
+ size_t dir_len[dir_count]; /* the according directory length */
+ size_t old_path_len = strlen(path); /* the old path length */
+ size_t total_len;
+ unsigned i = 0;
+
+ if (path[old_path_len - 1] == PATH_SEPARATOR) /* last character is ';' */
+ old_path_len--;
+
+ list[0] = p = path; /* first directory */
+
+ while(*p) {
+ if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR)
+ list[++i] = p;
+ }
+ /* now list[i] contains the ith directory of path (no 0-terminated strings!!!) */
+
+ /* determine the total length for the new path */
+ total_len = old_path_len;
+
+ for(i = 0; i < dir_count; i++) {
+ list[i] = _os2_unixroot(list[i]);
+ if (list[i] != NULL) {
+ dir_len[i] = strlen(list[i]);
+ total_len += dir_len[i] + 1; /* one character for ';' or '\0' */
+ }
+ else dir_len[i] = 0;
+ }
+ /* now list[] contains the according directories on the UNIXROOT drive or NULL
+ total_len contains the total length for the new path */
+ result = malloc(total_len + 1);
+
+ if (result) {
+ /* copy the old path and the new directories into the new path */
+ char *q = result;
+ memcpy(q, path, old_path_len);
+ q += old_path_len;
+
+ for(i = 0; i < dir_count; i++) {
+ if (dir_len[i] != 0) {
+ *q++ = PATH_SEPARATOR;
+ memcpy(q, list[i], dir_len[i]);
+ q += dir_len[i];
+ }
+ }
+
+ *q = '\0'; /* terminating '\0' */
+ }
+
+ for(i = 0; i < dir_count; i++) free((void*) list[i]);
+ }
+
+ return (result) ? (const char*) result : path;
+}
+#endif /* __EMX__ */
--- /dev/null
+;; export definitions for Windows32 gawk\r
+;; this is to support extension libraries -- this should generate a gawk.lib\r
+;; against which they can link\r
+;; don't change the ordinals (the numbers after the function names)\r
+\r
+EXPORTS\r
+\r
+;; functions related directly to adding external functions\r
+get_argument @1\r
+set_value @2\r
+make_builtin @3\r
+get_curfunc_arg_count @4\r
+\r
+;; functions for manipulating data types\r
+mk_number @11\r
+tmp_string @12\r
+unref @13\r
+r_force_string @14\r
+r_force_number @15\r
+nodetype2str @16\r
+\r
+\r
+;; incidental other functions\r
+assoc_lookup @31\r
+assoc_clear @32\r
+r_dupnode @33\r
+set_loc @34\r
+update_ERRNO @35\r
+r_fatal @36\r
+get_actual @37\r
+\r
+;; data -- note that this must be redeclared with __declspec(dllimport) in the extension\r
+;; library since the exported symbol is actually a pointer to the data\r
+\r
+CONVFMTidx @101\r
+lintfunc @102\r
+do_lint @103\r
+stack_ptr @104\r
--- /dev/null
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#ifdef OS2
+# define INCL_DOSPROCESS
+# include <os2.h>
+# if _MSC_VER == 510
+# define DosGetPID DosGetPid
+# endif
+#else
+# include <process.h>
+#endif
+
+#ifdef OS2
+int getpid(void)
+{
+ PIDINFO PidInfo;
+
+ DosGetPID(&PidInfo);
+ return(PidInfo.pid);
+}
+#endif
+
+unsigned int getuid (void)
+{
+ return (0); /* root! */
+}
+
+unsigned int geteuid (void)
+{
+ return (0);
+}
+
+unsigned int getgid (void)
+{
+ return (0);
+}
+
+unsigned int getegid (void)
+{
+ return (0);
+}
+
+#endif
+
+int getpgrp(void)
+{
+ return (0);
+}
+
+#if defined(_MSC_VER) || defined(__GO32__) || defined(__MINGW32__)
+int getppid(void)
+{
+#ifdef OS2
+ PIDINFO PidInfo;
+
+ DosGetPID(&PidInfo);
+ return(PidInfo.pidParent);
+#else
+ return(0);
+#endif
+}
+#endif
--- /dev/null
+#undef __STDC__\r
+#include <fcntl.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <process.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <stdio.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <stdlib.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <string.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <sys/stat.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <sys/types.h>\r
+#define __STDC__ 1\r
--- /dev/null
+#undef __STDC__\r
+#include <time.h>\r
+#define __STDC__ 1\r
--- /dev/null
+# install.awk
+# awk script to handle "make install". Goal is to eliminate need for
+# extra utilities (such as sh, mkdir, and cp). This is a hack.
+
+function mkinstalldirs(dir, i, ii, j, jj, s, comp, mkdir)
+{
+ gsub("/", "\\", dir); ii = split(dir, s, " ")
+ print "@echo off" > install_bat
+ print "@echo off" > install_cmd
+ for (i = 1; i <= ii; i++) {
+ jj = split(s[i], comp, "\\"); dir = comp[1];
+ for (j = 1; j <= jj; dir=dir "\\" comp[++j]) {
+ if (substr(dir, length(dir)) == ":" || mkdir[dir]) continue;
+ printf("if not exist %s\\*.* mkdir %s\n", dir, dir) > install_bat
+ printf("if not exist %s\\* mkdir %s\n", dir, dir) > install_cmd
+ mkdir[dir] = 1
+ }
+ }
+ close(install_bat); close(install_cmd)
+ system(install)
+}
+
+function cp(s, j, n, comp)
+{
+ gsub("/", "\\", s); n = split(s, comp, " ");
+ print "@echo off" > install_bat
+ print "@echo off" > install_cmd
+ for (j = 1; j < n; j++) {
+ printf("copy %s %s\n", comp[j], comp[n]) > install_cmd
+ if (substr(comp[j], length(comp[j]), 1) == "*")
+ comp[j] = comp[j] ".*"
+ printf("copy %s %s\n", comp[j], comp[n]) > install_bat
+ }
+ close(install_bat); close(install_cmd)
+ system(install)
+}
+
+BEGIN{
+install = "installg"
+install_bat = install ".bat"; install_cmd = install ".cmd"
+igawk_cmd = prefix "/bin/igawk.cmd"
+igawk_bat = prefix "/bin/igawk.bat"
+igawk = "pc/awklib/igawk"
+
+# Make the bin directory
+mkinstalldirs(prefix "/bin");
+
+# Create igawk.cmd for OS/2
+printf("extproc sh %s/bin/igawk.cmd\nshift\n", prefix) > igawk_cmd
+while (getline < igawk) print $0 > igawk_cmd
+
+# Create igawk.bat for DOS
+printf("@sh %s/bin/igawk %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9", prefix) > igawk_bat
+
+# Do common
+cp(igawk " *awk.exe " prefix "/bin")
+mkinstalldirs(prefix "/lib/awk " prefix "/man/man1 " prefix "/info")
+cp("awklib/eg/lib/* pc/awklib/igawk.awk " prefix "/lib/awk");
+cp("doc/*.1 " prefix "/man/man1");
+cp("doc/gawk.info " prefix "/info");
+cp("doc/gawkinet.info " prefix "/info");
+}
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ #set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ set fnord `echo "$file" | sed 's/\([^:]\)\//\1 /g'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#include <string.h>
+#include <process.h>
+
+#ifdef OS2
+#ifdef _MSC_VER
+#define popen(c,m) _popen(c,m)
+#define pclose(f) _pclose(f)
+#endif
+#endif
+
+#if defined(WIN32) && defined(_MSC_VER)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#ifndef _NFILE
+#define _NFILE 40
+#endif
+
+static char template[] = "piXXXXXX";
+static struct {
+ char *command;
+ char *name;
+ char pmode[4];
+} pipes[_NFILE];
+
+
+/*
+ * For systems where system() and popen() do not follow SHELL:
+ * 1. Write command to temp file. Temp filename must have slashes
+ * compatible with SHELL (if set) or COMSPEC.
+ * 2. Convert slashes in SHELL (if present) to be compatible with COMSPEC.
+ * Currently, only MSC (running under DOS) and MINGW versions are managed.
+ */
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+static int
+unixshell(char *p)
+{
+ static char *shell[] = {"sh", "bash", "csh", "tcsh", "sh32", "sh16", "ksh", NULL};
+ char **shellp = shell, *s, *q;
+
+ if (p == NULL) return (0);
+ s = p = strdup(p);
+ if ((q = strrchr(p, '\\')) != NULL)
+ p = q + 1;
+ if ((q = strrchr(p, '/')) != NULL)
+ p = q + 1;
+ if ((q = strchr(p, '.')) != NULL)
+ *q = '\0';
+ strlwr(p);
+ do {
+ if (strcmp(*shellp, p) == 0) break;
+ } while (*++shellp);
+ free(s);
+ return(*shellp ? 1 : 0);
+}
+
+static char *
+slashify(char *p, char *s)
+{
+ if (unixshell(s))
+ while (s = strchr(p, '\\')) *s = '/';
+ else
+ while (s = strchr(p, '/')) *s = '\\';
+ return(p);
+}
+
+static char *
+scriptify(char *command)
+{
+ FILE *fp;
+ char *cmd, *name, *s, *p;
+ int i;
+
+ if((name = tempnam(".", "pip")) == NULL) return(NULL);
+ p = getenv("COMSPEC"); s = getenv("SHELL");
+ cmd = malloc(strlen(name) + (s ? strlen(s) : 0) + 9); *cmd = '\0';
+ if (s) {
+ slashify(strcpy(cmd, s), p);
+ p = s;
+ }
+ slashify(name, p);
+ if (! (i = unixshell(p))) {
+ char *p = (char *) realloc(name, strlen(name) + 5);
+ if (p == NULL)
+ return NULL;
+ name = p;
+ strcat(name, ".bat");
+ }
+ if (s) sprintf(cmd + strlen(cmd), " %cc ", unixshell(s) ? '-' : '/');
+ strcpy(p = cmd + strlen(cmd), name); free(name);
+
+ if ((fp = fopen(p, i ? "wb" : "w")) != NULL) {
+ if (! i) fputs("@echo off\n", fp);
+ i = strlen(command);
+ if ((fwrite(command, 1, i, fp) < i) || (fputc('\n', fp) == EOF))
+ cmd = NULL;
+ } else
+ cmd = NULL;
+ if (fp) fclose(fp);
+ return(cmd);
+}
+
+static void
+unlink_and_free(char *cmd)
+{
+ char *s;
+
+ if (s = strrchr(cmd, ' '))
+ s++;
+ else
+ s = cmd;
+ unlink(s); free(cmd);
+}
+
+int
+os_system(char *cmd)
+{
+ char *s;
+ int i;
+
+#if defined(OS2)
+ if (_osmode == OS2_MODE)
+ return(system(cmd));
+#endif
+
+ if ((cmd = scriptify(cmd)) == NULL) return(1);
+ if (s = getenv("SHELL"))
+ i = spawnlp(P_WAIT, s, s, cmd + strlen(s), NULL);
+ else
+ i = system(cmd);
+ unlink_and_free(cmd);
+ return(i);
+}
+#else
+#define os_system(cmd) system(cmd)
+#endif
+
+
+FILE *
+os_popen( char *command, char *mode )
+{
+ FILE *current;
+ char *name;
+ int cur;
+ char curmode[4];
+
+#if defined(OS2) && (_MSC_VER != 510)
+ if (_osmode == OS2_MODE)
+ return(popen(command, mode));
+#endif
+
+ if (*mode != 'r' && *mode != 'w')
+ return NULL;
+ strncpy(curmode, mode, 3); curmode[3] = '\0';
+
+#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
+ current = popen(command = scriptify(command), mode);
+ cur = fileno(current);
+ strcpy(pipes[cur].pmode, curmode);
+ pipes[cur].command = command;
+ return(current);
+#endif
+
+ /*
+ ** get a name to use.
+ */
+ if((name = tempnam(".","pip"))==NULL)
+ return NULL;
+ /*
+ ** If we're reading, just call system to get a file filled with
+ ** output.
+ */
+ if (*curmode == 'r') {
+ FILE *fp;
+ if ((cur = dup(fileno(stdout))) == -1)
+ return NULL;
+ *curmode = 'w';
+ if ((current = freopen(name, curmode, stdout)) == NULL)
+ return NULL;
+ os_system(command);
+ if (dup2(cur, fileno(stdout)) == -1)
+ return NULL;
+ close(cur);
+ *curmode = 'r';
+ if ((current = fopen(name, curmode)) == NULL)
+ return NULL;
+ } else {
+ if ((current = fopen(name, curmode)) == NULL)
+ return NULL;
+ }
+ cur = fileno(current);
+ pipes[cur].name = name;
+ strcpy(pipes[cur].pmode, curmode);
+ pipes[cur].command = strdup(command);
+ return current;
+}
+
+int
+os_pclose( FILE * current)
+{
+ int cur = fileno(current);
+ int fd, rval;
+
+#if defined(OS2) && (_MSC_VER != 510)
+ if (_osmode == OS2_MODE)
+ return(pclose(current));
+#endif
+
+#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
+ rval = pclose(current);
+ *pipes[cur].pmode = '\0';
+ unlink_and_free(pipes[cur].command);
+ return rval;
+#endif
+
+ /*
+ ** check for an open file.
+ */
+ switch (*pipes[cur].pmode) {
+ case 'r':
+ /*
+ ** input pipes are just files we're done with.
+ */
+ rval = fclose(current);
+ unlink(pipes[cur].name);
+ break;
+ case 'w':
+ /*
+ ** output pipes are temporary files we have
+ ** to cram down the throats of programs.
+ */
+ fclose(current);
+ rval = -1;
+ if ((fd = dup(fileno(stdin))) != -1) {
+ char *mode = pipes[cur].pmode; *mode = 'r';
+ if (current = freopen(pipes[cur].name, mode, stdin)) {
+ rval = os_system(pipes[cur].command);
+ fclose(current);
+ if (dup2(fd, fileno(stdin)) == -1) rval = -1;
+ close(fd);
+ }
+ }
+ unlink(pipes[cur].name);
+ break;
+ default:
+ return -1;
+ }
+ /*
+ ** clean up current pipe.
+ */
+ *pipes[cur].pmode = '\0';
+ free(pipes[cur].name);
+ free(pipes[cur].command);
+ return rval;
+}
--- /dev/null
+/*
+** popen.h -- prototypes for pipe functions
+*/
+
+#if defined (OS2) && !defined(MSDOS) /* OS/2, but not family mode */
+# if defined (_MSC_VER)
+# define popen(c, m) _popen(c, m)
+# define pclose(f) _pclose(f)
+# endif
+#else
+# if !defined (__GO32__)
+# if defined (popen)
+# undef popen
+# undef pclose
+# endif
+# define popen(c, m) os_popen(c, m)
+# define pclose(f) os_pclose(f)
+ extern FILE *os_popen( char *, const char * );
+ extern int os_pclose( FILE * );
+# endif
+#endif
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+2004-02-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.14.1.
+ * Rules-quot: Upgrade to gettext-0.14.1.
+
+2004-01-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.13.1.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+2003-06-16 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.12.1.
+ * Rules-quot: New file, from gettext-0.12.1.
+ * boldquot.sed: New file, from gettext-0.12.1.
+ * en@boldquot.header: New file, from gettext-0.12.1.
+ * en@quot.header: New file, from gettext-0.12.1.
+ * insert-header.sin: New file, from gettext-0.12.1.
+ * quot.sed: New file, from gettext-0.12.1.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Mon Dec 2 11:49:59 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Rules-quot, en@quot.reader, en@boldquot.reader: removed.
+
+Thu Sep 19 11:00:00 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Updated to gettext 0.11.5.
+
+Mon Jun 17 18:26:23 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * POTFILES.in: Updated with list of new regex files.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+2002-04-09 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.11.1.
+ * remove-potcdate.sin: New file, from gettext-0.11.1.
+
--- /dev/null
+es
+fr
+he
+it
+sv
+tr
+de
+da
+pt_BR
+ca
+pl
+ja
+ro
+nl
+rw
+ga
+vi
--- /dev/null
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2005 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.14.4
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = @datadir@
+localedir = $(datadir)/locale
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+mkinstalldirs = $(SHELL) $(MKINSTALLDIRS)
+
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in remove-potcdate.sin \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+ @echo "$(MSGFMT) -c -o $@ $<"; \
+ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+ @lang=`echo $* | sed -e 's,.*/,,'`; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
+ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+ sed -e '/^#/d' $< > t-$@
+ mv t-$@ $@
+
+
+all: all-@USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ test ! -f $(srcdir)/$(DOMAIN).pot || \
+ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+ @test ! -f $(srcdir)/$(DOMAIN).pot || { \
+ echo "touch stamp-po" && \
+ echo timestamp > stamp-poT && \
+ mv stamp-poT stamp-po; \
+ }
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
+# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
+ if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
+ msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
+ else \
+ msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
+ fi; \
+ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
+ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
+ --files-from=$(srcdir)/POTFILES.in \
+ --copyright-holder='$(COPYRIGHT_HOLDER)' \
+ --msgid-bugs-address="$$msgid_bugs_address"
+ test ! -f $(DOMAIN).po || { \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
+ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
+ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
+ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
+ else \
+ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
+ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
+ fi; \
+ else \
+ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
+ fi; \
+ }
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
+$(srcdir)/$(DOMAIN).pot:
+ $(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+ @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+ if test -f "$(srcdir)/$${lang}.po"; then \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \
+ cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \
+ else \
+ $(MAKE) $${lang}.po-create; \
+ fi
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ $(INSTALL_DATA) $(srcdir)/$$file \
+ $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ for file in Makevars; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+install-data-no: all
+install-data-yes: all
+ $(mkinstalldirs) $(DESTDIR)$(datadir)
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(mkinstalldirs) $(DESTDIR)$$dir; \
+ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+ fi; \
+ done; \
+ done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ : ; \
+ fi
+installdirs-data-no:
+installdirs-data-yes:
+ $(mkinstalldirs) $(DESTDIR)$(datadir)
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(mkinstalldirs) $(DESTDIR)$$dir; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ fi; \
+ done; \
+ done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall: uninstall-exec uninstall-data
+uninstall-exec:
+uninstall-data: uninstall-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+uninstall-data-no:
+uninstall-data-yes:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ done; \
+ done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+ rm -f remove-potcdate.sed
+ rm -f stamp-poT
+ rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+ $(MAKE) update-po
+ @$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ dists="$$dists Makevars.template"; \
+ fi; \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ dists="$$dists $(DOMAIN).pot stamp-po"; \
+ fi; \
+ if test -f $(srcdir)/ChangeLog; then \
+ dists="$$dists ChangeLog"; \
+ fi; \
+ for i in 0 1 2 3 4 5 6 7 8 9; do \
+ if test -f $(srcdir)/ChangeLog.$$i; then \
+ dists="$$dists ChangeLog.$$i"; \
+ fi; \
+ done; \
+ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+ for file in $$dists; do \
+ if test -f $$file; then \
+ cp -p $$file $(distdir) || exit 1; \
+ else \
+ cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+ fi; \
+ done
+
+update-po: Makefile
+ $(MAKE) $(DOMAIN).pot-update
+ test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+ $(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+ @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
+ exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+ @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+ cd $(srcdir); \
+ if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+ @:
+
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
+ $(SHELL) ./config.status
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = arnold@skeeve.com
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
--- /dev/null
+# List of source files containing translatable strings.
+# Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+array.c
+awkgram.c
+builtin.c
+eval.c
+ext.c
+field.c
+gawkmisc.c
+getopt.c
+getopt1.c
+io.c
+main.c
+msg.c
+node.c
+posix/gawkmisc.c
+profile.c
+random.c
+re.c
+regcomp.c
+regex_internal.c
+regexec.c
+replace.c
--- /dev/null
+# Special Makefile rules for English message catalogs with quotation marks.
+
+DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
+
+.SUFFIXES: .insert-header .po-update-en
+
+en@quot.po-create:
+ $(MAKE) en@quot.po-update
+en@boldquot.po-create:
+ $(MAKE) en@boldquot.po-update
+
+en@quot.po-update: en@quot.po-update-en
+en@boldquot.po-update: en@boldquot.po-update-en
+
+.insert-header.po-update-en:
+ @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
+ if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ ll=`echo $$lang | sed -e 's/@.*//'`; \
+ LC_ALL=C; export LC_ALL; \
+ cd $(srcdir); \
+ if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "creation of $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+en@quot.insert-header: insert-header.sin
+ sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header
+
+en@boldquot.insert-header: insert-header.sin
+ sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header
+
+mostlyclean: mostlyclean-quot
+mostlyclean-quot:
+ rm -f *.insert-header
--- /dev/null
+s/"\([^"]*\)"/“\1”/g
+s/`\([^`']*\)'/‘\1’/g
+s/ '\([^`']*\)' / ‘\1’ /g
+s/ '\([^`']*\)'$/ ‘\1’/g
+s/^'\([^`']*\)' /‘\1’ /g
+s/“”/""/g
+s/“/“\e[1m/g
+s/”/\e[0m”/g
+s/‘/‘\e[1m/g
+s/’/\e[0m’/g
--- /dev/null
+# translation of gawk.po to Catalan
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Antoni Bella Perez <bella5@teleline.es>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.31\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2003-05-07 21:13+0100\n"
+"Last-Translator: Antoni Bella Perez <bella5@teleline.es>\n"
+"Language-Team: Catalan <ca@dodds.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.0.1\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "s'ha intentat usar la funció «%s» com a una matriu"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "s'ha intentat usar un paràmetre escalar «%s» com a una matriu"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (de %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referència a un element sense valor inicial «%s[\"%s\"]»"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "el subscript de la matriu «%s» és una cadena nul·la"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: l'índex «%s» no està en la matriu «%s»"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: buit (nul)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: buit (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: mida_taula = %d, mida_matriu = %d\n"
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: és un paràmetre\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: ref_matriu a %s\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "Els blocs FINAL han de tindre una part d'acció"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "Els blocs FINAL han de tindre una part d'acció"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "«%s» és una funció interna, no pot ser redefinida"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"la constant d'expressió regular «/%s/» sembla un comentari en C, perà no ho "
+"és"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"la constant d'expressió regular «/%s/» sembla un comentari en C, perà no ho "
+"és"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "la declaració podria no tindre efecte"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "«next» és usat dintre de l'acció BEGIN o END"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "«nextfile» és una extensió de gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "«return» és usat fora del context d'una funció"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"el «print» simple en la regla BEGIN o END probablement ha de ser «print \"\"»"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "«delete array» és una extensió de gawk"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "«delete array» és una extensió de gawk"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "les canonades bidireccionals multi-etapes no funcionen"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "expressió regular a la dreta d'una assignació"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "expressió regular a l'esquerra de l'operador «~» o «!~»"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "expressió regular a la derta de la comparació"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "«getline» no redirigit sense definir dintre de l'acció FINAL"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "la crida de «length» sense parèntesis no és portable"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "la crida de «length» sense parèntesis està desaprovada per POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "expressió de subscript no vàlida"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "nova línia inesperada"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "el text del programa en la línia de comandaments està buit"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "no es pot obrir el fitxer font «%s» per a lectura (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "no es pot llegir el fitxer font «%s» (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "el fitxer font «%s» està buit"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "el fitxer font no finalitza amb un retorn de carro"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "expressió regular sense finalitzar acaba amb «\\» al final del fitxer"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "expressió regular sense finalitzar"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "expressió regular sense finalitzar al final del fitxer"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "l'ús de «\\ #...» com a continuació de línia no és portable"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "la barra invertida no és l'últim caràcter en la línia"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX no permet l'operador «**=»"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "l'antic awk no suporta l'operador «**=»"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX no permet l'operador «**»"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "l'antic awk no suporta l'operador «**=»"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "l'operador «^=» no està suportat en l'antic awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "l'operador «^» no està suportat en l'antic awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "cadena sense finalitzar"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "caràcter «%c» no vàlid en l'expressió"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "«%s» és una extensió de gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "«%s» és una extensió de Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX no permet «%s»"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "«%s» no està suportat en l'antic awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "«goto» se considera nefast!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d no és vàlid com a nombre d'arguments per a %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: el tercer argument és una extensió de gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: la cadena literal com a últim argument de substitució no té efecte"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "sub: el tercer argument no és un objecte intercanviable"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: el segon argument és una extensió de gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"l'ús de dcgettext(_\"...\") no és correcte: elimineu el guió baix inicial"
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"l'ús de dcgettext(_\"...\") no és correcte: elimineu el guió baix inicial"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funció «%s»: paràmetre #%d, «%s», duplica al paràmetre #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "funció «%s»: paràmetre «%s» ofusca la variable global"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "no es pot obrir «%s» per a escriptura (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "enviant el perfil a l'eixida d'error estàndard"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: tancament erroni (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() crida dos vegades!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funció «%s»: no pot usar el nom de la funció com a paràmetre"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nom de la funció «%s» definida prèviament"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "es crida a la funció «%s» però no s'ha definit"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "es defineix la funció «%s» però no s'ha cridat mai"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"l'expressió regular constant per al paràmetre #%d condueix a un valor booleà"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"s'ha cridat a la funció «%s» amb espai entre el nom i el «(»,\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s a \"%s\" ha fallat (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "eixida estàndard"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "motiu desconegut"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: s'ha rebut un argument que no és un número"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: l'argument %g està fora de rang"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: no es pot netejar: la canonada «%s» s'ha obert per a lectura, no per "
+"a escriptura"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: no es pot netejar: el fitxer «%s» s'ha obert per a lectura, no per a "
+"escriptura"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: «%s» no és un fitxer obert, canonada o co-procés"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "índex: el primer argument rebut no és una cadena"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "índex: el segon argument rebut no és una cadena"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: s'ha rebut un argument no numèric"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "«delete array» és una extensió de gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: s'ha rebut un argument que no és una cadena"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: s'ha rebut un argument no numèric"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: s'ha rebut l'argument negatiu %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "no es permeten «$» en els formats awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "el compte d'arguments amb «$» ha de ser > 0"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"el comte d'arguments %d és major que el nombre total d'arguments "
+"proporcionats"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "no es permet «$» després d'un punt en el format"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "no es proporciona «$» per a l'ample o precisió del camp de posició"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "«l» manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "«l» no està permés en els formats POSIX de awk"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "«L» manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "«L» no està permés en els formats POSIX de awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "«h» manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "«h» no està permés en els formats POSIX de awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "no hi ha prou arguments per a satisfer el format d'una cadena"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ desbordament per a aquest"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: l'especificador de format no conté lletra de control"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "s'han proporcionat masses arguments per a la cadena de format"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: sense arguments"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: s'ha rebut un argument no numèric"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: cridat amb l'argument negatiu %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: l'índex d'inici %g no és vàlid, usant 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: l'índex d'inici no enter %g serà truncat"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: la longitud %g és <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: la longitud %g és <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: la longitud sobre un nombre no enter %g serà truncada"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: la cadena font és de longitud zero"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: l'índex d'inici %d sobrepassa l'acabament de la cadena"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: la longitud %d a l'índex d'inici %d excedeix la longitud del 1er "
+"argument (%d)"
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "strftime: el primer argument rebut no és una cadena"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: s'ha rebut una cadena de format buida"
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: el segon argument rebut no és numèric"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: s'ha rebut un argument que no és una cadena"
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "system: s'ha rebut un argument que no és una cadena"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referència a una variable sense inicialitzar «%s»"
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "tolower: s'ha rebut un argument que no és una cadena"
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "toupper: s'ha rebut un argument que no és una cadena"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: el primer argument rebut no és numèric"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: el segon argument rebut no és numèric"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: s'ha rebut un argument que no és numèric"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: s'ha rebut un argument que no és numèric"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: s'ha rebut un argument que no és numèric"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: el tercer argument no és una matriu"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: el tercer argument de 0 és tractat com a 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: el primer argument rebut no és numèric"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime: el segon argument rebut no és numèric"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): els valors negatius donaran resultats estranys"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): els valors fraccionaris sernn truncats"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): un valor de desplaçament massa gran donarà resultats "
+"estranys"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: el primer argument rebut no és numèric"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime: el segon argument rebut no és numèric"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): els valors negatius donaran resultats estranys"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): els valors fraccionaris seran truncats"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): un valor de desplaçament massa gran donarà resultats "
+"estranys"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: el primer argument rebut no és numèric"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: el segon argument rebut no és numèric"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): els valors negatius donaran resultats estranys"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): els valors fraccionaris seran truncats"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: el primer argument rebut no és numèric"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: el segon argument rebut no és numèric"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): els valors negatius donaran resultats estranys"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): els valors fraccionaris seran truncats"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: el primer argument rebut no és numèric"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: el segon argument rebut no és numèric"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): els valors negatius donaran resultats estranys"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): els valors fraccionaris seran truncats"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: s'ha rebut un argument que no és numèric"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): el valor negatiu donarà resultats estranys"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): el valor fraccionari serà truncat"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: «%s» no és una categoria local vàlida"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "tipo de node %d desconegut"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "desbordament del cau temporal en genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "s'ha intentat usar la matriu «%s» en un context escalar"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"bucle for: la matriu «%s» ha canviat de mida de %d a %d durant l'execució "
+"del bucle"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "«break» a fora d'un bucle no és portable"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "no es permet «break» a fora d'un bucle"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "«continue» fora d'un bucle no és portable"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "no es permet «continue» a fora d'un bucle"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "«next» no es pot cridar des d'una regla BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "«next» no es pot cridar des d'una regla FINAL"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "«nextfile» no es pot cridar des d'una regla BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "«nextfile» no es pot cridar des d'una regla FINAL"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "la sentència no té efecte"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "no es pot usar el nom de la funció «%s» com a variable o matriu"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referència a un argument sense inicialitzar «%s»"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referència a una variable sense inicialitzar «%s»"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenació: els efectes colaterals en una expressió han canviat la "
+"longitud d'una altra!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "assignació usada en un context condicional"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "s'ha intentat una divisió per zero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "s'ha intentat una divisió per zero en «%%»"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tipus il·legal (%s) en tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "s'ha intentat una divisió per zero en «/=»"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "s'ha intentat una divisió per zero en «%%=»"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "s'ha cridat a la funció «%s» amb més arguments dels declarats"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "la funció «%s» no està definida"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Pila de Crides a les Funcions:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- principal --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "s'ha intentat una referència de camp a partir d'un valor no numèric"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "s'ha intentat una referència a partir d'una cadena nul·la"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "s'ha intentat accedir al camp %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr ""
+"no es permet l'assignació per a obtindre un resultat d'una funció interna"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "«IGNORECASE» és una extensió de gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "«BINMODE» és una extensió de gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "«%sFMT» especificació errònia «%s»"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "desactivant «--lint» degut a una assignació a «LINT»"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "«extension» és una extensió gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: no es pot obrir «%s» (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: biblioteca «%s»: no es pot cridar a la funció «%s» (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: biblioteca «%s»: no es pot cridar a la funció «%s» (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: no es pot obrir «%s» (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "la funció «%s» no està definida"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "nom de la funció «%s» definida prèviament"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "es defineix la funció «%s» però no s'ha cridat mai"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "la funció «%s» no està definida"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operació No Suportada"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF s'inicialitza sobre un valor negatiu"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: el segon argument no és una matriu"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: la cadena nul·la per al tercer argument és una extensió de gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "«FIELDWIDTHS» és una extensió de gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "la cadena nul·la per a «FS» és una extensió de gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: l'opció «%s» és ambigua\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: l'opció «--%s» no admet cap argument\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: l'opció «%c%s» no admet cap argument\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: l'opció «%s» requereix un argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: no es reconeix l'opció «--%s»\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: no es reconeix l'opció «%c%s»\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: opció il·legal -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: opció no vàlida -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: l'opció requereix un argument -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: l'opció «-W %s» és ambigua\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: l'opció «-W %s» no admet cap argument\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "no es pot obrir el fitxer «%s» per a lectura (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "la finalització del descriptor fd %d («%s») ha fallat (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "tipus d'arbre %s no vàlid dintre de redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "l'expressió en la redirecció «%s» solt té un valor numèric"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "l'expressió per a la redirecció «%s» té un valor de cadena nul·la"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"el fitxer «%s» per a la redirecció «%s» pot ser resultat d'una expressió "
+"lògica"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "mescla innecessària de «>» i «>>» per al fitxer «%.*s»"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "no es pot obrir la canonada «%s» per a l'eixida (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "no es pot obrir la canonada «%s» per a l'entrada (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"no es pot obrir un socket bidireccional «%s» per a les entrades/eixides (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+"no es pot obrir una canonada bidireccional «%s» per a les entrades/eixides (%"
+"s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "no es pot redirigir des de «%s» (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "no es pot redirigir cap a «%s» (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"s'ha arribat al límit del sistema per a fitxers oberts: es començarà a "
+"multiplexar els descriptors de fitxer"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "la finalització de «%s» ha fallat (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "masses canonades o fitxers d'entrada oberts"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: el segon argument hauria de ser «to» o «from»"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: «%.*s» no és un fitxer obert, canonada o co-procés"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "finalització d'una redirecció que no s'ha obert"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: la redirecció «%s» no s'obre amb «|&», s'ignora el segon argument"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "estaus de falla (%d) en la finalització de la canonada «%s» (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "estatus de falla (%d) en la finalització del fitxer «%s» (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "no s'aporta la finalització explícita del socket «%s»"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "no s'aporta la finalització explícita del co-procés «%s»"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "no s'aporta la finalització explícita de la canonada «%s»"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "no s'aporta la finalització explícita del fitxer «%s»"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "error a l'escriure en l'eixida estàndard (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "error a l'escriure en l'eixida d'error estàndard (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "la neteja de la canonada de «%sx» ha fallat (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "la neteja de la canonada per al co-procés de «%sx» ha fallat (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "la neteja del fitxer «%sx» ha fallat (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "el client /inet/raw encara no està a punt, ho sento"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "sols el root pot usar «/inet/raw»."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "el servidor /inet/raw encara no està a punt, ho sento"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "no s'aporta cap protocol (conegut) en el nom del fitxer especial «%s»"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "el nom del fitxer especial «%s» està incomplet"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "port local no vàlid en «%s»"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "s'ha de subministrar un nom de sistema remot a «/inet»"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "s'ha de subministrar un port remot a «/inet»"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "port remot no vàlid en «%s»"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "les comunicacions TCP/IP no estan suportades"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "el fitxer «%s» és un directori"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "useu «PROCINFO[\"%s\"]» en comptes de «%s»"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "useu «PROCINFO[...]» en comptes de «/dev/user»"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "no es pot obrir «%s», mode «%s»"
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "ha fallat la finalització de la canonada (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr ""
+"ha fallat la finalització de l'eixida estàndard en els processos fills (%s)"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"ha fallat la redirecció cap a l'eixida estàndard dels processos fills (dup: %"
+"s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr ""
+"ha fallat la finalització de l'entrada estàndard en els processos fills (%s)"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"ha fallat la redirecció cap a l'entrada estàndard dels processos fills (dup: "
+"%s)"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "ha fallat la finalització de la canonada (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+"ha fallat la redirecció cap a l'eixida estàndard dels processos fills (dup: %"
+"s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+"ha fallat la redirecció cap a l'entrada estàndard dels processos fills (dup: "
+"%s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "ha fallat la restauració de l'eixida estàndard en el procés pare\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "ha fallat la restauració de l'entrada estàndard en el procés pare\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "ha fallat la finalització de la canonada (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "«|&» no està suportat"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "no es pot obrir la canonada «%s» (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "no es pot crear el procés fill per a «%s» (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "el fitxer de dades «%s» està buit"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "error en llegir el fitxer d'entrada «%s»: %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "el valor multicaràcter de «RS» és una extensió de gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "l'opción «-m[fr]» és irrellevant en gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "ús de l'opció -m: «-m[fr] nnn»"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: no es reconeix l'opció «-W %s», serà ignorada\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "s'igonarà l'argument buit per a l'opció «--source»"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"la variable d'entorn «POSIXLY_CORRECT» està establerta: usant «--posix»"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "«--posix» solapa a «--traditional»"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "«--posix» i «--traditional» solapen a «--non-decimal-data»"
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "executar %s com a setuid root pot ser un problema de seguretat"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "no es pot establir el mode en l'entrada estàndard (%s)"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "no es pot establir el mode en l'eixida estàndard (%s)"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "no es pot establir el mode en l'eixida d'error estàndard (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "no hi ha cap text per al programa!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Ús: %s [opcions d'estil POSIX o GNU] -f fitx_prog [--] fitxer ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Ús: %s [opcions d'estil POSIX o GNU] [--] %cprograma%c fitxer ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Opcions POSIX:\t\tOpcions llargues GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f fitx_prog\t\t--file=fitx_prog\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs (fs=sep_camp)\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=valor\t\t--assign=var=valor\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] valor\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fitxer] --dump-variables[=fitxer]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=fitxer]\t--profile[=fitxer]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fitxer]\t--profile[=fitxer]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=text_prog\t--source=text_prog\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr "a la secció «Reporting Problems and Bugs» de la versió impresa.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Aquest programa és programari lliure; pot redistribuir-se i/o modificar-se\n"
+"sota els termes de la Llicència Pública General de GNU tal i como està\n"
+"publicada per la Free Software Foundation; ja siga en la versió 2 de la\n"
+"Llicència, o (a la vostra elecció) qualsevol versió posterior.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Aquest programa es distribueix amb l'esperança de que serà d'utilitat,\n"
+"però SENSE CAP GARANTIA; fins i tot sense la garantia implícita de\n"
+"COMERCIABILITAT o IDONEÏTAT PER A UN PROPÒSIT EN PARTICULAR.\n"
+"Per a més detalls consulteu la Llicència Pública General de GNU.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Junt amb aquest programa hauríeu d'haber rebut una còpia de la Llicència\n"
+"Pública General de GNU; si no és així, escriviu a la Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft no permet inicialitzar FS a un tabulador en la versió POSIX de awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "excepció de coma flotant"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "error fatal: error intern"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "no s'ha pre-obert el descriptor fd per a %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "no es pot pre-obrir /dev/null per al descriptor fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "no es poden trobar els grups: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "línia cmd.:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "ADVERTIMENT: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "Error: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "Fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "no es pot convertir la cadena a coma flotant"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "barra invertida al final de la cadena"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX no permet seqüències d'escapada «\\x»"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "no hi ha dígits hexadecimals en la seqüència d'escapada «\\x»"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "la seqüència d'escapada «\\%c» és tractada com a una simple «%c»"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s «%s»: no es pot inicialitzar close-on-exec: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "no es pot obrir «%s» per a escriptura: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "error intern: Node_var amb vname nul"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# perfil gawk, creat %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# Bloc(s) INICI\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regla(es)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# Bloc(s) FINAL\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funcions, llistades alfabèticament\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "tipus %s inesperat en prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Èxit"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "No hi ha concordança"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Expressió regular no vàlida"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Caràcter de comparació no vàlid"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nom de classe de caràcters no vàlid"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Barra invertida extra al final"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Referència cap enradera no vàlida"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ o [^ desemparellats"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( o \\( desemparellats"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ desemparellat"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Contingut no vàlid de \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Final de rang no vàlid"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Memòria exhaurida"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Expressió regular precedent no vàlida"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Fí prematura de l'expressió regular"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "L'expressió regular és massa gran"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") o \\) desemparellats"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "No hi ha una expressió regular prèvia"
+
+#~ msgid "function %s called\n"
+#~ msgstr "s'ha cridat a la funció %s\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "el camp %d en FIELDWIDTHS, hauria de ser > 0"
+
+#, fuzzy
+#~ msgid "or used as a variable or an array"
+#~ msgstr "no es pot usar el nom de la funció «%s» com a variable o matriu"
+
+#, fuzzy
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: la longitud %g és <= 0"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: ús il·legal de la variable «%s» com a una matriu"
+
+#, fuzzy
+#~ msgid "%s: gvar_ref to %s\n"
+#~ msgstr "%s: ref_matriu a %s\n"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: el primer argument no és una matriu"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: el segon argument no és una matriu"
+
+#, fuzzy
+#~ msgid ""
+#~ "attempt to use array parameter `%s' that was passed from global scalar `%"
+#~ "s'"
+#~ msgstr "s'ha intentat usar un paràmetre escalar «%s» com a una matriu"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "error intern: Node_var_array amb vname nul"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Per a informar d'errors, consulteu el node «Bugs» en «gawk.info», que "
+#~ "està\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "sintaxi no vàlida en el nom «%s» per a l'asignació de la variable"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "o s'ha emprat en un altre context de l'expressió"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "«%s» és una funció, l'assignació no és permesa"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Els blocs INICI han de tindre una part d'acció"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "«nextfile» és usat dintre de l'acció BEGIN o END"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr "«getline» no redirigit sense definir dintre de l'acció BEGIN o END"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x no està en la taula de referència\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "gsub: el tercer argument no és un objecte intercanviable"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "seqüència d'escapada \\ sense finalitzar"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "repetició del comptador sense finalitzar"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "repetició del comptador malformada"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ sense aparellar"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( sense aparellar"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "No s'especifiquen els bits de sintaxi de l'expressió regular"
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") sense aparellar"
+
+#~ msgid "out of memory"
+#~ msgstr "memòria esgotada"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "error intern: fitxer «%s», línia %d\n"
--- /dev/null
+# Danish translation of gawk
+# Copyright (C) 2001 Free Software Foundation, Inc.
+# Keld Simonsen <keld@dkuug.dk>, 2002.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.31\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2002-11-09 10:09+0100\n"
+"Last-Translator: Keld Simonsen <keld@dkuug.dk>\n"
+"Language-Team: Danish <dansk@klid.dk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "forsøg på at bruge funktionen \"%s\" som vektor"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "forsøg på at bruge skalarparameteren \"%s\" som en vektor"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "forsøg på at bruge skalaren \"%s\" som vektor"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (fra %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "reference til ikke-initieret element \"%s[\"%s\"]\""
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "indeks i vektoren \"%s\" er en tom streng"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: indeks \"%s\" findes ikke i vektoren \"%s\""
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: tom (nil)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: tom (nul)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: tabelstørrelse = %d, vektorstørrelse = %d\n"
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: er en parameter\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: vektorreference til %s\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "END-blok skal have en handlingsdel"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "END-blok skal have en handlingsdel"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "\"%s\" er en indbygget funktion, den kan ikke omdefineres"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "regexp-konstanten \"/%s/\" ser ud som en C-kommentar, men er det ikke"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "regexp-konstanten \"/%s/\" ser ud som en C-kommentar, men er det ikke"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "kommandoen har måske ikke nogen effekt"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "\"next\" brugt i BEGIN- eller END-handling"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "\"nextfile\" er en gawk-udvidelse"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "\"return\" brugt uden for funktion"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"alenestående \"print\" i BEGIN eller END-regel bør muligvis være 'print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "\"delete array\" er en gawk-udvidelse"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "\"delete array\" er en gawk-udvidelse"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "flertrins dobbeltrettede datakanaler fungerer ikke"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "regulært udtryk i højreleddet af en tildeling"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "regulært udtryk på venstre side af en \"~\"- eller \"!~\"-operator"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "regulært udtryk i højreleddet af en sammenligning"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "ikke-omdirigeret \"getline\" udefineret inde i END-handling"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "kald af \"length\" uden parenteser er ikke portabelt"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "kald af \"length\" uden parenteser er forældet ifølge POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "ugyldig indeksudtryk"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "uventet nylinjetegn"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "tom programtekst på kommandolinjen"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "kan ikke åbne kildefilen \"%s\" for læsning (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "kan ikke læse kildefilen \"%s\" (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "kildefilen \"%s\" er tom"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "kildefilen slutter ikke med en ny linje"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "uafsluttet regulært udtryk slutter med \"\\\" i slutningen af filen"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "uafsluttet regulært udtryk"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "uafsluttet regulært udtryk i slutningen af filen"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "Brug af \"\\ #...\" for linjefortsættelse er ikke portabelt"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "sidste tegn på linjen er ikke en omvendt skråstreg"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX tillader ikke operatoren \"**=\""
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "gamle awk understøtter ikke operatoren \"**=\""
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX tillader ikke operatoren \"**\""
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "gamle awk understøtter ikke operatoren \"**\""
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "operatoren \"^=\" understøttes ikke i gamle awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "operatoren \"^\" understøttes ikke i gamle awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "uafsluttet streng"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "ugyldigt tegn \"%c\" i udtryk"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "\"%s\" er en gawk-udvidelse"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "\"%s\" er en Bell Labs-udvidelse"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX tillader ikke \"%s\""
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "\"%s\" understøttes ikke i gamle awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "\"goto\" anses for skadlig!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d er et ugyldigt antal argumenter for %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: tredje argument er en gawk-udvidelse"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: bogstavelig streng som sidste argument til erstatning har ingen effekt"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "sub: tredje argument er ikke et ændringsbart objekt"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: andet argument er en gawk-udvidelse"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"brug af dcgettext(_\"...\") er fejlagtigt: fjern det indledende "
+"understregningstegn"
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"brug af dcgettext(_\"...\") er fejlagtigt: fjern det indledende "
+"understregningstegn"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funktionen \"%s\": parameter %d, \"%s\", er samme som parameter %d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "funktionen \"%s\": parameteren \"%s\" overskygger en global variabel"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "kunne ikke åbne \"%s\" for skrivning (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "sender profilen til standard fejl"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: mislykkedes at lukke (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() kaldt to gange!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funktionen \"%s\": kan ikke bruge funktionsnavn som parameternavn"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funktionsnavnet \"%s\" er allerede defineret"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "funktionen \"%s\" kaldt, men aldrig defineret"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "funktionen \"%s\" defineret, men aldrig kaldt"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "konstant regulært udtryk for parameter %d giver en boolesk værdi"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"funktionen \"%s\" kaldt med blanktegn mellem navnet og \"(\",\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s til \"%s\" mislykkedes (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standard ud"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "ukendt årsag"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: fik et ikke-numerisk argument"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argumentet %g er uden for tilladt område"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kan ikke spole: datakanalen \"%s\" åbnet for læsning, ikke skrivning"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr "fflush: kan ikke spole: filen \"%s\" åbnet for læsning, ikke skrivning"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: \"%s\" er ikke en åben fil, datakanal eller ko proces"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "indeks: første argument er ikke en streng"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "indeks: andet argument er ikke en streng"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: fik et ikke-numerisk argument"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "\"delete array\" er en gawk-udvidelse"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: fik et argument som ikke er en streng"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: fik et ikke-numerisk argument"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: fik et negativt argument %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "\"$\" tillades ikke i awkformat"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "argumentantallet med \"$\" skal være > 0"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "argumentantallet %d er større end antal givne argumenter"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "\"$\" tillades ikke efter et punktum i formatet"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "intet \"$\" angivet for positionsangivet feltbredde eller præcision"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "\"l\" er meningsløst i awk-formater, ignoreret"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "\"l\" tillades ikke i POSIX awk-formater"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "\"L\" er meningsløst i awk-formater, ignoreret"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "\"L\" tillades ikke i POSIX awk-formater"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "\"h\" er meningsløst i awk-formater, ignoreret"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "\"h\" tillades ikke i POSIX awk-formater"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "for få argumenter til formatstrengen"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ sluttede her"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: formatspecifiereren har intet kommandobogstav"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "for mange argumenter til formatstrengen"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: ingen argumenter"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: fik ikke-numerisk argument"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: startindeks %g er ugyldigt, bruger 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: startindeks %g som ikke er et heltal bliver trunkeret"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: længden %g er <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: længden %g er <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: længden %g som ikke er et heltal bliver trunkeret"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: kildestrengen er tom"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: startindeks %d er forbi slutningen på strengen"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: længden %d ved startindeks %d overskrider længden af første argument "
+"(%d)"
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "strftime: fik et første argument som ikke er en streng"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: fik en tom formatstreng"
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: fik et ikke-numerisk andet argument"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: fik et argument som ikke er en streng"
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "system: fik et argument som ikke er en streng"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "reference til ikke-initieret variabel \"%s\""
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "tolower: fik et argument som ikke er en streng"
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "toupper: fik et argument som ikke er en streng"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: fik et ikke-numerisk første argument"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: fik et ikke-numerisk andet argument"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: fik et ikke-numerisk argument"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: fik et ikke-numerisk argument"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: fik et ikke-numerisk argument"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: tredje argument er ikke en vektor"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: Nullet i tredje argument behandlet som et ét-tal"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: fik et ikke-numerisk første argument"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime: fik et ikke-numerisk andet argument"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: fik et ikke-numerisk første argument"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime: fik et ikke-numerisk andet argument"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: fik et ikke-numerisk første argument"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: fik et ikke-numerisk andet argument"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: fik et ikke-numerisk første argument"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: fik et ikke-numerisk andet argument"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: fik et ikke-numerisk første argument"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: fik et ikke-numerisk andet argument"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: fik et ikke-numerisk argument"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): flydendetalsværdier vil blive trunkeret"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: \"%s\" er ikke en gyldig lokalekategori"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "ukendt nodetype %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "bufferoverløb i genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "forsøg på at bruge vektoren \"%s\" i skalarsammenhæng"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for-løkke: vektoren \"%s\" ændrede størrelse fra %d til %d under løkke-"
+"udførelsen"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "\"break\" uden for en løkke er ikke portabelt"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "\"break\" uden for en løkke er ikke tilladt"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "\"continue\" uden for en løkke er ikke portabelt"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "\"continue\" uden for en løkke er ikke tilladt"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "\"next\" kan ikke kaldes fra en BEGIN-regel"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "\"next\" kan ikke kaldes fra en END-regel"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "\"nextfile\" kan ikke kaldes fra en BEGIN-regel"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "\"nextfile\" kan ikke kaldes fra en END-regel"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "kommandoen har ingen effekt"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "kan ikke bruge funktionsnavnet \"%s\" som variabel eller vektor"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "reference til ikke-initieret argument \"%s\""
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "reference til ikke-initieret variabel \"%s\""
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation: sideeffekter i et udtryk har ændret længden af et andet!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "tildeling brugt i sammenligningsammenhæng"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "forsøgte at dividere med nul"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "forsøgte at dividere med nul i \"%%\""
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "ikke tilladt type (%s) i tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "forsøgte at dividere med nul i \"/=\""
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "forsøgte at dividere med nul i \"%%=\""
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "funktionen \"%s\" kaldt med flere argumenter end deklareret"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "funktionen \"%s\" er ikke defineret"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Funktionskaldsstak:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "forsøg på at feltreferere fra ikke-numerisk værdi"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "forsøg på at referere fra tom streng"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "forsøg på at få adgang til felt nummer %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "tildeling er ikke tilladt til resultatet fra en indbygget funktion"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "\"IGNORECASE\" er en gawk-udvidelse"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "\"BINMODE\" er en gawk-udvidelse"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "fejlagtig \"%sFMT\"-specifikation \"%s\""
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "deaktiverer \"--lint\" på grund af en tildeling til \"LINT\""
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "\"extension\" er en gawk-udvidelse"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: kan ikke åbne \"%s\" (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: bibliotek \"%s\": kan ikke kalde funktionen \"%s\" (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: bibliotek \"%s\": kan ikke kalde funktionen \"%s\" (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: kan ikke åbne \"%s\" (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "funktionen \"%s\" er ikke defineret"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "funktionsnavnet \"%s\" er allerede defineret"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "funktionen \"%s\" defineret, men aldrig kaldt"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "funktionen \"%s\" er ikke defineret"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "forsøg på at bruge skalaren \"%s\" som vektor"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operationen understøttes ikke"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF sat til en negativ værdi"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: andet argument er ikke en vektor"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: tom streng som tredje argument er en gawk-udvidelse"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "\"FIELDWIDTHS\" er en gawk-udvidelse"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "tom streng som \"FS\" er en gawk-udvidelse"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: flaget \"%s\" er flertydigt\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: flaget \"--%s\" tillader ikke noget argument\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: flaget \"%c%s\" tillader ikke noget argument\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: flaget \"%s\" kræver et argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: ukendt flag \"--%s\"\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: ukendt flag \"%c%s\"\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: ikke tilladt flag -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: ugyldig flag -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: flaget kræver et argument -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: flaget \"-W %s\" er flertydigt\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: flaget \"-W %s\" tillader ikke noget argument\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "kan ikke åbne filen \"%s\" for læsning (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "lukning af fd %d (\"%s\") mislykkedes (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "ugyldig trætype %s i redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "udtrykket i \"%s\"-omdirigering har kun numerisk værdi"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "udtrykket for \"%s\"-omdirigering har en tom streng som værdi"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"filnavnet \"%s\" for \"%s\"-omdirigering kan være resultatet af et logisk "
+"udtryk"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "unødig blanding af \">\" og \">>\" for filen \"%.*s\""
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "kan ikke åbne røret \"%s\" for udskrivning (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "kan ikke åbne røret \"%s\" for indtastning (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "kan ikke åbne tovejssoklen \"%s\" for ind-/uddata (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "kan ikke åbne tovejsrøret \"%s\" for ind-/uddata (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "kan ikke omdirigere fra \"%s\" (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "kan ikke omdirigere til \"%s\" (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"nåede systembegrænsningen for åbne filer: begynder at multiplekse "
+"fildeskriptorer"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "lukning af \"%s\" mislykkedes (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "for mange rør eller inddatafiler åbne"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: andet argument skal være \"to\" eller \"from\""
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: \"%.*s\" er ikke en åben fil, datakanal eller ko-proces"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "lukning af omdirigering som aldrig åbnedes"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: omdirigeringen \"%s\" åbnedes ikke med \"|&\", andet argument "
+"ignoreret"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "fejlstatus (%d) fra rørlukning af \"%s\" (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "fejlstatus (%d) fra fillukning af \"%s\" (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "ingen eksplicit lukning af soklen \"%s\" angivet"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "ingen eksplicit lukning af ko-processen \"%s\" angivet"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "ingen eksplicit lukning af røret \"%s\" angivet"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "ingen eksplicit lukning af filen \"%s\" angivet"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "fejl ved skrivning til standard ud (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "fejl ved skrivning til standard fejl (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "rørspuling af \"%s\" mislykkedes (%s)"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "ko-processpuling af røret til \"%s\" mislykkedes (%s)"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "filspuling af \"%s\" mislykkedes (%s)"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "/inet/raw-klient er desværre ikke klar endnu"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "kun root kan bruge \"/inet/raw\"."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "/inet/raw-server er desværre ikke klar endnu"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "ingen (kendt) protokol opgivet i special-filnavn \"%s\""
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "special-filnavn \"%s\" er ufuldstændigt"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "lokal port ugyldig i \"%s\""
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "skal angive et fjernmaskinenavn til \"/inet\""
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "skal angive en fjernport til \"/inet\""
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "fjernporten ugyldig i \"%s\""
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP-kommunikation understøttes ikke"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "filen \"%s\" er et katalog"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "brug \"PROCINFO[\"%s\"]\" i stedet for \"%s\""
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "brug \"PROCINFO[...]\" i stedet for \"dev/user\""
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "kunne ikke åbne \"%s\", tilstand \"%s\""
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "lukning af røret mislykkedes (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "lukning af standard ud i barnet mislykkedes (%s)"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "flytning af rør til standard ud i barnet mislykkedes (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "lukning af standard ind i barnet mislykkedes (%s)"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "flytning af rør til standard ind i barnet mislykkedes (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "lukning af røret mislykkedes (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "flytning af rør til standard ud i barnet mislykkedes (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "flytning af rør til standard ind i barnet mislykkedes (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "genskabelse af standard ud i forælderprocessen mislykkedes\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "genskabelse af standard ind i forælderprocessen mislykkedes\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "lukning af røret mislykkedes (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "\"|&\" understøttes ikke"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "kan ikke åbne røret \"%s\" (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "kan ikke oprette barneproces for \"%s\" (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "datafilen \"%s\" er tom"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "fejl ved læsning af inddatafilen \"%s\": %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "flertegnsværdien af \"RS\" er en gawk-udvidelse"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "\"-m[fr]\"-flaget er irrelevant i gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m-flagets brug: \"-m[fr] nnn\""
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: flaget \"-W %s\" ukendt, ignoreret\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "tomt argument til \"--source\" ignoreret"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "miljøvariablen \"POSIXLY_CORRECT\" sat: aktiverer \"--posix\""
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "\"--posix\" tilsidesætter \"--traditional\""
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "\"--posix\"/\"--traditional\" tilsidesætter \"--non-decimal-data\""
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "at køre %s setuid root kan være et sikkerhedsproblem"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "kan ikke sætte tilstand på standard ind (%s)"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "kan ikke sætte tilstand på standard ud (%s)"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "kan ikke sætte tilstand på standard fejl (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "ingen programtekst overhovedet!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Brug: %s [POSIX- eller GNU-stilflag] -f progfil [--] fil ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Brug: %s [POSIX- eller GNU-stilflag] %cprogram%c fil ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "POSIX-flag:\t\tGNU lange flag:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f progfil\t\t--file=progfil\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=værdi\t\t--assign=var=værdi\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] værdi\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fil]\t--dump-variables[=fil]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=fil]\t--profile[=fil]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fil]\t--profile[=fil]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=programtekst\t--source=programtekst\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"sektionen \"Reporting Problems and Bugs\" i den trykte version.\n"
+"Rapportér synpunkter på oversættelsen til <dansk@klid.dk>.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright © 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Dette program er frit programmel. Du kan distribuere det og/eller\n"
+"ændre det under betingelserne i GNU General Public License, offentliggjort\n"
+"af Free Software Foundation, enten version 2 eller (hvis du vil)\n"
+"enhver senere version.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Dette program distribueres i håb om at det vil være nyttigt,\n"
+"men UDEN NOGEN SOM HELST GARANTI, også uden underforstået garanti\n"
+"om SALGBARHED eller EGNETHED FOR NOGET SPECIELT FORMÅL. Se GNU\n"
+"General Public License for yderligere information.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Du bør have fået en kopi af GNU General Public License sammen\n"
+"med dette program. Hvis ikke, så skriv til Free Software Foundation,\n"
+"Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft sætter ikke FS til tab i POSIX-awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "flydendetalsundtagelse"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "fatal fejl: intern fejl"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "ingen for-åbnet fd %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "kunne ikke for-åbne /dev/null for fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "kunne ikke finde grupper: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "kommandolinje:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "advarsel: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "fejl: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "kan ikke konvertere en streng til flydende tal"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "omvendt skråstreg i slutningen af strengen"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX tillader ikke \"\\x\"-kontrolsekvenser"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "ingen heksadecimale cifre i \"\\x\"-kontrolsekvenser"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "kontrolsekvensen \"\\%c\" behandlet som kun \"%c\""
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s \"%s\": kunne ikke sætte luk-ved-exec (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "kunne ikke åbne \"%s\" for skrivning: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "intern fejl: Node_var med null vname"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawkprofil, oprettet %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN-blok\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regel/regler\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END-blok\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funktioner, listede alfabetisk\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "uventet type %s i prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Lykkedes"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Mislykkedes"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Ugyldigt regulært udtryk"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Ugyldigt kollationeringstegn"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Ugyldigt tegnklassenavn"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Efterfølgende omvendt skråstreg"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Ugyldig bagudreference"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Ubalanceret [ eller [^"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Ubalanceret ( eller \\("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Ubalanceret \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Ugyldigt indhold i \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Ugyldig intervalslutning"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Hukommelsen opbrugt"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Ugyldigt foregående regulært udtryk"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "For tidligt slut på regulært udtryk"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Regulært udtryk for stort"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Ubalanceret ) eller \\)"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Intet foregående regulært udtryk"
+
+#~ msgid "function %s called\n"
+#~ msgstr "funktionen %s kaldt\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "felt %d i FIELDWIDTHS skal være > 0"
+
+#, fuzzy
+#~ msgid "or used as a variable or an array"
+#~ msgstr "kan ikke bruge funktionsnavnet \"%s\" som variabel eller vektor"
+
+#, fuzzy
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: længden %g er <= 0"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: ikke tilladt brug af variablen \"%s\" som vektor"
+
+#, fuzzy
+#~ msgid "%s: gvar_ref to %s\n"
+#~ msgstr "%s: vektorreference til %s\n"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: første argument er ikke en vektor"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: andet argument er ikke en vektor"
+
+#, fuzzy
+#~ msgid ""
+#~ "attempt to use array parameter `%s' that was passed from global scalar `%"
+#~ "s'"
+#~ msgstr "forsøg på at bruge skalarparameteren \"%s\" som en vektor"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "intern fejl: Node_var_vektor med null vname"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "BEGIN-blok skal have en handlingsdel"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "\"nextfile\" brugt i BEGIN- eller END-handling"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "gsub: tredje argument er ikke et ændringsbart objekt"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "eller brugt i andre udtrykssammenhænge"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "\"%s\" er en funktion, tildeling er ikke tilladt"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "intern fejl: filen \"%s\", linje %d\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "For at rapportere fejl, se knuden \"Bugs\" i \"gawk.info\" som findes i\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "ugyldig syntaks i navnet \"%s\" for variabeltildeling"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "ikke-omdirigeret \"getline\" udefineret inde i BEGIN- eller END-handling"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x er ikke i tokentab\n"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Uafsluttet \\-kontrolsekvens"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "uafsluttet gentagelsesantal"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "fejlagtigt udformet gentagelsesantal"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "Ubalanceret ["
+
+#~ msgid "Unbalanced ("
+#~ msgstr "Ubalanceret ("
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Ingen syntaksbit for regulære udtryk angivet"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "Ubalanceret )"
+
+#~ msgid "out of memory"
+#~ msgstr "slut på hukommelsen"
--- /dev/null
+# GNU awk message strings
+# Copyright (C) 2000 Free Software Foundation, Inc.
+# Unknown Author, <info@gnu.org>, 2000
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.0\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2002-04-03 18:55+02:00\n"
+"Last-Translator: Christian Kirsch <ck@held.mind.de>\n"
+"Language-Team: German <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "Versuch, die Funktion '%s' als Array zu verwenden."
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "Versuch den skalaren Parameter '%s' als Array zu benutzen."
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "Versuch, Skalar '%s' als Array zu verwenden."
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (von %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "Bezug auf nicht-initialisiertes Element »%s[\"%s\"]«"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "Index in Array »%s« ist Nullstring."
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: Index »%s« nicht in Feld »%s« vorhanden."
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: leer (Null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: leer (0)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: Table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: ist ein Parameter\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: Array-Referenz auf %s\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "END-Blöcke müssen einen Aktionsteil haben."
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "END-Blöcke müssen einen Aktionsteil haben."
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "'%s' ist eine eingebaute Funktion und kann nicht umdefiniert werden."
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"Konstanter Regulärer Ausdruck '/%s' sieht wie ein C-Kommentar aus, ist aber "
+"keiner."
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"Konstanter Regulärer Ausdruck '/%s' sieht wie ein C-Kommentar aus, ist aber "
+"keiner."
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "Statement möglicherweise ohne Effekt."
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "'next' in BEGIN- oder END-Aktion benutzt."
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "'nextfile' ist eine gawk-Erweiterung."
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "'return' außerhalb einer Funktion benutzt."
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"Einfaches 'print' in BEGIN- oder END-Regel soll vermutlich 'print \"\"' sein."
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "'delete array' ist eine gawk-Erweiterung."
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "'delete array' ist eine gawk-Erweiterung."
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "'multistage' Zweiwege-Pipes funktionieren nicht."
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "Regulärer Ausdruck auf der rechten Seite einer Zuweisung."
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "Regulärer Ausdruck links vom '~'- oder '!~'-Operator."
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "Regulärer Ausdruck rechts von einem Vergleich."
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr ""
+"Nicht-umgelenktes 'getline' ist innerhalb der END-Aktion nicht definiert."
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "Aufruf von 'length' ohne Klammern ist nicht portabel."
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "Aufruf von 'length' ohne Klammern ist in POSIX-Mode veraltet."
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "Ungültiger Index-Ausdruck."
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "Unerwartetes Zeilenende"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "Kein Programmtext auf der Kommandozeile."
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "Kann Quelldatei '%s' nicht zum Lesen öffnen (%s)."
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "Kann Quelldatei '%s' nicht lesen (%s)."
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "Quelldatei '%s' ist leer."
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "Quelldatei hört nicht mit Zeilenende auf."
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+"Nicht-beendeter Regulärer Ausdruck (hört mit '\\' auf) am Ende der Datei."
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "Nicht-beendeter Regulärer Ausdruck"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "Nicht-beendeter Regulärer Ausdruck am Dateiende."
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr ""
+"Die Verwendung von '\\#...' zur Fortsetzung von Zeilen ist nicht portabel."
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "Backslash ist nicht letztes Zeichen auf der Zeile."
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX erlaubt den Operator '**=' nicht."
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "Das alte awk erlaubt den Operator '**=' nicht."
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX erlaubt den Operator '**' nicht."
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "Das alte awk erlaubt den Operator '**' nicht."
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "Das alte awk kennt den Operator '^=' nicht."
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "Das alte awk kennt den Operator '^' nicht."
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "Nicht-beendeter String"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "Ungültiges Zeichen '%c' in einem Ausdruck."
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "'%s' ist eine gawk-Erweiterung"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "'%s' ist eine Erweiterung der Bell Labs."
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX gestattet '%s' nicht."
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "Das alte awk gestattet '%s' nicht."
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "'goto' gilt als schlechter Stil!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "Unzulässige Argumentzahl %d für %s."
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: Das dritte Argument ist eine gawk-Erweiterung."
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: Ein String als letztes Argument von substitute hat keinen Effekt."
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "Der dritte Parameter von sub ist ein unveränderliches Objekt."
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: Das zweite Argument ist eine gawk-Erweiterung."
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"Fehlerhafte Verwendung von dcgettext(_\"...\"): \n"
+"Entfernen Sie den führenden Unterstrich."
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"Fehlerhafte Verwendung von dcgettext(_\"...\"): \n"
+"Entfernen Sie den führenden Unterstrich."
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "Funktion '%s': Parameter #%d, '%s' wiederholt Parameter #%d."
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "Funktion '%s': Parameter '%s' verdeckt eine globale Variable."
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "Kann '%s' nicht zum Schreiben öffnen (%s)."
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "Schicke Profile auf Stadard-Fehlerausgabe."
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: close gescheitert (%s)."
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() zweimal aufgerufen!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "Funktion '%s': Kann Funktionsnamen nicht als Parameternamen benutzen."
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "Funktion '%s' ist bereits definiert."
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "Aufgerufene funktion '%s' ist nirgends definiert."
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "Funktion '%s' wird nirgends aufgerufen."
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"Konstanter Regulärer Ausdruck für Parameter #%d ergibt einen logischen Wert."
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"Funktion '%s' mit Leerzeichen zwischen Name und '(' aufgerufen, \n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s to \"%s\" fehlgeschlagen (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "Standardausgabe"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "Unbekannte Ursache"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: Argument ist keine Zahl."
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: Argument %g außerhalb des gültigen Zahlenbereichs."
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: Leeren der Puffer nicht möglich, Pipe »%s« ist nur zum Lesen "
+"geöffnet."
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: Leeren der Puffer nicht möglich, Datei »%s« ist nur zum Lesen "
+"geöffnet."
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: »%s« ist keine geöffnete Datei, Pipe oder Prozess."
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: Erstes Argument ist kein String."
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: Zweites Argument ist kein string."
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "Argument ist keine Zahl."
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "'delete array' ist eine gawk-Erweiterung."
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: Argument ist kein String."
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: Argument ist keine Zahl."
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: Negatives Argument %g."
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "»$« ist in awk-Formaten nicht zulässig."
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "Argumentnummer bei »$« muss > 0 sein."
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "Argumentnummer %d ist größer als Anzahl angegebener Argumente."
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "»$« nach Punkt in Formatangabe nicht zulässig."
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "»$« fehlt in positionsabhängiger Feldbreite oder Genauigkeit."
+
+#
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "»l« ist in awk-Formaten bedeutungslos, ignoriert."
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "»l« in POSIX-awk-Formaten nicht zulässig."
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "»L« ist in awk-Formaten bedeutungslos, ignoriert."
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "»L« in POSIX-awk-Formaten nicht zulässig."
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "»h« ist in awk-Formaten bedeutungslos, ignoriert."
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "»h« in POSIX-awk-Formaten nicht zulässig.<"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "Nicht genügend Argumente für Formatangabe."
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ ran out for this one"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: Format-Specifier hat keinen Controlcode."
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "Zu viele Argumente für Formatstring."
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: Keine Argumente"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: Argument ist keine Zahl."
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: Argument %g ist negativ."
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: Start-Index %g ist ungültig, 1 wird benutzt."
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: Start-Wert %g wird abgeschnitten."
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: Länge %g ist kleiner oder gleich 0."
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: Länge %g ist kleiner oder gleich 0."
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: Länge %g wird abgeschnitten."
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: String ist leer."
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: Start-Wert %d liegt hinter dem Ende des Strings."
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: Länge %d am Start-Wert %d überschreitet Länge des ersten Arguments (%"
+"d)."
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "strftime: Erstes Argument ist kein String."
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: Format-String ist leer."
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime. Zweites Argument ist keine Zahl."
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: Argument ist kein String."
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "system: Argument ist kein String."
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "Referenz auf die nicht-initialisierte Variable '%s'."
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "tolower: Argument ist kein String."
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "toupper: Argument ist kein String."
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: Erstes Argument ist keine Zahl."
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: Zweites Argument ist keine Zahl."
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: Argument istk eine Zahl."
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: Argument ist keine Zahl."
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: Argument ist keine Zahl."
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: Drittes Argument ist kein Array."
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: Drittes Argument 0 als 1 interpretiert"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime. Zweites Argument ist keine Zahl."
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr ""
+"lshift(%lf, %lf): Negative Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): Zu große Shift-Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime. Zweites Argument ist keine Zahl."
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr ""
+"rshift (%lf, %lf): Negative Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): Zu große Shift-Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: Zweites Argument ist keine Zahl."
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): Negative Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: Zweites Argument ist keine Zahl."
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): Negative Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: Zweites Argument ist keine Zahl."
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf: Negative Werte werden merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: Erstes Argument ist keine Zahl."
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): Negativer Wert wird merkwürdige Ergebnisse liefern."
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): Dezimalteil wird abgeschnitten."
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: '%s' ist keine gültige Locale-Kategorie."
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "Unbekannter Knotentyp %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "Pufferüberlauf in genflags2str."
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "Versuch, das Array '%s' in Skalarkontext zu verwenden."
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for-Schleife: Array '%s' ändert Größse von %d zu %d innerhalb der Schleife."
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "'break' außerhalb einer Schleife ist nicht portabel."
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "'break' außerhalb einer Schleife ist nicht zulässig."
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "'continue' außerhalb einer Schleife ist nicht portabel."
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "'continue' außerhalb einer Schleife ist nicht zulässig."
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "'next' kann nicht in einer BEGIN-Regel benutzt werden."
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "'next' kann nicht in einer END-Regel benutzt werden."
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "'nextfile' kann nicht in einer BEGIN-Regel benutzt werden."
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "'nextfile' kann nicht in einer END-Regel benutzt werden."
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "Anweisung hat keinen Effekt."
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "Kann Funktion '%s' nicht als Variable oder Array verwenden."
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "Referenz auf nicht-initialisiertes Argument '%s'."
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "Referenz auf die nicht-initialisierte Variable '%s'."
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"Konkatenierung: Seiteneffekte in einem Ausdruck haben die Länge des anderen\n"
+"geändert!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "Zuweisung in einer Bedingung."
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "Division durch Null versucht."
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "Division durch Null versucht in '%%'."
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "Illegaler Typ (%s) in tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "Division durch Null versucht in '/='."
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "Division durch Null versucht in '%%='."
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "Funktion '%s' mit zu vielen Argumenten aufgerufen."
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "Funktion '%s' ist nicht definiert."
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Funktion Aufruf-Stack\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "Nicht-numerischer Wert für Feldreferenz verwendet."
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "Referenz von einem Null-String"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "Versuch des Zugriffs auf Feld %d."
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr ""
+"Zuweisungen an das Ergebnis einer eingebauten Funktion sind nicht erlaubt."
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "'IGNORECASE' ist eine gawk-Erweiterung"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "'BINMODE' ist eine gawk-Erweiterung."
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "Falsche '%sFMT'-Angabe '%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "'--lint' wird abgeschaltet, da 'LINT' gesetzt ist."
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "'extension' ist eine gawk-Erweiterung."
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: Kann '%s' nicht öffnen (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: Bibliothek '%s': kann Funktion '%s' nicht aufrufen (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: Bibliothek '%s': kann Funktion '%s' nicht aufrufen (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: Kann '%s' nicht öffnen (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "Funktion '%s' ist nicht definiert."
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "Funktion '%s' ist bereits definiert."
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "Funktion '%s' wird nirgends aufgerufen."
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "Funktion '%s' ist nicht definiert."
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "Versuch, Skalar '%s' als Array zu verwenden."
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operation nicht möglich."
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr ""
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: Zweites Argument ist kein Array."
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: Null-String als drittes Argument ist eine gawk-Erweiterung."
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "'FIELDWIDTHS' ist eine gawk-Erweiterung."
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "Null-String für 'FS' ist eine gawk-Erweiterung."
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: Option '%s' ist mehrdeutig.\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: Option '--%s' erlaubt kein Argument.\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: Option '%c%s\" erlaubt kein Argument.\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: Option '%s' erfordert ein Argument.\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: Unbekannte Option '--%s'.\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: Unbekannte Option '%c%s'.\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: Illegale Option -- %c.\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: Ungültige Option -- %c.\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s Option erfordert ein Argument -- %c.\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: Option '-W %s' ist mehrdeutig.\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s. Option '-W %s' erlaubt kein Argument.\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "Kann Datei '%s' nicht zum Lesen öffnen (%s)."
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "Schließen von Dateideskriptor %d ('%s') gescheitert (%s)."
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "Ungültiger Tree-Typ %s in redirect()."
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "Ausdruck in '%s' Umlenkung hat nur einen numerischen Wert."
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "Ausdruck für '%s' Umlenkung ist ein leerer String."
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"Dateiname '%s' für '%s' Umlenkung kann Ergebnis eines logischen Ausdrucks "
+"sein."
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "Unnötige Kombination von '>' und '>>' für Datei '%.*s'."
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "Kann Pipe '%s' nicht für Ausgabe öffnen (%s)."
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "Kann Pipe '%s' nicht für Eingabe öffnen (%s)."
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "Kann bidirektionalen Socket '%s' nicht für Ein-/Ausgabe öffnen (%s)."
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "Kann bidirektionale Pipe '%s' nicht für Ein-/Ausgabe öffnen (%s)."
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "Kann nicht von '%s' umlenken (%s)."
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "Kann nicht auf '%s' umlenken (%s)."
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"Systemgrenze offener Dateien erreicht; beginne mit Multiplexing von "
+"Dateideskriptoren."
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "Schließen von '%s' gescheitert (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "Zu viele Pipes oder Eingabedateien offen."
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: Zweites Argument muss 'to' oder 'from' sein."
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: '%.*s' ist keine offene Datei, Pipe oder Ko-Prozess."
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "'close' für eine Umlenkung, die nie geöffnet wurde."
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: Umlenkung '%s' nicht mit '[&' geöffnet, zweites Argument wird "
+"ignoriert."
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "Fehlerstatus (%d) beim Schließen der Pipe '%s' (%s)."
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "Fehlerstatus (%d) beim Schließen de rDatei '%s' (%s)."
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "Das explizite des Sockets '%s' fehlt."
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "Das explizite Schließen des Ko-Prozesses '%s' fehlt."
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "Das explizite Schließen der Pipe '%s' fehlt."
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "Das explizite Schließen der Datei '%s' fehlt."
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "Fehler beim Schreiben auf stdout (%s)."
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "Fehler beim Schreiben auf stderr (%s)."
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "Leeren der Pipe '%s' gescheitert (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "Ko-Prozess: Leeren der Pipe zu '%s' gescheitert (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "Flush der Datei '%s' gescheitert (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "/inet/raw Client noch nicht fertig."
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "Nur root darf '/inet/raw' benutzen"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "'/inet/raw'-Server noch nicht fertig."
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "Kein bekanntes Protokoll in Dateinamen '%s' angegeben."
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "Dateiname '%s' ist unvollständig."
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "Lokaler Port in '%s' ist ungültig."
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "Sie müssen einen Rechnernamen in '/inet' angeben."
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "Sie müssen einen Port in '/inet' angeben."
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "Port-Angabe in '%s' ist ungültig."
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP-Verbindungen sind nicht möglich."
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "Datei '%s' ist ein Verzeichnis."
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "Benutzen Sie 'PROCINFO[\"%s\"]' statt '%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "Benutzen Sie 'PROCINFO[...] statt '/dev/user'."
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "Konnte '%s' nicht öffnen, Mode '%s'."
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "Schließen der Pipe gescheitert (%s)."
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "Schließen von stdout in Kindprozess gescheitert (%s)."
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "Verschieben der Pipe zu stdout in Kindprozess gescheitert (dup: %s)."
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "Schließen von stdin im Kindprozess gescheitert (%s)."
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "Verschieben der Pipe zu stdin in Kindprozess gescheitert (dup: %s)."
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "Schließen der Pipe gescheitert (%s)."
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "Verschieben der Pipe zu stdout in Kindprozess gescheitert (dup: %s)."
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "Verschieben der Pipe zu stdin in Kindprozess gescheitert (dup: %s)."
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr ""
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr ""
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "Schließen der Pipe gescheitert (%s)."
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "'|&' nicht möglich."
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "Kann Pipe '%s' nicht öffnen (%s)."
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "Kann Kindprozess für '%s' nicht erzeugen (fork: %s)."
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "Datei '%s' ist leer."
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "Fehler beim Lesen der Eingabedatei '%s': %s."
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "Multicharacter-Wert von 'RS' ist eine gawk-Erweiterung."
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "Option '-m[fr]' ist in gawk bedeutungslos."
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "Anwendung der Option -m: '-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: Option '-W %s' unbekannt, ignoriert.\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "Leeres Argument für '--source' ignoriert."
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"Umgebungsvariable 'POSIXLY_CORRECT' ist gesetzt: '--posix' angeschaltet."
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "'--posix' hat Vorrang vor '--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "'--posix' /'--traditional' hat Vorrang vor '--non-decimal-data'."
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "%s als setuid root auszuführen, kann zu Sicherheitsproblemen führen."
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "Kann Mode für stdin nicht setzen (%s)."
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "Kann Mode für stdout nicht setzen (%s)."
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "Kann Mode für stderr nicht setzen (%s)."
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "Kein Programmtext."
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Anwendung: %s [POSIX- oder GNU-Optionen] -f PROGRAM [--] Datei ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Anwendung: %s [POSIX- oder GNU-Optionen] -- %cPROGRAM%c Datei ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "POSIX-Optionen\t\tGNU-Optionen (lang):\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f PROGRAM\t\t--file=PROGRAM\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F Feldtrenner\t\t\t--field-separator=Feldtrenner\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=Wert\t\t--assign=var=Wert\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] Wert\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=Datei]\t--dump-variables[=Datei]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=Datei]\t--profile[=Datei]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=Datei]\t--profile[=Datei]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=Programmtext\t--source=Programmtext\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"den Sie im Kapitel 'Reporting Problems and Bugs' in der \n"
+"gedruckten Version finden.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-2001 Free Software Foundation.\n"
+"\n"
+"Dieses Programm ist Freie Software. Sie können es unter den Bedingungen\n"
+"der von der Free Software Foundation veröffentlichten GNU \n"
+"General Public License weitergeben und/oder ändern.\n"
+"Es gilt Version 2 dieser Lizenz oder (nach Ihrer Wahl) irgendeine\n"
+"spätere Version.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Sie sollten eine Kopie der GNU General Publice License zusammen mit\n"
+"diesem Programm erhalten haben. Wenn nicht, schreiben Sie an die Free \n"
+"Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02111-"
+"1307, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft setzt FS im POSIX-awk nicht auf Tab."
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "Floating point exception"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "Fataler Fehler: interner Fehler"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "Kein geöffneter Dateideskriptor %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "Konnte /dev/null nicht für Dateideskriptor %d öffnen."
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "Konnte Gruppen nicht finden: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "Kommandozeile:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "Warnung: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "Fehler: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "Fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "Kann String nicht in Gleitkommazahl konvertieren."
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "Backslash am String-Ende."
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX erlabut keine '\\x'-Escapes."
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "Keine Hex-Ziffern in '\\x'-Escape."
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "Escape-Sequenz '\\%c' als '%c' behandelt."
+
+#: posix/gawkmisc.c:172
+#, fuzzy, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s '%s': Konnte close-on-exec nicht setzen: %s"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "Konnte '%s' nicht zum Schreiben öffnen: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "Interner Fehler: Node_var with null vname."
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawk-Profil, erzeugt %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN block(s)\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Rule(s)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END block(s)\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Functionen, alphabetisch sortiert\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "Unerwarteter Typ %s in prec_level."
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Erfolg"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Kein Treffer"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Ungültiger Regulärer Ausdruck."
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Ungültiges Zeichen."
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Ungültier Name für Zeichenklasse."
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Angehängter Backslash"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Ungültige Referenze"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ oder [^ nicht geschlossen"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( oder \\( nicht geschlossen"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ nicht geschlossen"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Ungültiger Inhalt von \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Ungültiges Bereichsende"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Kein Speicher mehr."
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Vorangehender Regulärer Ausdruck ist ungültig."
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Vorzeitiges Ende des Regulären Ausdrucks."
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Regulärer Ausdruck zu groß."
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") oder \\) nicht geöffnet"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Kein vorangehender Regulärer Ausdruck."
+
+#~ msgid "function %s called\n"
+#~ msgstr "Funktion %s aufgerufen\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "Feld %d in FIELDWIDTHS muss > 0 sein."
+
+#, fuzzy
+#~ msgid "or used as a variable or an array"
+#~ msgstr "Kann Funktion '%s' nicht als Variable oder Array verwenden."
+
+#, fuzzy
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: Länge %g ist kleiner oder gleich 0."
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: Benutzung der Variablen »%s« als Array ist nicht zulässig."
+
+#, fuzzy
+#~ msgid "%s: gvar_ref to %s\n"
+#~ msgstr "%s: Array-Referenz auf %s\n"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: Erstes Argument ist kein Array."
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: Zweites Argument ist kein array."
+
+#, fuzzy
+#~ msgid ""
+#~ "attempt to use array parameter `%s' that was passed from global scalar `%"
+#~ "s'"
+#~ msgstr "Versuch den skalaren Parameter '%s' als Array zu benutzen."
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "Interner Fehler: Node_var_array with null vname."
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "BEGIN-Blöcke müssen einen Aktionsteil haben."
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "'nextfile' in BEGIN- oder END-Aktion benutzt."
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "Der dritte Parameter von gsub ist ein unveränderliches Objekt."
+
+#~ msgid "or used in other expression context"
+#~ msgstr "or in anderem Kontext benutzt"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "'%s' ist eine Funktion, Zuweisungen sind nicht erlaubt."
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "Interner Fehler: Datei '%s', Zeile %d\n"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "Nicht-umgelenktes 'getline' ist innerhalb der BEGIN- und END-Aktion nicht "
+#~ "definiert."
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x nicht in tokentab\n"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ wird nicht geschlossen."
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Nicht-beendetes \\\\-Escape."
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "Nicht-beendeter Wiederholungszähler."
+
+#~ msgid "malformed repeat count"
+#~ msgstr "Fehlerhafter Wiederholungszähler."
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( wird nicht geschlossen."
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Kein Regulärer Ausdruck angegeben."
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") wird nicht geöffnet."
+
+#~ msgid "out of memory"
+#~ msgstr "Kein Speicher mehr."
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "Ungültige Syntax im Namen '%s' für Variablenzuweisung."
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Um Fehler zu melden, lesen Sie bitte den Abschnitt 'Bugs' in "
+#~ "'gawk_info',\n"
+
+#~ msgid "pipe from `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "Pipe von '%s': Konnte close-on-exec nicht setzen (fcntl: %s)."
+
+#~ msgid "pipe to `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "Pipe zu '%s': Konnte close-on-exec nicht setzen (fcntl: %s)."
--- /dev/null
+# All this catalog "translates" are quotation characters.
+# The msgids must be ASCII and therefore cannot contain real quotation
+# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
+# and double quote (0x22). These substitutes look strange; see
+# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
+#
+# This catalog translates grave accent (0x60) and apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019).
+# It also translates pairs of apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019)
+# and pairs of quotation mark (0x22) to
+# left double quotation mark (U+201C) and right double quotation mark (U+201D).
+#
+# When output to an UTF-8 terminal, the quotation characters appear perfectly.
+# When output to an ISO-8859-1 terminal, the single quotation marks are
+# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
+# grave/acute accent (by libiconv), and the double quotation marks are
+# transliterated to 0x22.
+# When output to an ASCII terminal, the single quotation marks are
+# transliterated to apostrophes, and the double quotation marks are
+# transliterated to 0x22.
+#
+# This catalog furthermore displays the text between the quotation marks in
+# bold face, assuming the VT100/XTerm escape sequences.
+#
--- /dev/null
+# All this catalog "translates" are quotation characters.
+# The msgids must be ASCII and therefore cannot contain real quotation
+# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
+# and double quote (0x22). These substitutes look strange; see
+# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
+#
+# This catalog translates grave accent (0x60) and apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019).
+# It also translates pairs of apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019)
+# and pairs of quotation mark (0x22) to
+# left double quotation mark (U+201C) and right double quotation mark (U+201D).
+#
+# When output to an UTF-8 terminal, the quotation characters appear perfectly.
+# When output to an ISO-8859-1 terminal, the single quotation marks are
+# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
+# grave/acute accent (by libiconv), and the double quotation marks are
+# transliterated to 0x22.
+# When output to an ASCII terminal, the single quotation marks are
+# transliterated to apostrophes, and the double quotation marks are
+# transliterated to 0x22.
+#
--- /dev/null
+# Mensajes en español para gawk-3.1.4l.
+# Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2001, 2002, 2003, 2004, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-27 09:20-0500\n"
+"Last-Translator: Cristian Othón Martínez Vera <cfuga@itam.mx>\n"
+"Language-Team: Spanish <es@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "se intentó usar la función `%s' como una matriz"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "se intentó usar el parámetro escalar `%s como una matriz'"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "se intentó usar el dato escalar `%s' como una matriz"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "desde %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referencia al elemento sin valor inicial `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "el subíndice de la matriz `%s' es la cadena nula"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: el índice `%s' no está en la matriz `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: vacío (nulo)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: vacío (cero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: tamaño_tabla = %d, tamaño_matriz = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: es un parámetro\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array_ref a %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "Los bloques %s deben tener una parte de acción"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "cada regla debe tener un patrón o una parte de acción"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' es una función interna, no se puede redefinir"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"la constante de expresión regular `//' parece un comentario de C++, pero no "
+"lo es"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"la constante de expresión regular `/%s/' parece un comentario de C, pero no "
+"lo es"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "la sentencia puede no tener efecto"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "se usó `%s' en la acción %s"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' es una extensión de gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "se usó `return' fuera del contexto de la función"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"el `print' simple en la regla BEGIN o END probablemente debe ser `print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' es una extensión de gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete(array)' es una extensión de gawk que no es transportable"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "valores case duplicados en el cuerpo de un switch: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "Se detectó un `default' duplicado en el cuerpo de un switch"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "las líneas de trabajo de dos vías multiestado no funcionan"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "expresión regular del lado derecho de una asignación"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "expresión regular a la izquierda del operador `~' o `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "expresión regular a la derecha de una comparación"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "`getline' no redirigido indefinido dentro de la acción de END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "la llamada de `length' sin paréntesis no es transportable"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "la llamada de `length' sin paréntesis está obsoleta por POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "uso de una matriz que no es matriz"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "expresión de subíndice inválida"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "nueva línea o fin de la cadena inesperados"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "texto de programa vacío en la linea de comando"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "no se puede abrir el fichero fuente `%s' para lectura (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "no se puede leer el fichero fuente `%s' (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "el fichero fuente `%s' está vacío"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "el fichero fuente no termina con línea nueva"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "expresión regular sin terminar termina con `\\` al final del fichero"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"%s: %d: el modificador de expresión regular `/.../%c` de tawk no funciona en "
+"gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"el modificador de expresión regular `/.../%c` de tawk no funciona en gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "expresión regular sin terminar"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "expresión regular sin terminar al final del fichero"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "el uso de la continuación de línea `\\ #...' no es transportable"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "la barra invertida no es el último caracter en la línea"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX no permite el operador `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "el awk antiguo no da soporte al operador `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX no permite el operador `**'"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "el awk antiguo no da soporte al operador `**='"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "el operador `^=' no tiene soporte en el awk antiguo"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "el operador `^' no tiene soporte en el awk antiguo"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "cadena sin terminar"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "caracter '%c' inválido en la expresión"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' es una extensión de gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' es una extensión de Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX no permite `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' no tiene soporte en el awk antiguo"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "¡`goto' se considera dañino!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d es inválido como número de argumentos para %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: el tercer argumento es una extensión de gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: la literal de cadena como último argumento de substitute no tiene efecto"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "el tercer argumento de %s no es un objecto que se puede cambiar"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: el segundo argumento es una extensión de gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"el uso de dcgettext(_\"...\") es incorrecto: quite el subrayado inicial"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"el uso de dcngettext(_\"...\") es incorrecto: quite el subrayado inicial"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "función `%s': parámetro #%d, `%s', duplica el parámetro #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "función `%s': parámetro `%s' obscurece la variable global"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "no se puede abrir `%s' para escritura (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "enviando perfil a la salida estándar de error"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: falló close (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "¡shadow_funcs() llamada dos veces!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "hay variables opacadas."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr ""
+"función `%s': no se puede usar un nombre de función como nombre de parámetro"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "el nombre de función `%s' se definió previamente"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "se llamó a la función `%s' pero nunca se definió"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "la función `%s' está definida pero nunca se llamó"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"la constante de expresión regular para el parámetro #%d da un valor booleano"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"se llamó la función `%s' con espacio entre el nombre y el `(',\n"
+"o se usó como una variable o una matriz"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "falló %s a \"%s\" (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "salida estándar"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "razón desconocida"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: se recibió un argumento que no es un número"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: no se puede limpiar: se abrió la tubería `%s' para lectura, no para "
+"escritura"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: no se puede limpiar: se abrió el fichero `%s' para lectura, no para "
+"escritura"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' no es un fichero abierto, tubería o co-proceso"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: el primer argumento recibido no es una cadena"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: el segundo argumento recibido no es una cadena"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: se recibió un argumento que no es un número"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete array' es una extensión de gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: se recibió un argumento que no es una cadena"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: se recibió un argumento que no es un número"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: se recibió el argumento negativo %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "se debe utilizar `count$' en todos los formatos o en ninguno"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "no se permite `$' en los formatos de awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "la cuenta de argumentos con `$' debe ser > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"la cuenta de argumentos %ld es mayor que el número total de argumentos "
+"proporcionados"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "no se permite `$' después de un punto en el formato"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr ""
+"no se proporciona `$' para el ancho o la precisión del campo posicional"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' no tiene significado en los formatos de awk; ignorado"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "no se permite `l' en los formatos POSIX de awk"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' no tiene significado en los formatos de awk; ignorado"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "no se permite `L' en los formatos POSIX de awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' no tiene significado en los formatos de awk; ignorado"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "no se permite `h' en los formatos POSIX de awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: el valor %g está fuera del rango del formato `%%%c'"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "no hay suficientes argumentos para satisfacer a la cadena de formato"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "se acabó ^ para éste"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: el especificador de formato no tiene letras de control"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "se proporcionaron demasiados argumentos para la cadena de formato"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: sin argumentos"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: se recibió un argumento que no es un número"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: llamado con el argumento negativo %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: el índice de inicio %g es inválido, usando 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: el índice de inicio no entero %g será truncado"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: la longitud %g no es >= 1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: la longitud %g no es >= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: la longitud no entera %g será truncada"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+"substr: la longitud %g es demasiado grande para ser índice de cadena, se "
+"trunca a %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: la cadena de origen es de longitud cero"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: el índice de inicio %g está después del fin de la cadena"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: la cadena %g en el índice de inicio %g excede la longitud del primer "
+"argumento (%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: el primer argumento recibido no es una cadena"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: se recibió una cadena de formato vacía"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: el segundo argumento recibido no es un número"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: se recibió un argumento que no es una cadena"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: se recibió un argumento que no es una cadena"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referencia al campo sin inicializar `$%d'"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: se recibió un argumento que no es una cadena"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: se recibió un argumento que no es una cadena"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: el primer argumento recibido no es un número"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: el segundo argumento recibido no es un número"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: se recibió un argumento que no es un número"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: se recibió un argumento que no es un número"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: se recibió un argumento que no es un número"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: el tercer argumento no es una matriz"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: el tercer argumento de 0 se trata como 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: el primer argumento recibido no es un número"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: el segundo argumento recibido no es un número"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): un valor de desplazamiento muy grande dará resultados "
+"extraños"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: el primer argumento recibido no es un número"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: el segundo argumento recibido no es un número"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): un valor de desplazamiento muy grande dará resultados "
+"extraños"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: el primer argumento recibido no es un número"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: el segundo argumento recibido no es un número"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: el primer argumento recibido no es un número"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: el segundo argumento recibido no es un número"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: el primer argumento recibido no es un número"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: el segundo argumento recibido no es un número"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: se recibió un argumento que no es un número"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): el valor fraccionario será truncado"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' no es una categoría local válida"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "tipo de nodo %d desconocido"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "desbordamiento de almacenamiento temporal en genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "se intentó usar la matriz `%s' en un contexto escalar"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"ciclo for: la matriz `%s' cambió de tamaño de %ld a %ld durante la ejecución "
+"del ciclo"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "`break' fuera de un ciclo no es transportable"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "no se permite `break' fuera de un ciclo"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "`continue' fuera de un ciclo no es transportable"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "no se permite `continue' fuera de un ciclo"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`next' no se puede llamar desde una regla BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "`next' no se puede llamar desde una regla END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`nextfile' no se puede llamar desde una regla BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`nextfile' no se puede llamar desde una regla END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "la sentencia no tiene efecto"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "no se puede usar el nombre de la función `%s' como variable o matriz"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referencia al argumento sin inicializar `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referencia a la variable sin inicializar `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenación: ¡Los efectos laterales en una expresión han cambiado la "
+"longitud de otra!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "se usó una asignación en un contexto condicional"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "se intentó una división por cero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "se intentó una división por cero en `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tipo ilegal (%s) en tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "se intentó una división por cero en `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "se intentó una división por cero en `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "se llamó a la función `%s' con más argumentos de los declarados"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "la función `%s' no está definida"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Pila de Llamadas de Funciones:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- principal --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "se intentó una referencia de campo desde un valor que no es un número"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "se intentó una referencia desde una cadena nula"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "se intentó accesar al campo %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "no se permite asignación como resultado de una función interna"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' es una extensión de gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' es una extensión de gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "especificación `%sFMT' `%s' errónea"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "desactivando `--lint' debido a una asignación a `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' es una extensión de gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: no se puede abrir `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"extension: biblioteca `%s': no se puede llamar a la función `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: falta el nombre de la función"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: carácter ilegal `%c' en el nombre de la función `%s'"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: no se puede redefinir la función `%s'"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: la función `%s' ya está definida"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+"extension: no se puede utilizar la orden interna de gawk `%s' como nombre de "
+"función"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: el nombre de función `%s' se definió previamente"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "la función `%s' está definida para tomar no más de %d argumento(s)"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "función `%s': falta el argumento #%d"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr ""
+"función `%s': argumento #%d: se intentó usar un escalar como una matriz"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+"función `%s': argumento #%d: se intentó usar una matriz como un escalar"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "No Se Da Soporte A La Operación"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF con un valor negativo"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: el segundo argumento no es una matriz"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr ""
+"split: la cadena nula para el tercer argumento es una extensión de gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' es una extensión gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "valor de FIELDWIDTHS inválido, cerca de `%s'"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "la cadena nula para `FS' es una extensión de gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: la opción `%s' es ambigua\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: la opción `--%s' no admite ningún argumento\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: la opción `%c%s' no admite ningún argumento\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: la opción `%s' requiere un argumento\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: no se reconoce la opción `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: no se reconoce la opción `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: opción ilegal -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: opción inválida -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: la opción requiere un argumento -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: la opción `-W %s' es ambigua\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: la opción `-W %s' no admite ningún argumento\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "no se puede abrir el fichero `%s' para lectura (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "falló al cerrar el df %d (`%s') (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "tipo de árbol %s inválido en redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "la expresión en la redirección `%s' sólo tiene un valor numérico"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "la expresión para la redirección `%s' tiene un valor de cadena nula"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"el fichero `%s' para la redirección `%s' puede ser resultado de una "
+"expresión lógica"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "mezcla innecesaria de `>' y `>>' para el fichero `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "no se puede abrir la tubería `%s' para la salida (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "no se puede abrir la tubería `%s' para la entrada (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"no se puede abrir el `socket' de dos vías `%s' para entrada/salida (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "no se puede abrir la tubería de dos vías `%s' para entrada/salida (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "no se puede redirigir desde `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "no se puede redirigir a `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"se alcanzó el límite del sistema para ficheros abiertos: comenzando a "
+"multiplexar los descriptores de fichero"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "falló al cerrar `%s' (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "demasiadas tuberías o ficheros de entrada abiertos"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: el segundo argumento debe ser `to' o `from'"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: `%.*s' no es un fichero abierto, tubería o co-proceso"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "cerrado de una redirección que nunca fue abierta"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: la redirección `%s' no se abre con `|&', se ignoró el segundo "
+"argumento"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "estado de fallo (%d) al cerrar la tubería de `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "estado de fallo (%d) al cerrar el fichero de `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "no se provee el cerrado explícito del `socket' `%s'"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "no se provee el cerrado explícito del co-proceso `%s'"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "no se provee el cerrado explícito del la tubería `%s'"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "no se provee el cerrado explícito del fichero `%s'"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "error al escribir en la salida estándar (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "error al escribir en la salida estándar de error (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "falló la limpieza de la tubería de `%s' (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "falló la limpieza del co-proceso de la tubería a `%s' (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "falló la limpieza del fichero de `%s' (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "el cliente /inet/raw no está listo aún, perdón"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "sólo root puede utilizar `/inet/raw'."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "el servidor /inet/raw no está listo aún, perdón"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+"no se proporciona algún protocolo (conocido) en el nombre de fichero "
+"especial `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "el nombre de fichero especial `%s' está incompleto"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "puerto local inválido en `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "se debe proporcionar a `/inet' un nombre de anfitrión remoto"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "se debe proporcionar a `/inet' un puerto remoto"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "puerto remoto inválido en `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "No tienen soporte las comunicaciones TCP/IP"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "el fichero `%s' es un directorio"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "use `PROCINFO[\"%s\"]' en lugar de `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "use `PROCINFO[...]' en lugar de `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "no se puede abrir `%s', modo `%s'"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "falló al cerrar el pty maestro (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "falló al cerrar la salida estándar en el hijo (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"falló el movimiento del pty esclavo a la salida estándar en el hijo (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "falló al cerrar la entrada estándar en el hijo (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"falló el movimiento del pty esclavo a la entrada estándar en el hijo (dup: %"
+"s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "falló al cerrar el pty esclavo (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "falló el movimiento a la salida estándar en el hijo (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+"falló el movimiento de la tubería a la entrada estándar en el hijo (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "falló la restauración de la salida estándar en el proceso padre\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "falló la restauración de la entrada estándar en el proceso padre\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "falló al cerrar la tubería (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' no tiene soporte"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "no se puede abrir la tubería `%s' (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "no se puede crear el proceso hijo para `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "el fichero de datos `%s' está vacío"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "no se puede reservar más memoria de entrada"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "error al leer el fichero de entrada `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "el valor multicaracter de `RS' es una extensión de gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "la opción -m[fr] es irrelevante en gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "uso de la opción -m: `-m[fr]' nnn"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: no se reconoce la opción `-W %s', se ignora\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "se ignora el argumento vacío para `--source'"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"la variable de ambiente `POSIXLY_CORRECT' está establecida: activando `--"
+"posix'"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--posix' se impone a `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--posix'/`--traditional' se imponen a `--non-decimal-data'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "ejecutar %s como setuid root puede ser un problema de seguridad"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "no se puede establecer el modo binario en la entrada estándar (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "no se puede establecer el modo binario en la salida estándar (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr ""
+"no se puede establecer el modo binario en la salida estándar de error (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "¡No hay ningún programa de texto!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Modo de empleo: %s [opciones estilo POSIX o GNU] -f fichprog [--] "
+"fichero ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Modo de empleo: %s [opciones estilo POSIX o GNU] [--] %cprograma%c "
+"fichero ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Opciones POSIX:\t\tOpciones largas GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f fichprog\t\t--file=fichprog\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F sc\t\t\t--field-separator=sc\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=valor\t\t--assign=var=valor\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] valor\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fichero]\t--dump-variables[=fichero]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=fichero\t\t--exec=fichero\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fichero]\t--profile[=fichero]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+# Esta es la línea más larga de la lista de argumentos.
+# Probar con gawk para revisar tabuladores. cfuga
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=texto-prog\t--source=texto-prog\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Para reportar bichos, consulte el nodo `Bugs' en `gawk.info', el cual\n"
+"corresponde a la sección `Reporting Problems and Bugs' en la versión "
+"impresa.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk es un lenguaje de reconocimiento y procesamiento de patrones.\n"
+"Por omisión lee la entrada estándar y escribe en la salida estándar.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Ejemplos:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' fichero\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Este programa es software libre; puede redistribuirse y/o ser modificado\n"
+"bajo los términos de la Licencia Pública General de GNU tal como es "
+"publicada\n"
+"por la Free Software Foundation; ya sea por la versión 2 de la Licencia, o\n"
+"(a su elección) cualquier versión posterior.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Este programa se distribuye con la esperanza que será útil,\n"
+"pero SIN NINGUNA GARANTÍA; aún sin la garantía implícita de\n"
+"COMERCIABILIDAD o IDONEIDAD PARA UN FIN DETERMINADO. Vea la\n"
+"Licencia Pública General de GNU para más detalles.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Debió haber recibido una copia de la Licencia Pública General de GNU\n"
+"junto con este programa; si no es así, escriba a la Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Quinto Piso, Boston, MA 02110-1301, "
+"USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft no establece FS a tabulador en el awk de POSIX"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: el argumento `%s' para `-v' no es de la forma `var=valor'\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' no es un nombre de variable legal"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' no es un nombre de variable, se busca el fichero `%s=%s'"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "excepción de coma flotante"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "error fatal: error interno"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "no existe el df %d abierto previamente"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "no se puede abrir previamente /dev/null para el df %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "no se pueden encontrar los grupos: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "línea ord.:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "aviso: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "error: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "no se puede convertir una cadena a coma flotante"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "barra invertida al final de la cadena"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX no permite escapes `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "no hay dígitos hexadecimales en la secuencia de escape `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "la secuencia de escape `\\%c' tratada como una simple `%c'"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': no se puede establecer close-on-exec: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "no se puede abrir `%s' para escritura: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "error interno: %s con vname nulo"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# se trata internamente como `delete'"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# esta es una función de extensión cargada dinámicamente"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# perfil de gawk, creado %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# bloque(s) BEGIN\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regla(s)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# bloque(s) END\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funciones, enumeradas alfabéticamente\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "tipo %s inesperado en prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Éxito"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "No hay coincidencia"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Expresión regular inválida"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Caracter de ordenación inválido"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nombre de clase de caracter inválido"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Barra invertida extra al final"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Referencia hacia atrás inválida"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ o [^ desemparejados"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( o \\( desemparejados"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ desemparejado"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Contenido inválido de \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Final de rango inválido"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Memoria agotada"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Expresión regular precedente inválida"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Fin prematuro de la expresión regular"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "La expresión regular es demasiado grande"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") o \\) desemparejados"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "No hay una expresión regular previa"
+
+#~ msgid "function %s called\n"
+#~ msgstr "se llamó a la función %s\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "el campo %d en FIELDWIDTHS, debe ser > 0"
+
+#~ msgid "or used as a variable or an array"
+#~ msgstr "o se usó como una variable o una matriz"
+
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: la longitud %g es < 0"
+
+#~ msgid "regex match failed, not enough memory to match string \"%.*s%s\""
+#~ msgstr ""
+#~ "falló la coincidencia de la expresión regular, no hay suficiente memoria "
+#~ "para que coincida la cadena \"%.*s%s\""
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: uso ilegal de la variable `%s' como una matriz"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: el primer argumento no es una matriz"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: el segundo argumento no es una matriz"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "error interno: Node_var_array con vname nulo"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "sintaxis inválida en el nombre `%s' para la asignación de variable"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "se usó or en otro contexto de la expresión"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "`%s' es una función, no se permite asignación"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Los bloques BEGIN deben tener una parte de acción"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "`nextfile' es usado en la acción de BEGIN o END"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "`getline' no redirigido indefinido dentro de la acción de BEGIN o END"
+
+# tokentab? cfuga
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x no está en tokentab\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "el tercer argumento de gsub no es un objecto que se puede cambiar"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ desbalanceado"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Escape \\ sin terminar"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "cuenta de repetición sin terminar"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "cuenta de repetición malformada"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( desbalanceado"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "No se especifican los bits de sintaxis de la expresión regular"
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") desbalanceado"
+
+#~ msgid "out of memory"
+#~ msgstr "memoria agotada"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "error interno: fichero `%s', línea %d\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Para reportar `bugs', vea el nodo `Bugs' en gawk.info, que es\n"
+
+#~ msgid "pipe from `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "tubería de `%s': no se puede establecer close-on-exec (fcntl: %s)"
+
+#~ msgid "pipe to `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "tubería a `%s': no se puede establecer close-on-exec (fcntl: %s)"
--- /dev/null
+# Messages français pour gawk.
+# Copyright © 2004 Free Software Foundation, Inc.
+# Michel Robitaille <robitail@IRO.UMontreal.CA>, 1996.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-29 08:00-0500\n"
+"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
+"Language-Team: French <traduc@traduc.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "tentative d'utilisation de la fonction « %s » comme un tableau"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr ""
+"tentative d'utilisation d'un paramètre scalaire « %s » comme un tableau"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "tentative d'utilisation du scalaire « %s » comme un tableau"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "à partir de %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "référence à un élément non initialisé « %s[\"%s\"] »"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "sous-description du tableau « %s » contient une chaîne nulle"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "destruction: index « %s » n'est pas dans le tableau « %s »"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: vide (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: vide (zéro)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: est un paramètre\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array_ref de %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "Les blocs %s doivent avoir une partie action"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "chaqque règle doit avoir un patron ou une partie action"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "« %s » est une fonction interne, elle ne peut être redéfinie"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"la constante d'expression régulière « // » ressemble à un commentaire en C, "
+"mais ne l'est pas"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"la constante d'expression régulière « /%s/ » ressemble à un commentaire en "
+"C, mais ne l'est pas"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "la déclaration peut n'avoir aucun effet"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "« %s » utilisé dans l'action %s"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "« nextfile » est une extension de gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "« return » utilisé en dehors du contexte d'une fonction"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"utilisation de « print » dans une règle BEGIN ou END doit être probablement "
+"« print \"\" »"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "« delete array » est une extension de gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "« delete(array) » est une extension de tawk qui n'est pas portable"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "duplicata de valeur de case dans le corps du switch: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "duplicata de « default » détecté dans le corps du switch"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "pipelines bidirectionnel à multi-étapes ne fonctionnent pas"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "expression régulière à la droite de l'affectation"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "expression régulière sur la gauche de l'opérateur « ~ » ou « !~ »"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "expression régulière sur la droite de la comparaison"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "« getline » non redirigé indéfini à l'intérieur de l'action END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "l'appel de « length » sans les parenthèses n'est pas portable"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "l'appel de « length » sans les parenthèses est déprécié par POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "utilisation d'une entité qui n'est pas un tableau comme tableau"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "sous-expression invalide"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "nouvelle ligne inattendue ou fin de la chaîne"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "texte du programme sur la ligne de commande est vide"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "ne peut ouvrir le fichier source « %s » pour lecture (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "ne peut lire le fichier source « %s » (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "fichier source « %s » est vide"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "fichier source ne se termine pas par un retour de chariot"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+"expression régulière non termineé se terminant par « \\ » à la fin du fichier"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"%s: %d: modificateur d'exp. rég. tawk `/.../%c' ne peut opérer dans gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "modificateur d'exp. rég. tawk `/.../%c' ne peut opérer dans gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "expression régulière non terminée"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "expression régulière non terminée à la fin du fichier"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr ""
+"utilisation de « \\ #... » comme continuation de ligne n'est pas portable"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "la barre oblique inverse n'est pas le dernier caractère sur la ligne"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX ne permet un opérateur « **= »"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "l'ancien awk ne supporte pas l'opérateur « **= »"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX ne permet pas l'opérateur « ** »"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "l'ancien awk ne supporte pas l'opérateur « ** »"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "l'opérateur « ^= » n'est pas supporté dans l'ancien awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "l'opérateur « ^ » n'est pas supporté dans l'ancien awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "chaîne non complétée"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "caractère invalide « %c » dans l'expression"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "« %s » est une extension de gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "« %s » est une extension de Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX ne permet pas « %s »"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "« %s » n'est pas supporté dans l'ancien awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "« goto » considéré néfaste!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d est invalide comme nombre d'arguments pour %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: 3e argument est une extension de gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: la chaîne litérale comme dernier arguement d'une substitution n'a aucun "
+"effet"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "3e paramètre %s n'est pas un objet interchangeable"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: 2e argument est une extension de gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"utilisation de dcgettext(_\"...\") est incorrect: enlever les soulignés en "
+"en-tête"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"utilisation de dcngettext(_\"...\") est incorrect: enlever les soulignés en "
+"en-tête"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "fonction « %s »: paramètre #%d, « %s » est un double du paramètre #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "fonction « %s »: paramètre « %s » porte ombrage à la variable globale"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "ne peut ourvrir « %s » en écriture (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "redirection du profile vers stderr"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: échec de fermeture (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadows_funcs() appelé deux fois!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "il y avait des variables ombragées"
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "fonction « %s »: ne peut utilise le nom de la fonction comme paramètre"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nom de la fonction « %s » définie précédemment"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "fonction « %s » appelé mais jamais définie"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "fonction « %s » définie mais jamais utilisée"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"expression régulière constante pour le paramètre #%d conduit à une valeur "
+"booléenne"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"fonction « %s » appelée avec un espace entre le nom et « ( »,\n"
+"ou utilisé comme variable ou comme un tableau"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s vers « %s » échec (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "sortie standard"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "raison inconnue"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: argument n'est pas numérique"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argument %g est hors limite"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: ne peut vider: le pipe « %s » est oouvert en lecture, pas en écriture"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: ne peut vider: fichier « %s » ouvert en lecture, pas en écriture"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr ""
+"fflush: « %s » n'est pas ni un fichier ouvert, un pipe ou un co-processus"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: premier argument n'est pas une chaîne"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: second argument n'est pas une chaîne"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: argument n'est pas numérique"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "« delete array » est une extension de gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: argument n'est pas une chaîne"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: argument n'est pas numérique"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: argument négatif %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "doit utiliser « count$ » sur tous les formats ou aucun"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "« $ » n'est pas permis dans les formats awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "décompte d'arguments avec « $ » doit être > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "compteur d'arguments %ld est > que le nombre total d'arguments fournis"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "« $ » n'est pas permis après le point"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "aucun « $ » fourni dans le champ positionnel (longueur ou précision)"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "« l » n'a aucun sens dans les formats de awk; ignoré"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "« l » n'est pas permis dans les format POSIX de awk"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "« L » n'a aucun sens dans les formats s de awk; ignoré"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "« L » n'est pas permis dans les formats POSIX de awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "« h » n'a aucun send dans les formats de awk; ignoré"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "« h » n'est pas permis dans les formats POSIX de awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: valeur %g est hors limite pour le format « %%%c »"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "pas assez d'arguments pour satisfaire le format d'une chaîne"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ débordement pour celle-ci"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr ""
+"[s]printf: spécificateur de format ne contient pas de lettre de contrôle"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "trop d'arguments pour la chaîne de format"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: aucun argument"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: argument n'est pas numérique"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: appelé avec un argument négatif %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: début de l'index %g est invalide, utilise 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: début avec un nombre non entier %g sera tronqué"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: longueur %g n'est pas >= 1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: longueur %g n'est pas >= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: longueur avec un nombre non entier %g sera tronqué"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+"substr: longueur %g trop grande pour l'indexation de chaînes, truncation à %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: chaîne de départ est de longueur zéro"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: début de l'index %g dépasse la fin de la chaîne"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: longueur %g début avec l'index %g déborde la longueur du 1er "
+"arguement (%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftim: premier argument reçu n'est pas une chaîne"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: chaîne de format vide"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: second argument reçu n'est pas numérique"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: argument n'est pas une chaîne"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: argument reçu n'est pas une chaîne"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "référence à un champ non initialisé « $%d »"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: argument reçu n'est pas une chaîne"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: argument reçu n'est pas une chaîne"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: premier argument n'est pas numérique"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: second argument n'est pas numérique"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: argument n'est pas numérique"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: argument n'est pas numérique"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: argument n'est pas numérique"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: le 3e argument n'est pas un tableau"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: le 3e argument de 0 traité comme un 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: premier argument n'est pas numérique"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: second argument reçu n'est pas numérique"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): trop grand déplacement donnera d'étranges résultats"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: premier argument n'est pas numérique"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: second argument reçu n'est pas numérique"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): trop grand déplacement donnera d'étranges résultats"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: premier argument n'est pas numérique"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: second argument reçu n'est pas numérique"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: premier argument n'est pas numérique"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: second argument reçu n'est pas numérique"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: premier argument n'est pas numérique"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: second argument reçu n'est pas numérique"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: argument n'est pas numérique"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): valeurs négatives donneront d'étranges résultats"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): valeurs fractionnaires seront tronquées"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: « %s » n'est pas dans un catégorie de localisation valide"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "type de noeud inconnu %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "débordement de tampo dans genflag2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "tentative d'utilisation du tableau « %s » dans un contexte scalaire"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for loop: tableau « %s » a changé de taille de %ld à %ld durant l'exécution "
+"de la boucle"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "« break » en dehors de la boucle n'est pas portable"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "« break » en dehors de la boucle n'est pas permis"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "« continue » en dehors de la boucle n'est pas portable"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "« continue » en dehors de la boucle n'est pas permis"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "« next » ne peut être appelé depuis une règle BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "« next » ne peut être appelé depuis une règle END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "« nextfile » ne peut être appelé depuis une règle BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "« nextfile » ne peut être appelé depuis une règle END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "la déclaration n'a aucun effet"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr ""
+"ne peut utiliser le nom de la fonction « %s » comme variable ou tableau"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "référence à un argument non initialisé « %s »"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "référence à une variable non initialisée « %s »"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concaténation: effects de bord dans une expression a modifié la longueur "
+"d'une autre!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "affectation utilisé dans un contexte conditionnel"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "tentative de division par zéro"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "tentative de division par zéro dans « %% »"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "type illégal (%s) dans tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "tentative de division par zéro dans « /= »"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "tentative de division par zéro dans « %%= »"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "fonction « %s » appelée avec plus d'arguments que déclarées"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "fonction « %s » non définie"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Appel d'une fonction sur la pile:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "#t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "tentative de référence un champ à partir d'une valeur non numérique"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "tentative de référence à partir d'une chaîne nulle"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "tentative d'accès du champ %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr ""
+"l'affectation n'est pas permise pour obtenir un résultat d'une fonction "
+"interne"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "« IGNORECASE » est une extension de gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "« BINMODE » est une extension de gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "« %sFMT » spécification erronée « %s »"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "désactivation « --lint » en raison d'une affectation à « LINT »"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "« extension » est une extension de gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: ne peut ouvrir « %s » (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: librairie « %s »: ne peut appeler la fonction « %s » (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: nom de fonction manquant"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: caractère illégal « %c » dans le nom de la fonction « %s »"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: ne peut redéfinir la fonction « %s »"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: fonction « %s » est déjà définie"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+"extension: ne peut utilisé la fonction interne gawk « %s » comme nom de "
+"fonction"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: nom de la fonction « %s » définie précédemment"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr ""
+"fonction « %s » est définie pour ne prendre pas plus de « %d » argument(s)"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "fonction « %s »: argument #%d manquant"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr ""
+"fonction « %s »: argument #%d: tentative d'utilisation du scalaire comme un "
+"tableau"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+"fonction « %s »: argument #%d: tentative d'utiliser un tableau comme un "
+"scalaire"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Opération non supportée"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF initialisé avec une valeur négative"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: 2e argument n'est pas un tableau"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: chaîne vide pour le 3e argument est une extension de gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "« FIELDWIDTHS » est une extension de gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "valeur de FIELDWIDTHS invalide, près de `%s'"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "chaîne vide pour « FS » est une extension de gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: option « %s » est ambiguë\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: option « --%s » n'admet pas d'arguement\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: l'option « %c%s » ne requiert pas d'arguement\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: l'option « %s » requiert un argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: option non reconnue « --%s »\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: option non reconnue « %c%s »\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: option illégale -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: option invalide -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: l'option requiert un arguement -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: l'option « -W %s » est ambiguë\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: l'option « -W %s » ne requiert pas d'arguement\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "ne peut ouvrir le fichier « %s » en lecture (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "fermeture de fd %d (« %s ») en échec (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "type d'arbre invalide %s dans redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr ""
+"l'expression de la redirection de « %s » a seulement une valeur numérique"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr ""
+"l'expression de la redirection de « %s » a une valeur nulle pour la chaîne"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"nom de fichier « %s » pour le redirection « %s » peut être le résultat d'une "
+"expression logique"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "mélange non nécessaire de « > » et de « >> » pour le fichier « %.*s »"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "ne peut ouvrir un pipe « %s » en sortie (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "ne peut ouvrir un pipe « %s » en entrée (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"ne peut ouvrir un socket bidirectionnel « %s » pour les entrées/sorties (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+"ne peut ouvrir un pipe bidirectionnel « %s » pour les entrées/sorties (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "ne peut rediriger de « %s » (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "ne peut rediriger vers « %s » (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"limite système atteinte pour l'ouverture des fichiers: début du multiplexage "
+"des descripteurs de fichiers"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "fermeture de « %s » en échec (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "trop de pipes ou de fichiers en lecture ouverts"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: 2e argument doit être « to » ou « from »"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: « %.*s » n'est pas ni un fichier ouvert, pipe ou co-processus"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "fermeture de la redirection qui n'a jamais été ouverte"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: redirection « %s » n'a pas été ouverte ave « |& » 2e argument ignoré"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "constat d'échec (%d) lors de la fermeture du pipe « %s » (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "constat d'échec (%d) lors de la fermeture du fichier « %s » (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "aucune fermeture explicite du socket « %s » fournie"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "aucune fermeture explicite du co-processus « %s » fournie"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "aucune fermeture explicite du pipe « %s » fournie"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "aucune fermeture explicite du fichier « %s » fournie"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "erreur lors de l'écriture vers stdout (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "erreur lors de l'écriture vers stderr (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "vidange du pipie de « %s » en échec (%s)"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "vidange du pipe par le co-processus vers « %s » en échec (%s)"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "vidange du fichier « %s » en échec (%s)"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "le client /inet/raw n'est pas encore prêt, désolé"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "seul root peut utiliser « /inet/raw »"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "le serveur /inet/raw n'est pas encore prêt, désolé"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "aucun protocole (connu) fourni dans le nom de fichier spécial « %s »"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "nom spécial de fichier « %s » est incomplet"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "port local invalide dans « %s »"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "un nom de hôte distant doit être fourni à « /inet »"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "un port distant doit être fournis à « /inet »"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "port distant invalide dans « %s »"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "les communications TCP/IP ne sont pas supportées"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "le fichier « %s » est un répertoire"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "utliser « PROCINFO[\"%s\"] » au lieu de « %s »"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "utliser « PROCINFO[\"%s\"] » au lieu de « /dev/user »"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "ne peut ouvrir « %s », mode « %s »"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "échec de la fermeture du pty maître (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "échec de fermeture de stdout du processus fils (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"échec de redirection de pty esclave vers stdout du processus fils (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "échec de fermeture de stdin du processus fils (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"échec de redirection du pty esclave vers stdin du processus fils (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "échec de la fermeture du pty esclave (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "échec de redirection du pipe vers stdout du processus fils (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "échec de redirection du pipe vers stdin du processus fils (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "restauration de stdout par le processus parent a échoué\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "restauration de stdin par le processus parent a échoué\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "échec de la fermeture du pipe (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "« |& » non supporté"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "ne ouvrir un pipe « %s » (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "ne créer le processus fils pour « %s » (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "le fichier de données « %s » est vide"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "ne peut allouer plus de mémoire pour l'entrée"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "erreur lors de la lecture du fichier source « %s »: %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "valeur de « RS » avec multiple caractères est une extension gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "« -m[fr] » est une option non pertinente en gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m usage de l'option: « -m[fr] nnn »"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: l'option « -W %s » n'est pas reconnue, ignorée\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "argument vide à l'option « --source », ignorée"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"variable d'environnement « POSIXLY__CORRECT » initialisée: utilisation de « "
+"--posix »"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "« --posix » écrase « --traditional »"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "« --posix »/« --traditional » écrase « --non-decimal-data »"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr ""
+"exécution de %s en mode setuid root peut causer un problème de sécurité"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "ne peut initialiser le mode binaire sur stdin (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "ne peut initialiser le mode binaire sur stdout (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "ne peut initialiser le mode binaire sur stderr (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "aucun programme!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Usage: %s [style des options POSIX ou GNU] -f fichierprog [--] fichier ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Usage: %s [style des options POSIX ou GNU] [--] %cprogram%c fichier ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Options POSIX:\t\toptions de long format GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f fichierprog\t\t--file=fichierprog\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "#t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "#t-v var=valeur\t\t--assign=var=valeur\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] valeur\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fichier]\t--dump-variables[=fichier]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=fichier\t\t--exec=fichier\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fichier]\t--profile[=fichier]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=program-text\t--source=program-text\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Pour rapporter une anomalies, voir la section « Bugs » dans « gawk.info » de "
+"la section\n"
+"« Problems and Bugs » dans la version imprimée.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk est un langage de gtraitement et de scrutation de patrons de chaînes.\n"
+"Par défaut, il lit de l'entrée standard et écrit sur la sortie standard.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Exemples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright © 1998, 1991-%d Free Software Foundation, Inc.\n"
+"\n"
+"Ce programme est un logiciel libre; vous pouvez le redistribuer ou le\n"
+"modifier selon les termes de la License Publique Générale de GNU, publiée\n"
+"par la Free Software Foundation; soit la version 2 de la Licence ou,\n"
+"soit (selon vos préférences) toute version ultérieure.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Ce logiciel est distribué en espérant qu'il soit utile,\n"
+"mais sans AUCUNE garantie; sans la garantie liée à des raisons\n"
+"COMMERCIALES ou pour RÉPONDRE À UN BESOIN PARTICULIER.\n"
+"selon les termes de la « GNU General Public License ».\n"
+"Pour plus d'informations à ce sujet, consulter la « GNU General Public "
+"License ».\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Vous devriez avoir reçu copie de la Licence Publique Générale de GNU\n"
+"avec ce programme; sinon, sinon écrire à la Free Software Foundation, Inc.,\n"
+"51 Franklin Street, FIth Floor, Boston, MA 02110-1301, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr ""
+"-Ft ne permet pas d'initialiser FS à un tabulateur dans la version POSIX de "
+"awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: « %s » argument pour « -v » n'utilise pas la formulation « var=valeur »\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "« %s » n'est pas un nom légal de variable"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "« %s » n'est pas un nom de variable, recherche du fichier « %s=%s »"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "exception de la virgule flottante"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "erreur fatale: erreur interne"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "aucun fd pré-ouvert pour %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "ne peut pré-ouvrir /dev/null pour le descripteud fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "n'a pu trouvé les groupes: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "cmd. ligne:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "AVERTISSEMENT:"
+
+#: msg.c:142
+msgid "error: "
+msgstr "Erreur: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "Fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "ne peut convertir la chaîne en nombre flottant"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "barre oblique inverse à la fin de la chaîne"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX ne permet pas de séquence d'échappement « \\x »"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "aucun chiffre hexadécimal dans la séquence d'échappement « \\x » "
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "séquence d'échappement « \\%c » traitée simplement comme « %c »"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s « %s »: ne peut initialiser close-on-exec: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "ne peut ouvrir « %s » en écriture: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "erreur interne: %s avec un vname nul"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# traité de manière interne comme « delete »"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# cela est un extension d'une fonction chargée dynamiquement"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# profile gawk, créé %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"#t# DÉBUT de bloc(s)\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Règle(s)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# FIN de bloc(s)\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Liste alphabétique des fonctions\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "type %s inattendu dans prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Succès"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Aucune concordance"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Expression régulière invalide"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Caractère de collation invalide"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nom de classe de caractères invalide"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Barre oblique inverse de terminaison"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Mauvaise référence arrière"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Non appariement de [ ou [^"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Non appariement de ( ou \\("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Non appariement de \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Contenu invalide de \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Borne finale invalide"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Mémoire épuisée"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Expression régulière précédente invalide"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Fin prématurée de l'expression régulière"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Expression régulière trop grande"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Non appariement de ) ou \\)"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Aucune expression régulière antérieure"
+
+#~ msgid "function %s called\n"
+#~ msgstr "fonction %s appelée\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "champ %d dans FIELDWIDTHS, doit être > 0"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr ""
+#~ "destruction: utilisation illégale d'une variable « %s » comme tableau"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort(): le premier argument n'est pas dans le tableau"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort(): le scond argument n'est pas dans le tableau"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Pour rapporter une anomalie, voir « Bugs » dans « gawk.info », dans la\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "syntaxe invalide dans le nom « %s » pour l'affectation de variable"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "erreur interne: Node_var_array avec un vname nul"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "ou utilisée dans un autre contexte d'expression"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "« %s » est une fonction, l'affectation n'est pas permise"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Les blocs de DÉBUT doitvent avoir une partie action"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "« nextfile » utilisé dans l'action BEGIN ou END"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "« getline » non redirigé indéfini à l'intérieur de l'action BEGIN ou END"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x n'est pas dans la table des jetons\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "gsub: 3e paramètre n'est pas un objet interchangeable"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "séquence d'échappement \\ non terminée"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "répétition de compteur non terminé"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "compteur de répétition mal composé"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "Non appariement de ["
+
+#~ msgid "Unbalanced ("
+#~ msgstr "Non appariement de ("
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Aucune syntaxe d'expression régulière des bits fournie"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "Non appariement de )"
+
+#~ msgid "out of memory"
+#~ msgstr "Mémoire épuisée"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "erreur interne: fichier « %s », ligne %d\n"
+
+#~ msgid "pipe from `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "pipe de `%s': ne peut initialiser close-on-exec (fcntl: %s)"
+
+#~ msgid "pipe to `%s': could not set close-on-exec (fcntl: %s)"
+#~ msgstr "pipe vers «%s»: ne peut initialiser close-on-exec (fcntl: %s)"
--- /dev/null
+# Irish translations for gawk.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Kevin Patrick Scannell <scannell@SLU.EDU>, 2004.
+# Peadar Ó Guilín <peadarog@oceanfree.net>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.31\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-01-03 13:47-0500\n"
+"Last-Translator: Peadar Ó Guilín <peadarog@oceanfree.net>\n"
+"Language-Team: Irish <ga@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "iarracht feidhm `%s' a úsáid mar eagar"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "iarracht paraiméadar scálach `%s' a úsáid mar eagar"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "iarracht scálach '%s' a úsáid mar eagar"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s ( ó %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "tagairt do eilimint gan túsú `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "is teaghrán folamh é foscript an eagair `%s'"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: níl innéacs `%s' san eagar `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: folamh (neamhní)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: folamh (nialas)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: méid_tábla = %d, méid_eagair = %d\n"
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: is paraiméadar é\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: tagairt_eagair do %s\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "tá gá le páirt gníomhach ag blocanna CRÍOCH"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "tá gá le páirt gníomhach ag blocanna CRÍOCH"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "is feidhm insuite í `%s', ní féidir í a shainmhíneadh"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "tá cuma nóta tráchta C ar an dtairiseach `/%s/', ach ní nóta tráchta é"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "tá cuma nóta tráchta C ar an dtairiseach `/%s/', ach ní nóta tráchta é"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "seans nach mbeidh éifeacht ag an ráiteas"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "`next' á úsáid ag an gníomh TÚS nó CRÍOCH"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "is feabhsúchán gawk é `nextfile'"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' á úsáid lasmuigh den comhthéacs feidhmach"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"is dóigh gur chóir go mbeadh an gnáth `print' sa riail TÚS nó CRÍOCH "
+"scríobhtha mar `print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "is feabhsúchán gawk é `delete array'"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "is feabhsúchán gawk é `delete array'"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "ní oibríonn pílínte déthreo ilchéimeacha"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "slonn ionadaíochta ar dhéis an sannacháin"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "slonn ionadaíochta ar chlé an oibreoirí `~' nó `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "slonn ionadaíochta ar dhéis na comparáide"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "ní shannadh `getline' neamhatreoraithe lasmuigh den ghníomh CRÍOCH"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "tá glao `length' gan lúibíní doiompairtha"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "lochtaíonn POSIX glao `length' gan lúibíní"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "slonn foscripte neamhbhailí"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "líne nua gan súil"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "téacs feidhmchlár folamh ar líne na n-orduithe"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "ní féidir an comhad foinseach `%s' a oscailt chun léamh (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "ní féidir an comhad foinseach `%s' a léamh (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "comhad foinseach `%s' folamh"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "ní chríochnaíonn an comhad foinseach le líne nua"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "críochnaíonn regexp gan chríochnú le `\\' ag an gcomhadchríoch"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "slonn ionadaíochta gan críochnú"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "slonn ionadaíochta gan críochnú ag an gcomhadchríoch"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "níl úsáid `\\ #...' mar leanúint líne doiompartha"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "ní cúlslais é carachtar deireanach an líne"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "ní cheadaíonn POSIX an t-oibreoir `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "ní cheadaíonn sean awk an t-oibreoir `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "ní cheadaíonn POSIX an t-oibreoir `**='"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "ní cheadaíonn sean awk an t-oibreoir `**='"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "tá an t-oibreoir `^=' gan tacaíocht sa shean awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "tá an t-oibreoir `^' gan tacaíocht sa shean awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "teaghrán gan chríochnú"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "carachtar neamhbhailí '%c' sa slonn"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "is feabhsúchán gawk é `%s'"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "is feabhsúchán Bell Labs é `%s'"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "ní cheadaíonn POSIX `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "tá `%s' gan tacaíocht sa shean awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "deirtear go bfhuil `goto' dochrach!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d oiread argóintí neamhbhailí le haghaidh %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "meaitseáil: is feabhsúchán gawk é an tríú argóint"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: ní bhíonn aon éifeacht ag teaghrán litriúil mar arg deireanach an ionadaí"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "ní oibiacht athraitheach é an tríú paraiméadar ionadaíoch"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: is feabhsúchán gawk é an dara hargóint"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "tá úsáid dcgettext(_\"...\") mí-cheart: bain amach an chéad fhostríoc"
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "tá úsáid dcgettext(_\"...\") mí-cheart: bain amach an chéad fhostríoc"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "feidhm `%s': is cóip é paraiméadar #%d, `%s', den paraiméadar #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "feidhm `%s': leanann paraiméadar `%s' an athróg domhanda"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "níorbh fhéidir `%s' a oscailt chun scríobh (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "ag seoladh cuntas go earráid chaighdeánach"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: theip ar an dún (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "glaodh dhá uair ar shadow_funcs()!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "feidhm `%s': níl cead ainm feidhme a úsáid mar ainm paraiméadar"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "ainm feidhme `%s' sainmhínithe chéana"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "glaodh ar an bhfeidhm `%s' nach bhfuil sainithe"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "tá sainiú ag an bhfeidhm `%s' ach ní ghlaodh é"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "tagann luach Boole de bharr ón dtairiseach regexp don paraiméadar #%d"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"glaodh feidhm `%s' le spás idir ainm agus `(',\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "theip ar %s go \"%s\" (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "aschur caighdeánach"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "níl fhios an fáth"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argóint %g as raon"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr "fflush: ní dhúisófear: píopa `%s' oscailte do léamh, ní do scríobh"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr "fflush: ní dhúisófear: comhad `%s' oscailte do léamh, ní do scríobh"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: ní comhad, píopa nó comhphróiseas oscailte é `%s'"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: ní teaghrán é an chéad argóint"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: ní teaghrán é an dara hargóint"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "is feabhsúchán gawk é `delete array'"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: fuarthas argóint nach teaghrán é"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: fuarthas argóint diúltach %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "Níl `$' ceadaithe i bhformáidí awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "caithfidh áireamh na harg. le `$' bheith > 0"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "áireamh na harg. %d níos mó ná na hargóintí faighte"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "níl `$' ceadaithe i bhformáid théis punc"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "níor thugadh `$' do leithead nó beachtas an réimse ionaid"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "níl ciall ag `l' i bhformáidí awk; neamhairdithe"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "ní cheadaítear `l' i bhformáidí awk POSIX"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "níl ciall ag `L' i bhformáidí awk; neamhairdithe"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "ní cheadaítear `L' i bhformáidí awk POSIX"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "níl ciall ag `h' i bhformáidí awk; neamhairdithe"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "ní cheadaítear `h' i bhformáidí awk POSIX"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "ní leor argóintí le haghaidh an teaghráin formáide"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ imithe thar bráid don cheann seo"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: níl litir rialúcháin ag an sonraitheoir formáide"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "fuarthas an iomarca argóintí don teaghrán formáide"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: níl aon argóint"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: glaodh le argóint diúltach %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: tá tús innéacs %g neamhbhailí, ag úsáid a 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: teascófar tús neamhuimhriúil an innéacs %g"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: tá fad %g <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: tá fad %g <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "ubstr: teascófar an fad neamhuimhriúil %g"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: tá an teaghrán foinse folamh"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: tosaíonn innéacs %d théis deireadh an teaghráin"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr "substr: fad %d ag tús innéacs %d ró-fhada don chéad argóint (%d)"
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "strftime: ní teaghrán é an chéad argóint"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: fuarthas teaghrán formáide folamh"
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: fuarthas dara hargóint neamhuimhriúil"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: ní teaghrán é an argóint"
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "system: ní teaghrán é an argóint"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "tagairt do athróg nach bhfuil túsaithe `%s'"
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "tolower: ní teaghrán é an argóint"
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "toupper: ní teaghrán é an argóint"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: ní huimhir é an chéad argóint"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: ní eagar é an tríú argóint"
+
+#: builtin.c:2555
+#, fuzzy
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: 3ú argóint as 0 úsáidte mar 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: ní huimhir é an chéad argóint"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): tiocfaidh torthaí aisteacha as luachanna diúltacha"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): teascófar luachanna codánacha"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): gheobhfar torthaí aisteacha le luach iomlaoidach ró-mhór"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: ní huimhir é an chéad argóint"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): gheobhfar torthaí aisteacha le luachanna diútlacha"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): teascófar luachanna codánacha"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): gheobhfar torthaí aisteacha le luach iomlaoidach ró-mhór"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: ní huimhir é an chéad argóint"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): gheobhfar torthaí aisteacha le luachanna diútlacha"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): teascófar luachanna codánacha"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: ní huimhir é an chéad argóint"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): gheobhfar torthaí aisteacha le luachanna diútlacha"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): teascófar luachanna codánacha"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: ní huimhir é an chéad argóint"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: ní huimhir é an dara hargóint"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): gheobhfar torthaí aisteacha le luachanna diútlacha"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): teascófar luachanna codánacha"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: fuarthas argóint neamhuimhriúil"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): gheobhfar torthaí aisteacha le luachanna diútlacha"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): teascófar luachanna codánacha"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: ní catagóir logánach ceart é `%s'"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr " cineál anaithnid nóid %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "maolán thar maoil i genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "iarracht eagar `%s' a úsáid i gcomhthéacs scálach"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr "lúb for: d'athraigh méid an eagair `%s' ó %d go %d i lár na lúibe"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "níl `break' lasmuigh den lúb iniompartha"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "níl `break' lasmuigh den lúb ceadaithe"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "níl `continue' lasmuigh den lúb iniompartha"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "níl `continue' lasmuigh den lúb ceadaithe"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "ní féidir glaoigh ar `next' ó riail TÚS"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "ní féidir glaoigh ar `next' ó riail CRÍOCH"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "ní féidir glaoigh ar `nextfile' ó riail TÚS"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "ní féidir glaoigh ar `nextfile' ó riail CRÍOCH"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "níl aon éifeacht ag an ráiteas"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "ní féidir ainm feidhme `%s' a úsáid mar athróg nó eagar"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "tagairt do argóint nach bhfuil túsaithe `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "tagairt do athróg nach bhfuil túsaithe `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr "comhchaitéiniú: d'athraigh éifeachtaí sloinn amháin fad ceann eile!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "sannadh úsáidte i gcomhthéacs coinníollach"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "iarracht roinnt le nialas a dhéanamh"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "iarracht roinnt le nialas a dhéanamh i `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "cineál neamhcheadaithe (%s) i tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "iarracht roinnt le nialas a dhéanamh i `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "iarracht roinnt le nialas a dhéanamh i `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "glaodh ar fheidhm `%s' le níos mó argóintí nó mar a bhí fógartha"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "feidhm `%s' gan sainmhíniú"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Cruach an Glaoigh ar an bhFeidhm:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- príomh --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "iarracht tagairt a fháil ó luach neamhuimhriúil"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "iarracht tagairt a fháil ó theaghrán neamhnitheach"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "iarracht rochtain a dhéanamh ar réimse %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "ní féidir sannachán a dhéanamh le toradh ó feidhm insuite"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "is feabhsúchán gawk é `IGNORECASE'"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "is feabhsúchán gawk é `BINMODE'"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "droch sonraíocht`%sFMT' `%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "ag múchadh `--lint' de bharr sannachán go `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "is feabhsúchán gawk é `extension'"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: ní féidir oscailt `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: leabharlann `%s': ní féidir glaoigh ar fheidhm `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: leabharlann `%s': ní féidir glaoigh ar fheidhm `%s' (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: ní féidir oscailt `%s' (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "feidhm `%s' gan sainmhíniú"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "ainm feidhme `%s' sainmhínithe chéana"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "tá sainiú ag an bhfeidhm `%s' ach ní ghlaodh é"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "feidhm `%s' gan sainmhíniú"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "iarracht scálach '%s' a úsáid mar eagar"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Oibríocht Gan Tacaíocht"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF socraithe go luach diúltach"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "scoilt: ní eagar é an dara hargóint"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "scoilt: is feabhsúchán gawk é an teaghrán neamhnitheach don tríú arg"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "is feabhsúchán gawk é `FIELDWIDTHS'"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "is feabhsúchán gawk é an teaghrán neamhnitheach do `FS'"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: tá an rogha `%s' débhríoch\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: ní cheadaítear argóint i ndiaidh an rogha `--%s'\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: ní cheadaítear argóint i ndiaidh an rogha `%c%s'\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: ní foláir argóint don rogha `%s'\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: rogha anaithnid `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: rogha anaithnid `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: rogha neamhcheadaithe -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: rogha neamhbhailí -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: ní foláir argóint don rogha -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: Tá an rogha `-W %s' débhríoch\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: ní cheadaítear argóint i ndiaidh an rogha `-W %s'\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "ní féidir `%s' a oscailt chun é a léamh (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "dúnadh fd %d (`%s') teipthe (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "cineál crainn %s neamhbhailí san atreorú()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "níl ach luach uimhriúil ag an slonn in atreorú `%s'"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "tá luach teaghráin neamhnitheach ag an slonn in atreorú `%s'"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"seans gur toradh sloinn loighciúil é an comhadainm `%s' don atreorú `%s'"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "meascán neamhriachtanach de `>' agus `>>' do chomhad `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "ní féidir píopa `%s' a oscailt do aschur (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "ní féidir píopa `%s' a oscailt do ionchur (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "ní féidir an soicéad déthreo `%s' a oscailt do ionchur/aschur (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "ní féidir an píopa déthreo `%s' a oscailt do ionchur/aschur (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "ní féidir atreorú ó `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "ní féidir atreorú go `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"tagtha chuig teorainn córais do chomhadlanna oscailte: ag tosnú "
+"tuairisceoirí na gcomhadlann a ilphléacsadh"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "dúnadh `%s' teipthe (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "tá an iomarca píopaí nó comhadlanna ionchuir oscailte"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: tá `to' nó `from' de dhíth mar dara hargóint"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: ní comhad oscailte, píopa nó comhphróiséas é `%.*s'"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "dúnadh atreoraithe nach n-osclóadh ariamh"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: níl atreorú `%s' oscailte le `|&', rinneadh neamhaird ar an dara "
+"hargóint"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "stádas teipfhulangach (%d) ar dúnadh an phíopa `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "stádas teipfhulangach (%d) ar dúnadh an chomhaid `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "ní fhuarthas dúnadh léir an tsoicéid `%s'"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "ní fhuarthas dúnadh léir an chomhphróiseis `%s'"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "ní fhuarthas dúnadh léir an phíopa `%s'"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "ní fhuarthas dúnadh léir an chomhaid `%s'"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "earráid agus ag scríobh go haschur caighdeánach (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "earráid agus ag scríobh go hearráid caighdeánach (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "sruthladh píopa `%s' teipthe (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "sruthladh comhphróseis an phíopa go `%s' teipthe (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "sruthladh comhaid `%s' teipthe (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "tá brón orm, níl an cliant /inet/raw réidh go fóill"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "`/inet/raw' ceadaithe do root amháin."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "tá brón orm, níl an freastalaí /inet/raw ré go fóill"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "ní fhuarthas fíor phrótacal sa chomhadainm speisialta `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "níl an comhadainm speisialta `%s' iomlán"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "port logánta neamhbhailí i `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "tá ainm cianóstaigh de dhíth ag `/inet'"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "tá cianphort de dhíth ag `/inet'"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "cianphort neamhbhailí i `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "cumarsáid TCP/IP gan tacaíocht"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "ní comhadlann é an comhad `%s'"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "úsáid `PROCINFO[\"%s\"]' in ionad `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "úsáid `PROCINFO[...]' in ionad `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "níorbh fhéidir `%s' a oscailt, mód `%s'"
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "theip ar dúnadh phíopa (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "theip ar dúnadh aschuir caighdeánach i mac teipthe (%s)"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "ag bogadh píopa go haschur caighdeánach i mac teipthe (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "theip ar dúnadh ionchuir caighdeánach i mac teipthe (%s)"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "ag bogadh píopa go ionchur caighdeánach i mac teipthe (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "theip ar dúnadh phíopa (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "ag bogadh píopa go haschur caighdeánach i mac teipthe (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "ag bogadh píopa go ionchur caighdeánach i mac teipthe (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "theip ar dul ar ais go haschur caighdeánach i máthair teipthe\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "theip ar dul ar ais go ionchur caighdeánach i máthair teipthe\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "theip ar dúnadh phíopa (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' gan tacaíocht"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "ní féidir píopa `%s' a oscailt (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "ní féidir mac a dhéanamh do `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "tá comhad sonraí `%s' folamh"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "earráid ag léamh comhad aschuir `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "is feabhsúchán gawk é an luach ilcharachtar 'RS'"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "`-m[fr]' rogha neamhábhartha i ngawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "úsáid rogha -m: `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: rogha `-W %s' anaithnid, rinneadh neamhshuim air\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "rinneadh neamhshuim ar argóint folamh go `--source'"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "athróg thimpeallachta `POSIXLY_CORRECT' socraithe: ag lasadh `--posix'"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "sáraíonn `--posix' `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "sáraíonn `--posix'/`--traditional' `--non-decimal-data'"
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "seans gur neamhdhaingean é ag rith %s setuid root"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "ní féidir mód a shocrú ar stdin (%s)"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "ní féidir mód a shocrú ar stdout (%s)"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "ní féidir mód a shocrú ar stderr (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "níl aon téacs sa ríomhchlár!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Úsáid: %s [roghanna cineál POSIX nó GNU] -f clárchomhad [--] comhad ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Úsáid: %s [roghanna cineál POSIX nó GNU] [--] %críomhchlár%c comhad ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "roghanna POSIX:\t\tGNU roghanna fada:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f comhad\t\t--file=progfile\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v athróg=luach\t\t--assign=athróg=luach\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] luach\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=comhad]\t--dump-variables[=comhad]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=comhad]\t--profile[=comhad]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=comhad]\t--profile[=comhad]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=program-text\t--source=program-text\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr "sa rannán `Reporting Problems and Bugs' sa leagan faoi chló.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Is saorbhogearra an ríomhchlár seo; is féidir leat é a scaipeadh agus/nó\n"
+"a athrú de réir na gcoinníollacha den GNU General Public License mar atá\n"
+"foilsithe ag an Free Software Foundation; faoi leagan 2 den cheadúnas,\n"
+"nó (más mian leat) aon leagan níos déanaí.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Scaiptear an ríomhchlár seo le súil go mbeidh sé áisiúil,\n"
+"ach GAN AON BARÁNTA; go fiú gan an barántas intuigthe de\n"
+"INDÍOLTACHT nó FEILIÚNACHT DO FHEIDHM AR LEITH. Féach ar an\n"
+"GNU General Public License chun níos mó sonraí a fháil.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Ba chomhair go mbeifeá tar éis cóip den GNU General Public License a fháil\n"
+"in éineacht leis an ríomhchlár seo; mura bhfuair, scríobh chuig an\n"
+"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n"
+"Boston, MA 02110-1301, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "ní athraíonn -Ft FS go táb san awk POSIX"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "eisceacht snámhphointe"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "earráid marfach: earráid inmheánach"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "níl aon fd %d réamhoscailte"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "níorbh fhéidir /dev/null a réamhoscailt do fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "ní féidir na grúpaí a aimsiú: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "líne na n-orduithe:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "rabhadh: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "earráid: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "marfach: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "ní féidir teaghrán a thiontú go snámhphointe"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "cúlslais ag deireadh an teaghráin"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "ní cheadaíonn POSIX éalaithe `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "níl digití heicsidheachúlach sa seicheamh éalaithe `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "seicheamh éalaithe `\\%c' úsáidte mar ghnáth `%c'"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': níorbh fhéidir close-on-exec a shannadh: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "Níorbh fhéidir `%s' a oscailt chun scríoch ann: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "earráid inmheánach: Node_var le vname nialasacha"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# cuntas gawk, cruthaíodh %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# TÚS bloc(anna)\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Riail(eacha)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# CRÍOCH bloc(anna)\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Feidhmeanna, i liosta aibítreach\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "cineál gan súil %s i prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Bua!"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Níl a leithéid ann"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Slonn ionadaíochta neamhbhailí"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Carachtar neamhbhailí cóimheasa"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Aicme neamhbhailí charachtair"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Cúlslais ag deireadh"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Cúltagairt neamhbhailí"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ nó [^ corr"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( nó \\( corr"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ corr"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Inneachar neamhbhailí idir \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Deireadh raoin neamhbhailí"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Cuimhne ídithe"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Is neamhbhailí an slonn ionadaíochta roimhe seo"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Deireadh le slonn ionadaíochta gan choinne"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Slonn ionadaíochta rómhór"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") nó \\) corr"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Níl aon slonn ionadaíochta roimhe seo"
+
+#~ msgid "function %s called\n"
+#~ msgstr "glaodh ar fheidhm %s\n"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: úsáid neamhdhleathach na hathróige `%s' mar eagar"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: ní eagar é an chéad argóint"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: ní eagar é an dara hargóint"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Chun tuairiscí fabhtanna a sheoladh, féach ar `Bugs' sa `gawk.info', atá\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "comhréir mícheart san ainm `%s' chun athróga a shannadh"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "earráid inmheánach: Node_var_array le vname nialasacha"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "nó úsaidte i gcomhthéacs sloinn eile"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "is feidhm í `%s', ní féidir sannachán a dhéanamh"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "tá gá le páirt gníomhach ag blocanna TÚS"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "`nextfile' á úsáid ag an gníomh TÚS nó CRÍOCH"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "ní shannadh `getline' neamhatreoraithe lasmuigh den ghníomh TÚS nó CRÍOCH"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "níl fptr %x ar fáil sa tháb ceadchomharthaí\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "ní oibiacht athraitheach é an tríú paraiméadar ionadaíoch gsub"
+
+# FARF - KPS
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Seicheamh éalúcháin \\ gan chríochnú"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "Tá líon na hathráite neamhiomlán"
+
+# more precisely, "the string indicating the repeat count" is malformed -- KPS
+#~ msgid "malformed repeat count"
+#~ msgstr "Tá líon na hathráite míchumtha"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ corr"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( corr"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Níl bearta comhréire regexp sainithe"
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") corr"
+
+#~ msgid "out of memory"
+#~ msgstr "cuimhne ídithe"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "caithfidh go bhfuil réimse %d i FIELDWIDTHS > 0"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "earráid inmheánach: comhad `%s', líne %d\n"
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr ""
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr ""
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr ""
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr ""
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr ""
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr ""
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr ""
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr ""
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr ""
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr ""
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr ""
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr ""
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr ""
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr ""
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr ""
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr ""
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr ""
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr ""
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr ""
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr ""
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr ""
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr ""
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr ""
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr ""
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr ""
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr ""
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr ""
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr ""
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr ""
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr ""
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr ""
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr ""
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr ""
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr ""
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr ""
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr ""
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr ""
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr ""
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr ""
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr ""
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr ""
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr ""
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr ""
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr ""
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr ""
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr ""
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr ""
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr ""
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr ""
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr ""
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr ""
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr ""
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr ""
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr ""
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr ""
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr ""
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr ""
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr ""
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr ""
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr ""
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr ""
+
+#: builtin.c:146
+msgid "standard output"
+msgstr ""
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr ""
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr ""
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr ""
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr ""
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr ""
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:472
+msgid "`length(array)' is a gawk extension"
+msgstr ""
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr ""
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr ""
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr ""
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr ""
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr ""
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr ""
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr ""
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr ""
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr ""
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr ""
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr ""
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr ""
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr ""
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr ""
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr ""
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr ""
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr ""
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr ""
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr ""
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr ""
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr ""
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr ""
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr ""
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr ""
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr ""
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr ""
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr ""
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr ""
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr ""
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr ""
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr ""
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr ""
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr ""
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr ""
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr ""
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr ""
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr ""
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr ""
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr ""
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr ""
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr ""
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr ""
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr ""
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr ""
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr ""
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr ""
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr ""
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr ""
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr ""
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr ""
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr ""
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr ""
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr ""
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr ""
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr ""
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr ""
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr ""
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr ""
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr ""
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr ""
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr ""
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr ""
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr ""
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr ""
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr ""
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr ""
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr ""
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr ""
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr ""
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr ""
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr ""
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr ""
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr ""
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr ""
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr ""
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr ""
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr ""
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr ""
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr ""
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr ""
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr ""
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr ""
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr ""
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr ""
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr ""
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr ""
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr ""
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr ""
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr ""
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr ""
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr ""
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr ""
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr ""
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr ""
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr ""
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr ""
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr ""
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr ""
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr ""
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr ""
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr ""
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr ""
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr ""
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr ""
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr ""
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr ""
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr ""
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr ""
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr ""
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr ""
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr ""
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr ""
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr ""
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr ""
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr ""
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr ""
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr ""
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr ""
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr ""
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr ""
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr ""
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr ""
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr ""
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr ""
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr ""
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr ""
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr ""
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr ""
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr ""
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr ""
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr ""
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr ""
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr ""
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr ""
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr ""
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr ""
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr ""
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr ""
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr ""
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr ""
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr ""
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr ""
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr ""
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr ""
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr ""
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr ""
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr ""
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr ""
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr ""
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr ""
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr ""
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr ""
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr ""
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr ""
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr ""
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr ""
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr ""
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr ""
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr ""
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr ""
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr ""
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr ""
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr ""
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr ""
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr ""
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr ""
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr ""
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr ""
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr ""
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr ""
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr ""
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr ""
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr ""
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr ""
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr ""
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr ""
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr ""
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr ""
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr ""
+
+#: msg.c:120
+msgid "warning: "
+msgstr ""
+
+#: msg.c:142
+msgid "error: "
+msgstr ""
+
+#: msg.c:178
+msgid "fatal: "
+msgstr ""
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr ""
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr ""
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr ""
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr ""
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr ""
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr ""
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr ""
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr ""
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr ""
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr ""
+
+#: regcomp.c:160
+msgid "Success"
+msgstr ""
+
+#: regcomp.c:163
+msgid "No match"
+msgstr ""
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr ""
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr ""
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr ""
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr ""
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr ""
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr ""
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr ""
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr ""
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr ""
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr ""
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr ""
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr ""
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr ""
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr ""
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ""
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr ""
--- /dev/null
+# Hebrew messages for GNU Awk -*- coding: hebrew-iso-8bit -*-
+# Copyright (C) 2001 Free Software Foundation, Inc.
+# Eli Zaretskii <eliz@is.elta.co.il>, 2001, 2002.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.1a\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2002-04-28 21:46+0300\n"
+"Last-Translator: Eli Zaretskii <eliz@gnu.org>\n"
+"Language-Team: Hebrew <eliz@gnu.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "êøòîë `%s' äéö÷ðåôá ùåîéù ïåéñð"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "êøòî äéä åìéàë `%s' éøì÷ñ øèîøôá ùåîéù ïåéñð"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "êøòîë `%s' øàì÷ñá éåâù ùåîéù"
+
+# This is not translated because it cannot be reworded in Hebrew
+# without looking awkward.
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (from %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "ìçåúî åðéàù `%s[\"%s\"]' èðîìàì äééðô"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "`%s' êøòî ïééöîë ä÷éø úæåøçîá ùåîéù"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "`%s' ïééöî ìéëî åðéà `%s' êøòî :delete"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: (ñôåàî) ÷éø\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: (ä÷éø hash úìáè) ÷éø\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "øèîøô åðéä %s\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: %s-ì (array_ref) äéðôä\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "äìåòô úøãâä ìåìëì áééç END ÷åìá"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "äìåòô úøãâä ìåìëì áééç END ÷åìá"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "äúøãâä úà úåðùì ïéà ,úéðáåî äéö÷ðåô äðéä `%s'"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "äøòä åðéà êà ,C úôùá äøòä åîë äàøð `/%s/' éøìåâø éåèéá"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "äøòä åðéà êà ,C úôùá äøòä åîë äàøð `/%s/' éøìåâø éåèéá"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "úéìëú íåù äéäú àì äæ éåèéáìù ïëúé"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "END åà BEGIN ìù äìåòô úøãâäá `next'-á ùåîéù"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `nextfile'"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "äéö÷ðåô ìù èñ÷èðå÷á àìù `return'-á ùåîéù"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr "`print \"\"' úåéäì íúñä ïî êéøö END åà BEGIN éììëá èåùô `print'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `delete array'"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `delete array'"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "íéãáåò íðéà íéáìù éáåøî íééðååéë-åã íé÷éôà"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "êøò úîùä úàøåä ìù ïéîé ãöá éøìåâø éåèéá"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "`!~' åà `~' øåèøôåàì ìàîùî éøìåâø éåèéá"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "äàååùä ìù ïéîé ãöá éøìåâø éåèéá"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "END úìåòô êåúá øãâåî åðéà äééðôä àìì `getline'"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "úéìéáèøåô äðéà íééøâåñ àìì `length'-ì äàéø÷"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "POSIX ï÷úì ãåâéðá äðéä íééøâåñ àìì `length'-ì äàéø÷"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "êøòî ïééöîá éåâù øéáçú ìòá éåèéá"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "éåôö-éúìá íå÷îá äøåù óåñ"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "äãå÷ôä úøåùî äìá÷úä ä÷éø úéðëú"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "åúàéø÷ íùì `%s' øå÷î õáå÷ úçéúôá (%s) äì÷ú"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "`%s' øå÷î õáå÷î äàéø÷á (%s) äì÷ú"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "÷éø åðéä `%s' øå÷î õáå÷"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "äøåù-óåñ åúá íééúñî åðéà øå÷îä õáå÷"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "õáå÷ä óñá `\\'-á íééúñî øåîâ-éúìá éøìåâø éåèéá"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "øåîâ-éúìá éøìåâø éåèéá"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "õáå÷ä óåñá øåîâ-éúìá éøìåâø éåèéá"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "éìéáèøåô åðéà äøåù êùîäì ïîéñë `\\ #...'-á ùåîéù"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "äøåùá ïåøçà åú åðéàù êåôä ïñëåì"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "`**=' øåèøôåà äùøî åðéà POSIX"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "`**=' øåèøôåàá êîåú åðéà ïùé awk"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "`**' øåèøôåà äùøî åðéà POSIX"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "`**' øåèøôåàá êîåú åðéà ïùé awk"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "ïùé awk-á êîúð åðéà `^=' øåèøôåà"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "ïùé awk-á êîúð åðéà `^' øåèøôåà"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "äøåîâ-éúìá úæåøçî"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "éåèéáá '%c' éåâù åú"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä äðéä `%s'"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "Bell úåãáòî úñøâá awk-ì úéôéöôñ äáçøä åðéä `%s'"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "`%s' äùøî åðéà POSIX"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "ïùé awk-á êîúð åðéà `%s'"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "!òø-òâô áùçð `goto'\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "íéèðîåâøà øôñîë %d ìá÷ì ìåëé åðéà %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `match' ìù éùéìù èðîåâøà"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "úéìëú íåù äì ïéà `%s' ìù ïåøçà èðîåâøàë äòåá÷ úæåøçî"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "éåðéù-øá è÷ééáåà åðéà `sub' ìù éùéìù èðîåâøà"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `close' ìù éðù èðîåâøà"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "èðîåâøà úîã÷áù ïåúçú-ó÷î ÷ìñì ùé :dcgettext(_\"...\")-á éåâù ùåîéù"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "èðîåâøà úîã÷áù ïåúçú-ó÷î ÷ìñì ùé :dncgettext(_\"...\")-á éåâù ùåîéù"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "`%s' äéö÷ðåôá %d 'ñî øèîøôì ääæ ,`%s' ,%d 'ñî øèîøô ìù åîù"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "éìáåìâ äðúùî ìò ìéôàî `%s' äéö÷ðåôá `%s' øèîøô"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "äáéúë íùì `%s' úçéúôá (%s) äì÷ú"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "éð÷ú úåàéâù õåøòì çìùð òåöéá ìéôåøô"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "`%s' úøéâñ úòá (%s) äì÷ú"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "!íééîòô äàø÷ð shadow_funcs()"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "øèîøô íùë ùîùì ìåëé åðéà äéö÷ðåô íù :`%s' äéö÷ðåôá"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "úøãâåî øáë `%s' íùá äéö÷ðåô"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "úøãâåî äðéàù `%s' äéö÷ðåôì äàéø÷"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "úàø÷ð àì êà ,äøãâåä `%s' äéö÷ðåô"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "éðàéìåá êøò áéðî %d 'ñî øèîøôë òåá÷ éøìåâø éåèéá"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+",`(' ïéáì äîù ïéá íéçååø íò `%s' äéö÷ðåôì äàéø÷\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s é\"ò \"%s\"-ì äáéúëá (%s) äì÷ú"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "úéèøãðèñ èìô úãéçé"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "äòåãé-éúìá äáéñî"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :exp"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "øúåîä íåçúá åðéà %g èðîåâøà :exp"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr "äáéúëì àì ,äàéø÷ì çåúô `%s' ÷éôà :õöåçä ï÷åøì ïúéð àì :fflush"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr "äáéúëì àì ,äàéø÷ì çåúô `%s' õáå÷ :õöåçä ï÷åøì ïúéð àì :fflush"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "ìéá÷î êéìäú åà çåúô ÷éôà ,çåúô õáå÷ åðéà `%s' :fflush"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "úæåøçî åðéà ïåùàø èðîåâøà :index"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "úæåøçî åðéà éðù èðîåâøà :index"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :int"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `delete array'"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "úæåøçî åðéà èðîåâøà :length"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :log"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "%g éìéìù èðîåâøà íò àø÷ð :log"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "ãçà óàá åà íéèîøåôä ìëá åà øúåî `count$'-á ùåîéù"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "awk ìù íéèîøåôá ùåîéùì øåñà `$'"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "0-î ìåãâ úåéäì áééç `$' ãéì èðîåâøàä äðåî"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "íéèðîåâøàä ìù ììåëä íøôñîî ìåãâ %d èðîåâøàä äðåî"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "èîøåôá äãå÷ðä éøçà òéôåäì ìåëé åðéà `$'"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "å÷åéã åà äãù áçåø ïééöîá èðîåâøàä äðåî øåáò `$' àöîð àì"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "çðæåä ;awk ìù èîøåôá úåòîùî øñç åðéä `l'"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "POSIX éô-ìò awk ìù èîøåôá òéôåäì ìåëé åðéà `l'"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "çðæåä ;awk ìù èîøåôá úåòîùî øñç åðéä `L'"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "POSIX éô-ìò awk ìù èîøåôá òéôåäì ìåëé åðéà `L'"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "çðæåä ;awk ìù èîøåôá úåòîùî øñç åðéä `h'"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "POSIX éô-ìò awk ìù èîøåôá òéôåäì ìåëé åðéà `h'"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "èîøåôä øåáò íéèðîåâøà ÷éôñî ïéà"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ íéèðîåâøàä éì åøîâð ïàë"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "äøîää úø÷á úåà ìéëî åðéà èîøåôä :[s]printf"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "èîøåôä øåáò íéèðîåâøà éãî øúåé"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "èðîåâøà óà ïéà :printf"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :sqrt"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "%g éìéìù èðîåâøà íò àø÷ð :sqrt"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "1-á óìçåä ,éåâù åðéä %g äìçúä ïééöî :substr"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "õöå÷é ,íìù øôñî åðéàù, %g äìçúä ïééöî ìù åëøò :substr"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "0-î ìåãâ øôñî åððéà %g êøåà :substr"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "0-î ìåãâ øôñî åððéà %g êøåà :substr"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "õöå÷é ,íìù øôñî åðéàù ,%g êøåà :substr"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "ñôà êøåàá äðéä øå÷îä úæåøçî :substr"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "úæåøçîä óåñì øáòî åðéä %d äìçúä ïééöî :substr"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"%d äëøåàå %d ïééöîá äúìéçúù úæåøçî-úúì ÷éôñî åðéà (%d) úæåøçî êøåà :substr"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "úæåøçî åðéà ïåùàø èðîåâøà :strftime"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "ä÷éø èîøåô úæåøçî :strftime"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :strftime"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "úæåøçî åðéà èðîåâøà :mktime"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "úæåøçî åðéà èðîåâøà :system"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "`%s' ìçåúî-éúìá äðúùîì äéðôä"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "úæåøçî åðéà èðîåâøà :tolower"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "úæåøçî åðéà èðîåâøà :toupper"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :atan2"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :atan2"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :sin"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :cos"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :srand"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "êøòî åðéà éùéìù èðîåâøà :match"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "1-á óìçåä 0 åëøòù éùéìù èðîåâøà :gensub"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :lshift"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :strftime"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú åáéðé íééìéìù íéëøò :lshift(%lf, %lf)"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "åööå÷é íéøåáù íéëøò :lshift(%lf, %lf)"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú áéðé éãî ìåãâ äææä øåòéù :lshift(%lf, %lf)"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :rshift"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :strftime"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú åáéðé íééìéìù íéëøò :rshift(%lf, %lf)"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "åööå÷é íéøåáù íéëøò :rshift(%lf, %lf)"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú áéðé éãî ìåãâ äææä øåòéù :rshift(%lf, %lf)"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :and"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :atan2"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú åáéðé íééìéìù íéëøò :and(%lf, %lf)"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "åööå÷é íéøåáù íéëøò :and(%lf, %lf)"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :or"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :atan2"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú åáéðé íééìéìù íéëøò :or(%lf, %lf)"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "åööå÷é íéøåáù íéëøò :or(%lf, %lf)"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "øôñî åðéà ïåùàø èðîåâøà :xor"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "øôñî åðéà éðù èðîåâøà :atan2"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú åáéðé íééìéìù íéëøò :xor(%lf, %lf)"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "åööå÷é íéøåáù íéëøò :xor(%lf, %lf)"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "øôñî åðéà èðîåâøà :compl"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "úåéåôö-éúìá úåàöåú áéðé éìéìù êøò :compl(%lf)"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "õöå÷é øåáù êøò :compl(%lf)"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "äðé÷ú íå÷éî úééøåâè÷ åðéà `%s' :dcgettext"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "%d ääåæî-éúìá âåñ ìòá node"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "genflags2str-á õöåç úùéìâ"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "øàì÷ñ ùøåãä èñ÷èðå÷á `%s' êøòîá ùåîéù ïåéñð"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr "(`%s' êøòî) äàìåìä òåöéá êìäîá %d-î %d-ì äðåù êøòî ìù åìãåâ :for úàìåì"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "éìéáèøåô åðéà äàìåìì õåçî `break'"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "äàìåìì õåçî `break'-á ùîúùäì ïéà"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "éìéáèøåô åðéà äàìåìì õåçî `continue'"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "äàìåìì õåçî `continue'-á ùîúùäì ïéà"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "BEGIN éììë êåúî `next'-ì àåø÷ì ïéà"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "END éììë êåúî `next'-ì àåø÷ì ïéà"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "BEGIN éììë êåúî `nextfile'-ì àåø÷ì ïéà"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "END éììë êåúî `nextfile'-ì àåø÷ì ïéà"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "úéìëú-úìåèð äàøåä"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "êøòî åà äðúùîë `%s' äéö÷ðåô íùá ùîúùäì ïéà"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "`%s' ìçåúî-éúìá èðîåâøàì äéðôä"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "`%s' ìçåúî-éúìá äðúùîì äéðôä"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"!øçà éåèéá ìù åëøåà éåðéùì åîøâ ãçà éåèéá áåùéç ìù éàåì-úåòôåú :concatenation"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "éàðú ìù èñ÷èðå÷á äîùäá ùåîéù"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "ñôàá ä÷åìç ïåéñð"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "`%%'-á ñôàá ä÷åìç ïåéñð"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tree_eval-á (%s) éåâù âåñ"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "`/='-á ñôàá ä÷åìç ïåéñð"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "`%%='-á ñôàá ä÷åìç ïåéñð"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "äúæøëäá øùàî íéèðîåâøà øúåé íò `%s' äéö÷ðåôì äàéø÷"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "úøãâåî äðéà `%s' äéö÷ðåô"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# :úåéö÷ðåôì úåàéø÷ä úéðñçî\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "øôñî åðéàù êøò úåòöîàá äãùì äéðôä ïåéñð"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "ä÷éø úæåøçî úåòöîàá äãùì äéðôä ïåéñð"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "%d 'ñî äãùì äùéâ ïåéñð"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "úéðáåî äéö÷ðåô ìù äàöåúá êøò áéöäì ïéà"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `IGNORECASE'"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `BINMODE'"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "äðé÷ú `%sFMT' úøãâä åðéà `%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "`LINT'-ì êøò úîùä á÷ò `--lint' ìèáî"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä äðéä `extension'"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "`%s' úçéúô úòá (%s) äì÷ú äòøéà :extension\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "`%s' äéøôñî `%s' äéö÷ðåôì äàéø÷á (%s) äì÷ú äòøéà :extension\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "`%s' äéøôñî `%s' äéö÷ðåôì äàéø÷á (%s) äì÷ú äòøéà :extension\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "`%s' úçéúô úòá (%s) äì÷ú äòøéà :extension\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "úøãâåî äðéà `%s' äéö÷ðåô"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "úøãâåî øáë `%s' íùá äéö÷ðåô"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "úàø÷ð àì êà ,äøãâåä `%s' äéö÷ðåô"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "úøãâåî äðéà `%s' äéö÷ðåô"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "êøòîë `%s' øàì÷ñá éåâù ùåîéù"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "úëîúð äðéà åæ äìåòô"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "éìéìù êøò ìáé÷ NF"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "êøòî åðéà `split' ìù éðùä èðîåâøàä"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä äðéä `split'-ì éùéìù èðåîâøàë úñôåàî úæåøçî"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä åðéä `FIELDWIDTHS'"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä äðéä `FS'-ë úñôåàî úæåøçî"
+
+# The way the leading "%s:" is translated is a terrible kludge,
+# but what can I do? FIXME.
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s úéðëú øåáò éòîùî-ãç åðéà `%s' ïééôàî\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s úéðëú øåáò èðîåâøà ìá÷î åðéà `--%s' ïééôàî\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s úéðëú øåáò èðîåâøà ìá÷î åðéà `%c%s' ïééôàî\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s úéðëú øåáò èðîåâøà áééçî `%s' ïééôàî\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s úéðëú øåáò `--%s' ääåæî-éúìá ïééôàî\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s úéðëú øåáò `%c%s' ääåæî-éúìá ïééôàî\n"
+
+# "Illegal" is against GNU coding standards, but since Posix requires
+# it (see the comment below), let's say that in Hebrew as well...
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: é÷åç-éúìá ïééôàî -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s úéðëú øåáò éåâù ïééôàî -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: èðîåâøà áééçî ïééôàî -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s úéðëú øåáò éòîùî-ãç åðéà `-W %s' ïééôàî\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s úéðëú øåáò èðîåâøà ìá÷î åðéà `-W %s' ïééôàî\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "åúàéø÷ íùì `%s' õáå÷ úçéúôá (%s) äì÷ú"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "(%d èìô/èì÷ õåøò) `%s' úøéâñá (%s) äì÷ú"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "redirect() äéö÷ðåôá %s éåâù õò âåñ"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "ãáìá éøîåð êøò áéðî `%s' èìô/èì÷ úééðôäá éåèéá"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "ä÷éø úæåøçî áéðî `%s' èìô/èì÷ úééðôäá éåèéá"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr "éâåì éåèéá ìù äàöåú úåéäì ìåìò `%s' õáå÷ íù `%s' èìô/èì÷ úééðôäá"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "`%.*s' õáå÷ øåáò `>>'-á ïäå `>'-á ïä øúåéî ùåîéù"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "èìô êøåöì `%s' ÷éôà úçéúôá (%s) äì÷ú"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "èì÷ êøåöì `%s' ÷éôà úçéúôá (%s) äì÷ú"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "èìô/èì÷ êøåöì éðååéë-åã (socket) ò÷ùë `%s' úçéúôá (%s) äì÷ú"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "èìô/èì÷ êøåöì éðååéë-åã (pipe) ÷éôàë `%s' úçéúôá (%s) äì÷ú"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "`%s'-î äééðôäá (%s) äì÷ú"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "`%s' ìà äééðôäá (%s) äì÷ú"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr "èìô/èì÷ éöåøò áåáéø úìéçú ;íéçåúô íéöá÷ øôñî ìù úëøòî úìáâîì äòâä"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "`%s' úøéâñá (%s) äì÷ú"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "úéðîæ-åá íéçåúô èì÷ éöá÷ åà (pipes) íé÷éôà éãî øúåé"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "`from' åà `to' úåéäì áééç `close' ìù éðùä èðîåâøàä"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "ìéá÷î êéìäú åà çåúô ÷éôà ,çåúô õáå÷ åðéà `%.*s' :close"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "íìåòî äçúôð àìù äééðôä úøéâñ"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr "çðæåä éðùä èðîåâøàä ,`|&' é\"ò äçúôð àì `%s' äééðôä"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "(%d äì÷ú ãå÷) `%s'-ì ÷éôà úøéâñá (%s) äì÷ú"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "(%d äì÷ú ãå÷) `%s' õáå÷ úøéâñá (%s) äì÷ú"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "ùøåôîá øâñð àì (socket) `%s' ò÷ù"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "ùøåôîá øâñð àì (co-process) `%s' ìéá÷î êéìäú"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "ùøåôîá øâñð àì (pipe) `%s' ÷éôà"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "ùøåôîá øâñð àì `%s' õáå÷"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "éð÷ú èìô õåøòì äáéúëá (%s) äì÷ú"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "éð÷ú úåàéâù õåøòì äáéúëá (%s) äì÷ú"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "`%s'-ì ÷éôà ìù õöåç ïå÷éøá (%s) äì÷ú"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "`%s'-ì ìéá÷î êéìäú ÷éôà ìù õöåç ïå÷éøá (%s) äì÷ú"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "`%s' ìù õáå÷ éðåúð õöåç ïå÷éøá (%s) äì÷ú"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "ïëåî íøè /inet/raw çå÷ì ,íéøòèöî"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "ãáìá root ùîúùîì øúåî `inet/raw'-á ùåîéù"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "ïëåî íøè /inet/raw úøù ,íéøòèöî"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "`%s' ãçåéî õáå÷ íùá ääåæî-éúìá åà øñç ìå÷åèåøô"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "íìù åðéà `%s' ãçåéî õáå÷"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "`%s'-á äéåâù úéîå÷î äàéöé"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "`/inet' øåáò ÷çåøî çøàî-áùçî íù øéãâäì äáåç"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "`/inet' øåáò ú÷çåøî äàéöé øéãâäì äáåç"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "`%s'-á äéåâù ú÷çåøî äàéöé"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP úøåù÷úá äëéîú ïéà"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "äé÷éú åðéä `%s' õáå÷"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "`PROCINFO[\"%s\"]'-á ùîúùäì óéãò `%s' íå÷îá"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "`/dev/user' éðô-ìò óéãò `PROCINFO[...]'-á ùåîéù"
+
+# This probably sounds nonsensical in Hebrew, but what can I do,
+# given the original message text?
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "`%s' øåáò `%s' äìåòô ïôåà úçéúôá ïåìùë"
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "÷éôà úøéâñá (%s) äì÷ú"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "úá-úéðëúá stdout úøéâñá (%s) äì÷ú"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "úá-úéðëúá stdout-ì ÷éôà ìåôëùá (dup: %s) äì÷ú"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "úá-úéðëúá stdin úøéâñá (%s) äì÷ú"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "úá-úéðëúá stdin-ì ÷éôà ìåôëùá (dup: %s) äì÷ú"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "÷éôà úøéâñá (%s) äì÷ú"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "úá-úéðëúá stdout-ì ÷éôà ìåôëùá (dup: %s) äì÷ú"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "úá-úéðëúá stdin-ì ÷éôà ìåôëùá (dup: %s) äì÷ú"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "áà-úéðëúá stdout ÷éôà øåæçùá äì÷ú\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "áà-úéðëúá stdin ÷éôà øåæçùá äì÷ú\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "÷éôà úøéâñá (%s) äì÷ú"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&'-á äëéîú ïéà"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "`%s' ÷éôà úçéúôá (%s) äì÷ú"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "`%s' úá-úéðëúì êéìäú úøéöéá (fork: %s) äì÷ú"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "÷éø åðéä `%s' íéðåúð õáå÷"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "`%s' õáå÷ úàéø÷á (%s) äì÷ú"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "gawk-ì úéôéöôñ äáçøä äðéä `RS' ìù êøòá íéåú øôñîá äëéîú"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "gawk øåáò éèðååìø åðéà `-m[fr]' ïééôàî"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "`-m[fr] nnn' :-m ïééôàîá ùåîéù ïôåà"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "çðæåä ,%s úéðëú øåáò øëåî åðéà `-W %s' ïééôàî\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "çðæåä `--source'-ì ÷éø èðîåâøà"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "`--posix' ìéòôî :øãâåî `POSIXLY_CORRECT' äáéáñ äðúùî"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--traditional' ìò øáåâ `--posix'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--non-decimal-data' ìò øáåâ `--posix'/`--traditional'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "òãéî úçèáàá òåâôì äìåìò setuid root-ë %s úöøä"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "stdin úìåòô ïôåà úòéá÷á (%s) äì÷ú"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "stdout úìåòô ïôåà úòéá÷á (%s) äì÷ú"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "stderr úìåòô ïôåà úòéá÷á (%s) äì÷ú"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "!ììë àöîðá äéä àì úéðëú ìù èñ÷è"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"%s [GNU åà POSIX ïåðâñá íéðééôàî] -f úéðëú-íù [--] õáå÷-íù ... :ùåîéù ïôåà\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"%s [GNU åà POSIX ïåðâñá íéðééôàî] [--] %cúéðëú%c õáå÷-íù ... :ùåîéù ïôåà\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr ":POSIX éðééôàî\t\t:íéëåøà GNU éðééôàî\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f úéðëú-õáå÷\t\t--file=úéðëú-õáå÷\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F úåãù-ãéøôî\t\t--field-separator=úåãù-ãéøôî\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v äðúùî=êøò\t\t--assign=äðúùî=êøò\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] êøò\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=õáå÷-íù]\t--dump-variables[=õáå÷-íù]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=õáå÷-íù]\t--profile[=õáå÷-íù]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=õáå÷-íù]\t--profile[=õáå÷-íù]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=úéðëú-èñ÷è\t--source=úéðëú-èñ÷è\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"àåäù ,`gawk.info' õáå÷á `Bugs' úîåö äàø ,úåì÷ú ìò çååéãì\n"
+" .ñôãåîä êéøãîá `Reporting Problems and Bugs' ä÷ñô\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+".èñ÷è úåéðáú ìù ãåáéòå äé÷øñì äôù åðéä gawk\n"
+".éð÷ú èìôì áúåëå éð÷ú èì÷ õåøò àøå÷ àåä ìãçî úøéøáë\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+" :úåàîâåã\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"óåôëá äúåðùì åà/å äöéôäì íëúåëæ ;úéùôç äðëú äðéä åæ úéðëú\n"
+" é\"ò øåàì àöåéä ,GNU General Public License ïåéùøä éàðúì\n"
+" íàå ,ïåéùøä ìù 2 àñøâá íà ;Free Software Foundation\n"
+" .øúåé úøçåàî àñøâ ìëá (íëì äøåîùä äéöôåàë)\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+",úìòåú àéáú àéäù äåå÷ú êåúî úöôåî åæ úéðëú\n"
+"òîúùîá-úåéøçà àì åìéôà ;úåéøçà áúë ìë àìì íìåà\n"
+",íéèøôì .úîéåñî úéìëú åæéàì äîàúä åà úåøéçñ ìù\n"
+" .GNU General Public License-á åðééò àðà\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+";GNU General Public License ìù ÷úåòá äååìî úåéäì äøåîà åæ úéðëú\n"
+"Free Software Foundation, Inc.-ì åáúë àðà ,åúåà íúìáé÷ àì íà\n"
+".51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "awk ìù POSIX úñøâá TAB úåéäì FS-ì íøåâ åðéà -Ft"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "äôö äãå÷ð éáåùéçá äâéøç"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "úéîéðô äðëú úàéâù :äøåîç äì÷ú"
+
+# FIXME: I wonder how many people will understand what "fd 2" means.
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "ùàøî çåúô åðéà %d èìô/èì÷ õåøò"
+
+# FIXME: /dev/null might not be known to all.
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "/dev/null-ì %d èìô/èì÷ õåøò çåúôì ïúéð àì"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "%s :úëøòîá íéùîúùî úåöåá÷ ìò òãéî ïéà"
+
+# The next 4 strings are untranslated because msg.c prints the actual
+# message after "warning:", "error:", etc., which will look terribly
+# wrong if both these headings and the message text after them is in
+# Hebrew, due to changed directionality.
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "cmd. line:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "warning: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "error: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "øôñîì äøîäì úðúéð äðéà úæåøçî"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "úæåøçî óåñá êåôä ïñëåì"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "`\\x' âåñî äø÷á úåøãñ äùøî åðéà POSIX ï÷ú"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "`\\x' äø÷á úøãñá úåéìîéöãñ÷ä úåøôñá ùîúùäì ïéà"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "éìåìéî åúë ìôåè `\\%c' äø÷á úøãñá `%c' åú"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s' øåáò close-on-exec ïééôàî úìòôäá (fcntl: %s) äì÷ú"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "äáéúë êøåöì `%s' úçéúô úòá (%s) äì÷ú"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "ñôåàî åìù vname-äù Node_var :úéîéðô äðëú úàéâù"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# %s êéøàúî gawk ìù ìéôåøô\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN ÷åìá\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# (íé)ììë\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END ÷åìá\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# úéá-óìà øãñá ,úåéö÷ðåô\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "prec_level-á %s éåâù âåñ"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "äçìöä"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "äîéàúî úæåøçî äàöîð àì"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "éåâù éøìåâø éåèéá"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "øãâåî-éúìá øåãéñ åú"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "íéåú úöåá÷ ìù øãâåî-éúìá íù"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "`\\' éøåçà ïñëåìá íééúñî éøìåâø éåèéá"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "íãå÷ éåèéá-úúì äéåâù äééðôä"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "âåæ-ïá åì ïéàù [^ åà ["
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "âåæ-ïá åì ïéàù \\( åà ("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "âåæ-ïá åì ïéàù \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "\\{\\} êåúá éåâù äðáî"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "íéåú íåçú ìù äéåâù äøãâä"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "ïåøëæä øîâð"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "íéé÷ åðéà åà éåâù íãå÷ éøìåâø éåèéá"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "éãî íã÷åî íééúñî éøìåâø éåèéá"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "éãî áëøåî åà ìåãâ éøìåâø éåèéá"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "âåæ-ïá åì ïéàù \\) åà )"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "íãå÷ éøìåâø éåèéá ïéà"
+
+#~ msgid "function %s called\n"
+#~ msgstr "`%s' äéö÷ðåôì äàéø÷\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "0-î ìåãâ úåéäì áééç FIELDWIDTHS-á %d 'ñî äãù"
+
+#, fuzzy
+#~ msgid "or used as a variable or an array"
+#~ msgstr "êøòî åà äðúùîë `%s' äéö÷ðåô íùá ùîúùäì ïéà"
+
+#~ msgid "regex match failed, not enough memory to match string \"%.*s%s\""
+#~ msgstr ""
+#~ "\"%.*s%s\" úæåøçî úîàúäì ïåøëæ éã ïéà ,ìùëð éøìåâø éåèéáì äîàúä ùåôéç"
+
+#, fuzzy
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "0-î ìåãâ øôñî åððéà %g êøåà :substr"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "êøòîë `%s' äðúùîá éåâù ùåîéù :delete"
+
+#, fuzzy
+#~ msgid "%s: gvar_ref to %s\n"
+#~ msgstr "%s: %s-ì (array_ref) äéðôä\n"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "êøòî åðéà ïåùàø èðîåâøà :asort"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "êøòî åðéà éðù èðîåâøà :asort"
+
+#, fuzzy
+#~ msgid ""
+#~ "attempt to use array parameter `%s' that was passed from global scalar `%"
+#~ "s'"
+#~ msgstr "êøòî äéä åìéàë `%s' éøì÷ñ øèîøôá ùåîéù ïåéñð"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "ñôåàî åìù vname-äù Node_var_array :úéîéðô äðëú úàéâù"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "äìåòô úøãâä ìåìëì áééç BEGIN ÷åìá"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "END åà BEGIN ìù äìåòô úøãâäá `nextfile'-á ùåîéù"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "éåðéù-øá è÷ééáåà åðéà `gsub' ìù éùéìù èðîåâøà"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "øçà éåèéá ìù èñ÷èðå÷á äá ùåîéù åà"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "äøåñà äá êøò úîùä ,äéö÷ðåô àéä `%s'"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "`%s' õáå÷ ìù %d äøåùá úéîéðô äðëú äàéâù\n"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr "END åà BEGIN úìåòô êåúá øãâåî åðéà äééðôä àìì `getline'"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "tokentab-á àöîð àì fptr %x\n"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "âåæ-ïá åì ïéàù ["
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "äøåîâ-éúìá \\ äø÷á úøãñ"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "äøåîâ-éúìá úåðùéä äðåî úøãâä"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "úåðùéä äðåî úøãâäá éåâù øéáçú"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "âåæ-ïá åì ïéàù ("
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "íééøìåâø íééåèéá ìù øéáçú úøãâä ïéà"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "âåæ-ïá åì ïéàù )"
+
+#~ msgid "out of memory"
+#~ msgstr "ïåøëæä øîâð"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "êøò úîùäá `%s' äðúùî íù ìù éåâù øéáçú"
--- /dev/null
+# Sed script that inserts the file called HEADER before the header entry.
+#
+# At each occurrence of a line starting with "msgid ", we execute the following
+# commands. At the first occurrence, insert the file. At the following
+# occurrences, do nothing. The distinction between the first and the following
+# occurrences is achieved by looking at the hold space.
+/^msgid /{
+x
+# Test if the hold space is empty.
+s/m/m/
+ta
+# Yes it was empty. First occurrence. Read the file.
+r HEADER
+# Output the file's contents by reading the next line. But don't lose the
+# current line while doing this.
+g
+N
+bb
+:a
+# The hold space was nonempty. Following occurrences. Do nothing.
+x
+:b
+}
--- /dev/null
+# Italian messages for GNU Awk
+# Copyright (C) 2002-2005 Free Software Foundation, Inc.
+# Antonio Colombo <azc10@yahoo.com>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.35\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-22 14:00+0100\n"
+"Last-Translator: Antonio Colombo <azc10@yahoo.com>\n"
+"Language-Team: Italian <it@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "tentativo di usare funzione '%s' come vettore"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "tentativo di unare il parametro scalare `%s' come un vettore"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "tentativo di usare scalare '%s' come vettore"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "da %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referenza a elemento non inizializzato `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "l'indice del vettore '%s' è una stringa nulla"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: indice `%s' non presente nel vettore `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: vuoto (nullo)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: vuoto (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: dimensione_tabella = %d, dimensione_vettore = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: è parametro\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: referenza_vettoriale a %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "blocchi %s richiedono una 'azione'"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "ogni regola deve avere una parte 'espressione' o una parte 'azione'"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' è una funzione interna, non si può ridefinire"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "espressione regolare costante `//' sembra un commento C, ma non lo è"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "espressione regolare costante `/%s/' sembra un commento C, ma non lo è"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "istruzione che può non aver alcun effetto"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s' usato in 'azione' %s"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' è un'estensione gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' usato fuori da una funzione"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr "`print' da solo in BEGIN o END dovrebbe forse essere `print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' è un'estensione gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete(array)' è un'estensione tawk non-portabile"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "valori di 'case' doppi all'interno di uno 'switch': %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "Valori per difetto doppi all'interno di uno 'switch'"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "'pipelines' multistadio bidirezionali non funzionano"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "espressione regolare usata per assegnare un valore"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "espressione regolare prima di operatore `~' o `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "espressione regolare a destra in un confronto"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "`getline' non re-diretta indefinita dentro 'azione' END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "chiamata a `length' senza parentesi non portabile"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "chiamata a `length' senza parentesi sconsigliata da POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "uso di non-vettore come vettore"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "espressione indice invalida"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "carattere 'a capo' o fine stringa inaspettati"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "programma nullo sulla linea comandi"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "non riesco ad aprire file sorgente `%s' in lettura (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "non riesco a leggere file sorgente `%s' (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "file sorgente `%s' vuoto"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "file sorgente non termina con carattere 'a capo'"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "espressione regolare non completata termina con `\\' a fine file"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"%s: %d: modificatore di espressione regolare tawk `/.../%c' non valido in "
+"gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "modificatore di espressione regolare tawk `/.../%c' non valido in gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "espressione regolare non completata"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "espressione regolare non completata a fine file"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "uso di `\\ #...' continuazione linea non portabile"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "'\\' non è l'ultimo carattere della linea"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX non permette l'operatore `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "il vecchio awk non supporta l'operatore `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX non permette l'operatore `**'"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "il vecchio awk non supporta l'operatore `**'"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "l'operatore `^=' non è supportato nel vecchio awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "l'operatore `^' non è supportato nel vecchio awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "stringa non terminata"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "carattere '%c' invalido in un'espressione"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' è un'estensione gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' è un'estensione Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX non permette `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' non è supportato nel vecchio awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' considerato pericoloso!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d invalido come numero di argomenti per %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: il terzo argomento è un'estensione gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: una stringa come ultimo argomento di 'substitute' non ha effetto"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "il terzo parametro di '%s' non è un oggetto modificabile"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: il secondo argomento è un'estensione gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"uso scorretto di dcgettext(_\"...\"): togliere il carattere '_' iniziale"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"uso scorretto di dcngettext(_\"...\"): togliere il carattere '_' iniziale"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funzione `%s': parametro #%d, `%s', duplica parametro #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "funzione `%s': parametro `%s' nasconde variabile globale"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "non riesco ad aprire `%s' in scrittura (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "mando profilo a 'standard error'"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: 'close' fallita (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() chiamata due volte!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "c'erano variabili nascoste."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funzione `%s': non posso usare nome della funzione come nome parametro"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funzione di nome `%s' definita in precedenza"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "funzione `%s' chiamata ma mai definita"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "funzione `%s' definita ma mai chiamata"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"espressione regolare di valore costante per parametro #%d genera valore "
+"booleano"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"funzione `%s' chiamata con spazio tra il nome e `(',\n"
+"o usata come variabile o vettore"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s a \"%s\" fallita (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standard output"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "ragione indeterminata"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: argomento non numerico"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argomento %g non accettabile"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: non posso scaricare: 'pipe' `%s' aperta in lettura, non in scrittura"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: non posso scaricare: file `%s' aperto in lettura, non in scrittura"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' non è un file aperto, una 'pipe' o un co-processo"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: il primo argomento non è una stringa"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: il secondo argomento non è una stringa"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: argomento non numerico"
+
+#: builtin.c:472
+msgid "`length(array)' is a gawk extension"
+msgstr "`length(array)' è un'estensione gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: l'argomento non è una stringa"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: argomento non numerico"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: argomento negativo %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "'count$' va usato per tutti i formati o per nessuno"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' non permesso nei 'format' awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "il numero di argomento con `$' deve essere > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"numero di argomenti (%ld) maggiore del numero totale di argomenti specificati"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' non permesso dopo un punto nel 'format'"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr ""
+"nessun `$' specificato per larghezza o precisione di un campo posizionale"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' non ha senso nei 'format' awk; ignorata"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`l' non permessa nei 'format' awk POSIX"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' non ha senso nei 'format' awk; ignorata"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`L' non permessa nei 'format' awk POSIX"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' non ha senso nei 'format' awk; ignorata"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`h' non permessa nei 'format' awk POSIX"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: valore %g non accettabile per il 'format' `%%%c'"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "mancano argomenti per completare il 'format'"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ uscito per questo"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: il designatore di 'format' non ha una lettera di controllo"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "troppi argomenti specificati per il 'format'"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: manca argomento"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: argomento non numerico"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: chiamata con argomento negativo %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: indice di partenza %g invalido, uso 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: indice di partenza non intero %g: sarà troncato"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: lunghezza %g non >= 1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: lunghezza %g non >= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: lunghezza non intera %g: sarà truncata"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "substr: lunghezza %g troppo elevata per indice stringa, tronco a %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: stringa di partenza lunga zero"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: indice di partenza %g oltre la fine della stringa"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: lunghezza %g all'indice di partenza %g supera la lunghezza del primo "
+"argomento (%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: il primo argomento non è una stringa"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: 'format' è una stringa nulla"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: il secondo argomento non è numerico"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: l'argomento non è una stringa"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: l'argomento non è una stringa"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referenza a variabile non inizializzata `$%d'"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: l'argomento non è una stringa"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: l'argomento non è una stringa"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: il primo argomento non è numerico"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: il secondo argomento non è numerico"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: l'argomento non è numerico"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: l'argomento non è numerico"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: l'argomento non è numerico"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: il terzo argomento non è un vettore"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: il terzo argomento è 0, trattato come 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: il primo argomento non è numerico"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: il secondo argomento non è numerico"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): valori negativi daranno risultati strani"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): valori con decimali verranno troncati"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): valori troppo alti daranno risultati strani"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: il primo argomento non è numerico"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: il secondo argomento non è numerico"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): valori negativi daranno risultati strani"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): valori con decimali verranno troncati"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): valori troppo alti daranno risultati strani"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: il primo argomento non è numerico"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: il secondo argomento non è numerico"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): valori negativi daranno risultati strani"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): valori con decimali verranno troncati"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: il primo argomento non è numerico"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: il secondo argomento non è numerico"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): valori negativi daranno risultati strani"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): valori con decimali verranno troncati"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: il primo argomento non è numerico"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: il secondo argomento non è numerico"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): valori negativi daranno risultati strani"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): valori con decimali verranno troncati"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: l'argomento non è numerico"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): valore negativo darà risultati strani"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): valore con decimali verrà troncato"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' non è una categoria 'locale' valida"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "tipo nodo sconosciuto %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "superament limiti buffer in 'genflags2str'"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "tentativo di usare vettore `%s' in un contesto scalare"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"ciclo for: vettore `%s' ha cambiato dimensione da %ld a %ld durante "
+"l'esecuzione del ciclo"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "`break' all'esterno di un ciclo non è portabile"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "`break' all'esterno di un ciclo non è consentito"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "`continue' all'esterno di un ciclo non è portabile"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "`continue' all'esterno di un ciclo non è consentito"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`next' non può essere chiamato da una regola BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "`next' non può essere chiamato da una regola END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`nextfile' non può essere chiamato da una regola BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`nextfile' non può essere chiamato da una regola END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "istruzione che non fa nulla"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "non posso usare nome di funzione `%s' come variabile o vettore"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referenza ad argomento non inizializzato `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referenza a variabile non inizializzata `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenatione: effetti secondari in una espressione hanno modificato la "
+"lunghezza di un'altra espressione!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "assegnamento usato nel contesto di un test condizionale"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "tentativo di dividere per zero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "divisione per zero tentata in `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tipo non ammesso (%s) in 'tree_eval'"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "divisione per zero tentata in `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "divisione per zero tentata in `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "funzione `%s' chiamata con più argomenti di quelli previsti"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "funzione `%s' non definita"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# 'Stack' (Pila) Chiamate Funzione:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- principale --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "tentativo di referenziare campo da valore non numerico"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "tentativo to referenziare da stringa nulla"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "tentativo di accedere al campo %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "assegnamento non permesso al risultato di una funzione interna"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' è un'estensione gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' è un'estensione gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "specificazione invalida `%sFMT' `%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "disabilito `--lint' a causa di assegnamento a `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' è un'estensione gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "estensione: non riesco ad aprire `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"estensione: biblioteca `%s': non riesco a chiamare funzione `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "estensione: manca nome di funzione"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "estensione: carattere non ammesso `%c' nel nome di funzione `%s'"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "estensione: non riesco a ridefinire funzione `%s'"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "estensione: funzione `%s' già definita"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+"estensione: nome funzione interna gawk `%s' non ammesso come nome funzione"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "estensione: funzione di nome `%s' definita in precedenza"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "funzione `%s' definita per avere al massimo %d argumenti/o"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "funzione `%s': manca argomento #%d"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "funzione `%s': argomento #%d: tentativo di usare scalare come vettore"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "funzione `%s': argomento #%d: tentativo di usare vettore come scalare"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operazione Non Supportata"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF impostato a un valore negativo"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: il secondo argomento non è un vettore"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: la stringa nulla come terzo arg. è un'estensione gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' è un'estensione gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "valore di FIELDWIDTHS invalido, vicino a `%s'"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "la stringa nulla usata come `FS' è un'estensione gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: opzione `%s' ambigua\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: opzione `--%s' non prevede un argomento\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: opzione `%c%s' non prevede un argomento\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: opzione `%s' richiede un argomento\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: opzione sconosciuta `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: opzione sconosciuta `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: opzione non permessa -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: opzione non valida -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: l'opzione richiede un argomento -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: opzione `-W %s' ambigua\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: opzione `-W %s' non prevede un argomento\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "non riesco ad aprire file `%s' in lettura (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "chiusura di fd %d (`%s') fallita (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "tipo di albero invalido %s in redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "espressione nella re-direzione `%s' ha solo un valore numerico"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "espressione nella re-direzione `%s' ha per valore la stringa nulla"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"nome file `%s' per la re-direzione `%s' può essere il risultato di una "
+"espressione logica"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "mistura non necessaria di `>' e `>>' per il file `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "non posso aprire 'pipe' `%s' in scrittura (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "non posso aprire 'pipe' `%s' in lettura (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"non posso aprire 'socket' bidirezionale `%s' per lettura/scrittura (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "non posso aprire 'pipe' bidirezionale `%s' per lettura/scrittura (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "non posso re-dirigere da `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "non posso re-dirigere a `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"numero massimo consentito di file aperti raggiunto: comincio a riutilizzare "
+"i descrittori di file"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "chiusura di `%s' fallita (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "troppe 'pipe' o file di input aperti"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: il secondo argomento deve essere `a' o `da'"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: `%.*s' non è un file aperto, una 'pipe' o un co-processo"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "chiusura di una re-direzione mai aperta"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr "close: re-direzione `%s' non aperta con `|&', ignoro secondo argomento"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "errore ritornato (%d) dalla chiusura della 'pipe' `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "errore ritornato (%d) dalla chiusura del file `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "nessuna chiusura esplicita richiesta per 'socket' `%s'"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "nessuna chiusura esplicita richiesta per co-processo `%s'"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "nessuna chiusura esplicita richiesta per 'pipe' `%s'"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "nessuna chiusura esplicita richiesta per file `%s'"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "errore scrivendo 'standard output' (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "errore scrivendo 'standard error' (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "scaricamento di 'pipe' `%s' fallita (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "scaricamento da co-processo di 'pipe' a `%s' fallita (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "scaricamento di file `%s' fallita (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "spiacente, 'client' /inet/raw non ancora pronto"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "solo root può usare `/inet/raw'."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "spiacente, 'server' /inet/raw non ancora pronto"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "nessuno protocollo (conosciuto) specificato nel filename speciale `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "nome file speciale `%s' incompleto"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "porta locale invalida in `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "va fornito nome di 'host' remoto a `/inet'"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "va fornita porta remota a `/inet'"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "porta remota invalida in `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "comunicazioni TCP/IP non supportate"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "file `%s' è una 'directory'"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "usa `PROCINFO[\"%s\"]' invece che `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "usa `PROCINFO[...]' invece che `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "non riesco ad aprire `%s', modo `%s'"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "fallita chiusura di 'pty' principale (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "fallita chiusura di 'stdout' nel processo-figlio (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"fallito trasferimento di 'pty' secondaria a 'stdout' nel processo-figlio "
+"(dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "fallita chiusura di 'stdin' nel processo-figlio (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"fallito trasferimento di 'pty' secondaria a 'stdin' nel processo-figlio "
+"(dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "fallita chiusura di 'pty' secondaria (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "fallito passaggio di 'pipe' a 'stdout' nel processo-figlio (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "fallito passaggio di pipe a 'stdin' nel processo-figlio (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "fallito ripristino di 'stdout' nel processo-padre\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "fallito ripristino di 'stdin' nel processo-padre\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "fallita chiusura di 'pipe' (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' non supportato"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "non riesco ad aprire 'pipe' `%s' (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "non riesco a creare processo-figlio per `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "file dati `%s' vuoto"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "non riesco ad allocare ulteriore memoria per l'input"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "errore leggendo file di input `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "valore multicarattere per `RS' è un'estensione gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "`-m[fr]' opzione irrilevante per gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m uso opzione: `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: opzione `-W %s' non riconosciuta, ignorata\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "argomento di `--source' mancante, comando ignorato"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "variable d'ambiente `POSIXLY_CORRECT' impostata: attivo `--posix'"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--posix' annulla `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--posix'/`--traditional' annulla `--non-decimal-data'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "eseguire %s con 'setuid' root può essere un rischio per la sicurezza"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "non posso impostare modalità binaria su 'stdin'(%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "non posso impostare modalità binaria su 'stdout'(%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "non posso impostare modalità binaria su 'stderr'(%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "manca del tutto il testo del programma!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Uso: %s [opzioni in stile POSIX o GNU] -f fileprog [--] file ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Usage: %s [opzioni in stile POSIX o GNU] [--] %cprogramma%c file ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Opzioni POSIX:\t\topzioni lunghe GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f fileprog\t\t--file=fileprog\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=valore\t\t--assign=var=valore\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] valore\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec[=file]\t--exec[=file]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=file]\t--profile[=file]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=testo-programma\t--source=testo-programma\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Per segnalare problemi, vedi nodo `Bugs' in `gawk.info', oppure la\n"
+"sezione `Reporting Problems and Bugs' nella versione a stampa.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk è un linguaggio per scandire e processare espressioni.\n"
+"Senza parametri, legge da 'standard input' e scrive su 'standard output'.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Esempi:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Questo software è libero; lo puoi distribuire e/o modificare\n"
+"alle condizioni stabilite nella 'GNU General Public License' pubblicata\n"
+"dalla Free Software Foundation; fai riferimento alla versione 2 della\n"
+"Licenza, o (a tua scelta) a una qualsiasi versione successiva.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Questo programma è distribuito con la speranza che sia utile,\n"
+"ma SENZA ALCUNA GARANZIA; senza neppure la garanzia implicita\n"
+"di COMMERCIABILITA' o IDONEITA' AD UN PARTICOLARE SCOPO.\n"
+"Vedi la 'GNU General Public License' per ulteriori dettagli.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Dovresti aver ricevuto una copia della 'GNU General Public License'\n"
+"assieme a questo programma; se non è così, scrivi alla Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft non imposta FS a 'tab' nell'awk POSIX"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: `%s' argomento di `-v' non in forma `var=valore'\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' non è un nome di variabile ammesso"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' non è un nome di variabile, cerco il file `%s=%s'"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "eccezione floating point"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "errore fatale: errore interno"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "manca 'fd' predefinita %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "non riesco a predefinire /dev/null per 'fd' %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "non riesco a trovare gruppi: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "linea progr.:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "attenzione: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "errore: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatale: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "non riesco a convertire stringa a valore in virgola mobile"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "'\\' a fine stringa"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX non permette formato `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "niente cifre esadecimanli nel formato `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr " sequenza in formato `\\%c' considerata come semplice `%c'"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': non riesco a impostare 'close-on-exec': (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "non riesco ad aprire `%s' in scrittura: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "errore interno: %s con 'vname' nullo"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# gestito internamente come 'delete' (cancellazione)"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# questa è una funzione di estensione caricata dinamicamente"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# profilo gawk, creato %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# blocco(hi) BEGIN\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regola(e)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# blocco(hi) END\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funzioni, listate in ordine alfabetico\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "tipo non previsto %s in 'prec_level'"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Successo"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Nessuna corrispondenza"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Espressione regolare invalida"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Carattere di ordinamento non valido"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nome di 'classe di caratteri' invalido"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "'\\' finale"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Riferimento indietro invalido"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ or [^ non chiusa"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( or \\( non chiusa"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ non chiusa"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Contenuto di \\{\\} invalido"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Fine di intervallo invalido"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Memoria esaurita"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Espressione regolare precedente invalida"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Fine di expressione regolare inaspettata"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Espressione regolare troppo complessa"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") or \\) non aperta"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Nessuna espressione regolare precedente"
--- /dev/null
+# Japanese messages for gawk.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gawk package.
+# Makoto Hosoya <mhosoya@ozemail.com.au>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-27 02:37+1000\n"
+"Last-Translator: Makoto Hosoya <mhosoya@ozemail.com.au>\n"
+"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=EUC-JP\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "´Ø¿ô `%s' ¤òÇÛÎó¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "¥¹¥«¥é¡¼¥Ñ¥é¥á¡¼¥¿ `%s' ¤òÇÛÎó¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "¥¹¥«¥é¡¼ `%s' ¤òÇÛÎó¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "%s ¤«¤é"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤Í×ÁÇ `%s[\"%s\"]' ¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "ÇÛÎó¤Îź»ú `%s' ¤¬¶õÎó¤Ç¤¹¡£"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: ÇÛÎó `%2$s' ¤Ë»ØÉ¸ `%1$s' ¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: ¶õ (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: ¶õ (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: ¥Æ¡¼¥Ö¥ë¥µ¥¤¥º (table_size) = %d, ÇÛÎó¥µ¥¤¥º (array_size) = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: ¤Ï¥Ñ¥é¥á¡¼¥¿¤Ç¤¹¡£\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: %s ¤Ø¤ÎÇÛÎó»²¾È (array_ref)\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "%s ¥Ö¥í¥Ã¥¯¤Ë¤Ï¥¢¥¯¥·¥ç¥óÉô¤¬É¬¿Ü¤Ç¤¹¡£"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "³Æ¥ë¡¼¥ë¤Ë¤Ï¥Ñ¥¿¡¼¥ó¤Þ¤¿¤Ï¥¢¥¯¥·¥ç¥óÉô¤¬É¬¿Ü¤Ç¤¹¡£"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' ¤ÏÁȹþ¤ß´Ø¿ô¤Ç¤¹¡£ºÆÄêµÁ¤Ç¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "Àµµ¬É½¸½Äê¿ô `//' ¤Ï C++¥³¥á¥ó¥È¤Ë»÷¤Æ¤¤¤Þ¤¹¤¬¡¢°ã¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "Àµµ¬É½¸½Äê¿ô `/%s/' ¤Ï C¥³¥á¥ó¥È¤Ë»÷¤Æ¤¤¤Þ¤¹¤¬¡¢°ã¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "Ì¿Îáʸ¤Ë¤Ï¸ú²Ì¤¬Ìµ¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s' ¤¬ %s ¤Î¥¢¥¯¥·¥ç¥ó¤Ç»È¤ï¤ì¤Þ¤·¤¿¡£"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' ¤¬´Ø¿ôÄêµÁʸ¤Î³°¤Ç»È¤ï¤ì¤Þ¤·¤¿¡£"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"BEGIN ¤Þ¤¿¤Ï END ¥ë¡¼¥ëÆâ¤Î°ú¿ô¤Î̵¤¤ `print' ¤Ï `print \"\"' ¤À¤È»×¤ï¤ì¤Þ"
+"¤¹¡£"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete(array)' ¤Ï tawk ÆÃͤγÈÄ¥¤Ç¤¹¡£Â¾¤Î awk ¤Ç¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "switch ʸ¤ÎÃæ¤Ë½ÅÊ£¤·¤¿ case Ãͤ¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "switch ʸ¤ÎÃæ¤Ë `default' ¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "¿Ãʳ¬¤ÇÁÐÊý¸þ¥Ñ¥¤¥×¤òÍøÍѤ·¤¿¼°¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "Àµµ¬É½¸½¤¬ÂåÆþ¼°¤Î±¦Êդ˻ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "`~' ¤ä `!~' ±é»»»Ò¤Îº¸ÊÕ¤ËÀµµ¬É½¸½¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "Èæ³Ó¼°¤Î±¦ÊÕ¤ËÀµµ¬É½¸½¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤Æ¤¤¤Ê¤¤ `getline' ¤Ï END ¥¢¥¯¥·¥ç¥ó¤Ç¤Ï̤ÄêµÁ¤Ç¤¹¡£"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "³ç¸Ì̵¤·¤Î `length' ¤Ï¾¤Î awk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "POSIX ¤Ï³ç¸Ì̵¤·¤Ç¤Î `length' ¤Î»ÈÍѤò¿ä¾©¤·¤Þ¤»¤ó¡£"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "ÇÛÎó¤Ç¤Ê¤¤¤â¤Î¤òÇÛÎó¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "ź»ú¼°¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "ͽÁÛ³°¤Î²þ¹Ô¤Þ¤¿¤Ïʸ»úÎó¤Î½ªÃ¼¤¬¤¢¤ê¤Þ¤¹¡£"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "¥³¥Þ¥ó¥É¹Ô¤Î¥×¥í¥°¥é¥àɽµ¤¬¶õ¤Ç¤¹¡£"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "¥½¡¼¥¹¥Õ¥¡¥¤¥ë `%s' ¤òÆÉ¤ß¹þ¤à¤¿¤á¤Ë³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "¥½¡¼¥¹¥Õ¥¡¥¤¥ë `%s' ¤òÆÉ¤ß¹þ¤á¤Þ¤»¤ó (%s)¡£"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "¥½¡¼¥¹¥Õ¥¡¥¤¥ë `%s' ¤Ï¶õ¤Ç¤¹¡£"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤¬²þ¹Ô¤Ç½ª¤Ã¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "½ªÃ¼¤µ¤ì¤Æ¤¤¤Ê¤¤Àµµ¬É½¸½¤¬¥Õ¥¡¥¤¥ëºÇ¸å¤Î `\\' ¤Ç½ª¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "%s: %d: tawk ¤ÎÀµµ¬É½¸½½¤¾þ»Ò `/.../%c' ¤Ï gawk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "tawk ¤ÎÀµµ¬É½¸½½¤¾þ»Ò `/.../%c' ¤Ï gawk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "Àµµ¬É½¸½¤¬½ªÃ¼¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "¥Õ¥¡¥¤¥ë¤ÎÃæ¤ÇÀµµ¬É½¸½¤¬½ªÃ¼¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "`\\ #...' ·Á¼°¤Î¹Ô·Ñ³¤Ï¾¤Î awk ¤Ç»È¤¨¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤¬¹ÔºÇ¸å¤Îʸ»ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX ¤Ï±é»»»Ò `**=' ¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "±é»»»Ò `**=' ¤Ï¸Å¤¤ awk ¤Ç»È¤¨¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX ¤Ç¤Ï±é»»»Ò `**' ¤òµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "±é»»»Ò `**' ¤Ï¸Å¤¤ awk ¤Ç»È¤¨¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "±é»»»Ò `^=' ¤Ï¸Å¤¤ awk ¤Ç»È¤¨¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "±é»»»Ò `^' ¤Ï¸Å¤¤ awk ¤Ç»È¤¨¤Þ¤»¤ó¡£"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "ʸ»úÎ󤬽ªÃ¼¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "ɽ¸½¤Î char '%c' ¤ÏÉÔÀµ¤Ç¤¹¡£"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' ¤Ï¥Ù¥ë¸¦µæ½ê¤Ë¤è¤ë³ÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX ¤Ï `%s' ¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' ¤Ï¸Å¤¤ awk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' ¤Ïͳ²¤Ç¤¹!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d ¤Ï %s ¤Ë»È¤¨¤ë°ú¿ô¤Î¿ô¤È¤·¤Æ¤ÏÉÔÀµ¤Ç¤¹¡£"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: Âè»°°ú¿ô¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: ʸ»úÎó¥ê¥Æ¥é¥ë¤òÃÖ¤´¹¤¨ºÇ¸å¤Î°ú¿ô¤Ë»ÈÍѤ¹¤ë¤È¸ú²Ì¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "%s Âè»°¥Ñ¥é¥á¡¼¥¿¤Ï²ÄÊÑ¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: ÂèÆó°ú¿ô¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"dcgettext(_\"...\")¤Î»È¤¤Êý¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹: ºÇ½é¤Î¥¢¥ó¥À¡¼¥¹¥³¥¢¤òºï½ü¤·¤Æ¤¯"
+"¤À¤µ¤¤¡£"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"dcngettext(_\"...\")¤Î»È¤¤Êý¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹: ºÇ½é¤Î¥¢¥ó¥À¡¼¥¹¥³¥¢¤òºï½ü¤·¤Æ"
+"¤¯¤À¤µ¤¤¡£"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "´Ø¿ô `%s': ¥Ñ¥é¥á¡¼¥¿ #%d, `%s' ¤¬¥Ñ¥é¥á¡¼¥¿ #%d ¤È½ÅÊ£¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "´Ø¿ô `%s': ¥Ñ¥é¥á¡¼¥¿ `%s' ¤¬Âç°èÊÑ¿ô¤òʤ¤¤±£¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "`%s' ¤ò½ñ¹þ¤ßÍѤ˳«¤±¤Þ¤»¤ó¤Ç¤·¤¿ (%s)¡£"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "¥×¥í¥Õ¥¡¥¤¥ë¤òɸ½à¥¨¥é¡¼¤ËÁ÷¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: ÊĤ¸¤ë¤³¤È¤¬¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() ¤òÆó²ó¸Æ¤Ó½Ð¤·¤Æ¤¤¤Þ¤¹!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "ʤ¤¤±£¤µ¤ì¤¿ÊÑ¿ô¤¬¤¢¤ê¤Þ¤·¤¿¡£"
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "´Ø¿ô `%s': ´Ø¿ô̾¤Ï¥Ñ¥é¥á¡¼¥¿Ì¾¤Ë»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "´Ø¿ô̾ `%s' ¤ÏÄêµÁºÑ¤ß¤Ç¤¹¡£"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "̤ÄêµÁ¤Î´Ø¿ô `%s' ¤ò¸Æ¤Ó½Ð¤·¤Þ¤·¤¿¡£"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "ÄêµÁ¤µ¤ì¤¿´Ø¿ô `%s' ¤Ï°ìÅÙ¤â¸Æ¤Ó½Ð¤µ¤ì¤Þ¤»¤ó¤Ç¤·¤¿¡£"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "¥Ñ¥é¥á¡¼¥¿ #%d ¤ÎÀµµ¬É½¸½Äê¿ô¤Ï¥Ö¡¼¥ëÃͤò½ÐÎϤ·¤Þ¤¹¡£"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"´Ø¿ô̾¤È `(' ¤Î´Ö¤Ë¥¹¥Ú¡¼¥¹¤òÆþ¤ì¤Æ´Ø¿ô `%s' ¤ò¸Æ¤Ó½Ð¤·¤Æ¤¤¤Þ¤¹¡£\n"
+"¤Þ¤¿¤Ï¡¢ÊÑ¿ô¤«ÇÛÎó¤È¤·¤Æ»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s ¤«¤é \"%s\" ¤Ø½ÐÎϤǤ¤Þ¤»¤ó (%s)¡£"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "ɸ½à½ÐÎÏ"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "¸¶°øÉÔÌÀ"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: °ú¿ô %g ¤¬µöÍÆÈϰϤòͤ¨¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr "fflush: ¥Õ¥é¥Ã¥·¥åÉÔ²Ä: ¥Ñ¥¤¥× `%s' ¤ÏÆÉ¤ß¹þ¤ßÀìÍѤǤ¹¡£"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr "fflush: ¥Õ¥é¥Ã¥·¥åÉÔ²Ä: ¥Õ¥¡¥¤¥ë `%s' ¤ÏÆÉ¤ß¹þ¤ßÀìÍѤǤ¹¡£"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr ""
+"fflush: `%s' ¤Ï¥Õ¥¡¥¤¥ë¤«¡¢¥Ñ¥¤¥×¤«¡¢ÊÂ¹Ô¥×¥í¥»¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: Âè°ì°ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: ÂèÆó°ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete array' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: °ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: °ú¿ô %g ¤¬Éé¤ÎÃͤǤ¹¡£"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+"`count$¡Ç¤ÏÁ´¤Æ¤Î½ñ¼°»ØÄê¤ËŬÍѤ¹¤ë¡¢¤Þ¤¿¤ÏÁ´¤Æ¤ËŬÍѤ·¤Ê¤¤¤Î¤É¤Á¤é¤«¤Ç¤·¤«»È"
+"¤¨¤Þ¤»¤ó¡£"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' ¤Ï awk ¤Ç¤Ï»È¤¨¤Þ¤»¤ó¡£"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "½ç½ø»ØÄê¤Î `$' ¤Ë»È¤¨¤ë¿ô»ú¤ÏÀµ¤ÎÃͤǤ¹¡£"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "½ç½ø»ØÄê %ld ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë°ú¿ô¤Î¿ô¤òͤ¨¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' ¤Ï½ñ¼°»ØÄê¤Î¥Ô¥ê¥ª¥É `.' ¤Î¸å¤Ë»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "¥Õ¥£¡¼¥ë¥ÉÉý¡¢¤Þ¤¿¤ÏÀºÅ٤λØÄê»Ò¤Ë `$' ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "awk ¤Î½ñ¼°»ØÄê¤Ç¤Ï `l' ¤Ï̵°ÕÌ£¤Ç¤¹¡£Ìµ»ë¤·¤Þ¤¹¡£"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "POSIX ½àµò¤Î awk ¤Ç¤Ï `l' ¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "awk ¤Î½ñ¼°»ØÄê¤Ç¤Ï `L' ¤Ï̵°ÕÌ£¤Ç¤¹¡£Ìµ»ë¤·¤Þ¤¹¡£"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "POSIX ½àµò¤Î awk ¤Ç¤Ï `L' ¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "awk ¤Î½ñ¼°»ØÄê¤Ç¤Ï `h' ¤Ï̵°ÕÌ£¤Ç¤¹¡£Ìµ»ë¤·¤Þ¤¹¡£"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "POSIX ½àµò¤Î awk ¤Ç¤Ï `h' ¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: %g ¤ÎÃͤ¬½ñ¼° `%%%c' ¤ÎµöÍÆÈϰϤòͤ¨¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "½ñ¼°»ØÄꤹ¤ë¤¿¤á¤Î°ú¿ô¤¬Â¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ ¤³¤³¤«¤é¤ê¤Þ¤»¤ó"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: ½ñ¼°»ØÄê»Ò¤ËÀ©¸æÊ¸»ú¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "½ñ¼°»ØÄêʸ»úÎó¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹¡£"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: °ú¿ô¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: °ú¿ô¤ËÉé¤ÎÃÍ %g ¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: µ¯ÅÀ»ØÉ¸ %g ¤¬ÉÔÀµ¤Ç¤¹¡£1 ¤ò»È¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: µ¯ÅÀ»ØÉ¸ %g ¤Î¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Þ¤¹¡£"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: ʸ»ú¿ô %g ¤¬ 1 °Ê¾å¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: ʸ»ú¿ô %g ¤¬ 0 °Ê¾å¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: ʸ»ú¿ô %g ¤Î¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Þ¤¹¡£"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "substr: ʸ»ú¿ô %g ¤ÏºÇÂçÃͤòͤ¨¤Æ¤¤¤Þ¤¹¡£%g ¤ò»È¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: ʸ»úÎó¤ÎŤµ¤¬¥¼¥í¤Ç¤¹¡£"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: µ¯ÅÀ»ØÉ¸ %g ¤¬Ê¸»úÎó¤ÎŤµ¤òͤ¨¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: µ¯ÅÀ»ØÉ¸ %2$g ¤«¤é¤Îʸ»ú¿ô %1$g ¤Ïʸ»úÎó¤ÎŤµ %3$lu ¤òͤ¨¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: Âè°ì°ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: ½ñ¼°»ØÄêʸ»úÎ󤬶õ¤Ç¤¹¡£"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: °ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: °ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤¥Õ¥£¡¼¥ë¥É `$%d' ¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: °ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: °ú¿ô¤¬Ê¸»úÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: Âè»°°ú¿ô¤¬ÇÛÎó̾¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: Âè»°°ú¿ô¤¬ 0 ¤Ç¤¹¡£1 ¤òÂå¤ï¤ê¤Ë»ÈÍѤ·¤Þ¤¹¡£"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): ¥·¥Õ¥ÈÃͤ¬Â礲᤮¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): ¥·¥Õ¥ÈÃͤ¬Â礲᤮¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: Âè°ì°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: ÂèÆó°ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: °ú¿ô¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): Éé¤Î¿ôÃͤò»ÈÍѤ¹¤ë¤È°Û¾ï¤Ê·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): ¾®¿ôÅÀ°Ê²¼¤ÏÀÚ¤ê¼Î¤Æ¤Ë¤Ê¤ê¤Þ¤¹¡£"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' ¤ÏÉÔÀµ¤Ê¥í¥«¡¼¥ë¡¦¥«¥Æ¥´¥ê¡¼¤Ç¤¹¡£"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "¥Î¡¼¥É %d ¤Î¼ïÎबÉÔÌÀ¤Ç¤¹¡£"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "genflags2str ¤¬¥Ð¥Ã¥Õ¥¡ÍÆÎ̤òĶ²á¤·¤Þ¤·¤¿¡£"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "¥¹¥«¥é¡¼´Ä¶¤ËÇÛÎó `%s' ¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for ¥ë¡¼¥×: ¥ë¡¼¥×Ãæ¤ËÇÛÎó `%s' ¤Î¥µ¥¤¥º¤¬ %ld ¤«¤é %ld ¤ËÊѤï¤ê¤Þ¤·¤¿¡£"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "¥ë¡¼¥×¤Î³°¤Ç»ÈÍѤ¹¤ë `break' ¤Ï¾¤Î awk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "¥ë¡¼¥×¤Î³°¤Ç¤Ï `break' ¤ò»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "¥ë¡¼¥×¤Î³°¤Ç»ÈÍѤ¹¤ë `continue' ¤Ï¾¤Î awk ¤Ç»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "¥ë¡¼¥×¤Î³°¤Ç¤Ï `continue' ¤ò»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "BEGIN ¥ë¡¼¥ë¤«¤é¤Ï `next' ¤ò¸Æ¤Ó½Ð¤»¤Þ¤»¤ó¡£"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "END ¥ë¡¼¥ë¤«¤é¤Ï `next' ¤ò¸Æ¤Ó½Ð¤»¤Þ¤»¤ó¡£"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "BEGIN ¥ë¡¼¥ë¤«¤é¤Ï `nextfile' ¤ò¸Æ¤Ó½Ð¤»¤Þ¤»¤ó¡£"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "END ¥ë¡¼¥ë¤«¤é¤Ï `nextfile' ¤ò¸Æ¤Ó½Ð¤»¤Þ¤»¤ó¡£"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "Ì¿Îáʸ¤Ë¸ú²Ì¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "´Ø¿ô̾ `%s' ¤ÏÊÑ¿ô¤äÇÛÎó¤Ë¤Ï»È¤¨¤Þ¤»¤ó¡£"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤°ú¿ô `%s' ¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤ÊÑ¿ô `%s' ¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation¡Êʸ»úÎóÏ¢·ë¡Ë: °ìÊý¤Î¼°¤ÎÉûºîÍѤǡ¢¤â¤¦°ìÊý¤ÎŤµ¤¬ÊѤï¤ê¤Þ¤·"
+"¤¿!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "¾ò·ïÊ¸Ãæ¤Ç¤ÎÂåÆþ"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "¥¼¥í¤Ç¤Î½ü»»¤ò¹Ô¤¤¤Þ¤·¤¿¡£"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "`%%' ¤Ç¥¼¥í¤Ç¤Î½ü»»¤ò¹Ô¤¤¤Þ¤·¤¿¡£"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tree_eval ¤ÎÃæ¤ËÉÔÀµ¤Ê¥¿¥¤¥× (%s) ¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "`/=' ¤Ç¥¼¥í¤Ç¤Î½ü»»¤ò¹Ô¤¤¤Þ¤·¤¿¡£"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "`%%=' ¤Ç¥¼¥í¤Ç¤Î½ü»»¤ò¹Ô¤¤¤Þ¤·¤¿¡£"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "Àë¸À¤µ¤ì¤Æ¤¤¤ë¿ô¤è¤ê¿¤¤°ú¿ô¤ò»È¤Ã¤Æ´Ø¿ô `%s' ¤ò¸Æ¤Ó½Ð¤·¤Þ¤·¤¿¡£"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "´Ø¿ô `%s' ¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# ¸Æ½Ð´Ø¿ô¥¹¥¿¥Ã¥¯:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- ¥á¥¤¥ó --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "¿ôÃͰʳ°¤ÎÃͤò»È¤Ã¤Æ¥Õ¥¤¡¼¥ë¥É¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "¶õÎó¤ò»È¤Ã¤Æ»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "¥Õ¥£¡¼¥ë¥É %d ¤ò»²¾È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "Áȹþ´Ø¿ô¤ÎÌá¤êÃͤËÂåÆþ¤Ï¤Ç¤¤Þ¤»¤ó¡£"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "`%sFMT' ¤Î»ØÄê `%s' ¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "`LINT' ¤Ø¤ÎÂåÆþ¤Ë½¾¤¤ `--lint' ¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: `%s' ¤ò³«¤±¤Þ¤»¤ó (%s)¡£\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: ¥é¥¤¥Ö¥é¥ê `%s': ´Ø¿ô `%s' ¤ò¸Æ¤Ó½Ð¤»¤Þ¤»¤ó (%s)¡£\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: ´Ø¿ô̾¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: ´Ø¿ô̾ `%2$s' ¤ÎÃæ¤ËÉÔÀµ¤Êʸ»ú `%1$c' ¤¬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: ´Ø¿ô `%s' ¤òºÆÄêµÁ¤Ç¤¤Þ¤»¤ó¡£"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: ´Ø¿ô `%s' ¤Ï´û¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr "extension: ÁȤ߹þ¤ß´Ø¿ô `%s' ¤Ï´Ø¿ô̾¤Ë»È¤¨¤Þ¤»¤ó¡£"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: ´Ø¿ô̾ `%s' ¤Ï´û¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "´Ø¿ô `%s' ¤Ë»È¤¨¤ë°ú¿ô¤Î¿ô¤Ï `%d' °Ê²¼¤ÈÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "´Ø¿ô `%s': °ú¿ô #%d ¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "´Ø¿ô `%s': °ú¿ô #%d: ¥¹¥«¥é¡¼¤òÇÛÎó¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "´Ø¿ô `%s': °ú¿ô #%d: ÇÛÎó¤ò¥¹¥«¥é¡¼¤È¤·¤Æ»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "¤³¤ÎÁàºî¤Ï¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF ¤¬Éé¤ÎÃͤǤ¹¡£"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: ÂèÆó°ú¿ô¤¬ÇÛÎó¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: Âè»°°ú¿ô¤Ë¶õÎó¤ò»ÈÍѤ¹¤ë¤Î¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' ¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "`%s' ÉÕ¶á¤Î FIELDWIDTHS Ãͤ¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "`FS' ¤Ë¶õÎó¤ò»ÈÍѤ¹¤ë¤Î¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `%s' ¤ÏÛ£Ëæ¤Ç¤¹¡£\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `--%s' ¤Ë°ú¿ô¤Ï¤¢¤ê¤Þ¤»¤ó¡£\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `%c%s' ¤Ë°ú¿ô¤Ï¤¢¤ê¤Þ¤»¤ó¡£\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `%s' ¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹¡£\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: ǧ¼±¤Ç¤¤Ê¤¤¥ª¥×¥·¥ç¥ó `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: ǧ¼±¤Ç¤¤Ê¤¤¥ª¥×¥·¥ç¥ó `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: ÉÔÀµ¤Ê¥ª¥×¥·¥ç¥ó -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: ̵¸ú¤Ê¥ª¥×¥·¥ç¥ó -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: °ú¿ô¤¬É¬Íפʥª¥×¥·¥ç¥ó -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `-W %s' ¤ÏÛ£Ëæ¤Ç¤¹¡£\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `-W %s' ¤Ë°ú¿ô¤Ï¤¢¤ê¤Þ¤»¤ó¡£\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "¥Õ¥¡¥¤¥ë `%s' ¤òÆÉ¤ß¹þ¤à¤¿¤á¤Ë³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "fd %d (`%s') ¤òÊĤ¸¤ë¤³¤È¤¬¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "redirect() ¤ÎÃæ¤ÇÉÔÀµ¤Ê¥Ä¥ê¡¼¥¿¥¤¥× %s ¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "`%s' ¥ê¥À¥¤¥ì¥¯¥È¤ÎÌ¿Îá¼°¤Ë¿ôÃͤ·¤«µ½Ò¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "`%s' ¥ê¥À¥¤¥ì¥¯¥È¤ÎÌ¿Îá¼°¤¬¶õÎó¤Ç¤¹¡£"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"`%2$s' ¥ê¥À¥¤¥ì¥¯¥È¤ËÏÀÍý±é»»¤Î·ë²Ì¤È»×¤ï¤ì¤ë¥Õ¥¡¥¤¥ë̾ `%1$s' ¤¬»È¤ï¤ì¤Æ¤¤¤Þ"
+"¤¹¡£"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "¥Õ¥¡¥¤¥ë `%.*s' ¤ÇɬÍװʾå¤Ë `>' ¤È `>>' ¤òÁȹ礻¤Æ¤¤¤Þ¤¹¡£"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "½ÐÎÏÍѤ˥ѥ¤¥× `%s' ¤ò³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "ÆþÎÏÍѤ˥ѥ¤¥× `%s' ¤ò³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "Æþ½ÐÎÏÍѤÎÁÐÊý¸þ¥½¥±¥Ã¥È `%s' ¤¬³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "Æþ½ÐÎÏÍѤÎÁÐÊý¸þ¥Ñ¥¤¥× `%s' ¤¬³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "`%s' ¤«¤é¥ê¥À¥¤¥ì¥¯¥È¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "`%s' ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"³«¤¤¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Î¿ô¤¬¥·¥¹¥Æ¥àÀ©¸Â¤Ë㤷¤Þ¤·¤¿¡£¥Õ¥¡¥¤¥ëµ½Ò»Ò¤ò¿½Å²½¤·¤Þ"
+"¤¹¡£"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "`%s' ¤¬ÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "³«¤¤¤Æ¤¤¤ë¥Ñ¥¤¥×¤Þ¤¿¤ÏÆþÎÏ¥Õ¥¡¥¤¥ë¤Î¿ô¤¬Â¿²á¤®¤Þ¤¹¡£"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: ÂèÆó°ú¿ô¤Ë»ÈÍѤǤ¤ë¤Î¤Ï `to' ¤Þ¤¿¤Ï `from' ¤Ç¤¹¡£"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+"close: `%.*s' ¤Ï¥Õ¥¡¥¤¥ë¡¢¥Ñ¥¤¥×¡¢ÊÂ¹Ô¥×¥í¥»¥¹¤Î¤¤¤º¤ì¤Ç¤â¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "³«¤¤¤Æ¤Ê¤¤¥ê¥À¥¤¥ì¥¯¥È¤òÊĤ¸¤è¤¦¤È¤·¤Æ¤¤¤Þ¤¹¡£"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: ¥ê¥À¥¤¥ì¥¯¥È `%s' ¤Ï `|&' ¤ò»È¤Ã¤Æ¤¤¤Þ¤»¤ó¡£ÂèÆó°ú¿ô¤Ï̵»ë¤·¤Þ¤¹¡£"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "¥Ñ¥¤¥× `%2$s' ¤òÊĤ¸¤¿¤È¤¤Î¾õÂÖ¥³¡¼¥É¤¬¼ºÇÔ (%1$d) ¤Ç¤·¤¿ (%3$s)¡£"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "¥Õ¥¡¥¤¥ë `%2$s' ¤òÊĤ¸¤¿¤È¤¤Î¾õÂÖ¥³¡¼¥É¤¬¼ºÇÔ (%1$d) ¤Ç¤·¤¿ (%3$s)¡£"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "¥½¥±¥Ã¥È `%s' ¤òÌÀ¼¨¤·¤ÆÊĤ¸¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "ÊÂ¹Ô¥×¥í¥»¥¹ `%s' ¤òÌÀ¼¨¤·¤ÆÊĤ¸¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "¥Ñ¥¤¥× `%s' ¤òÌÀ¼¨¤·¤ÆÊĤ¸¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "¥Õ¥¡¥¤¥ë `%s' ¤òÌÀ¼¨¤·¤ÆÊĤ¸¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "ɸ½à½ÐÎϤؤνñ¹þ¤ß¥¨¥é¡¼ (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "ɸ½à¥¨¥é¡¼¤Ø¤Î½ñ¹þ¤ß¥¨¥é¡¼ (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "¥Ñ¥¤¥× `%s' ¤ò¥Õ¥é¥Ã¥·¥å¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "`%s' ¤ØÀܳ¤¹¤ë¥Ñ¥¤¥×¤òÊÂ¹Ô¥×¥í¥»¥¹¤«¤é¥Õ¥é¥Ã¥·¥å¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "¥Õ¥¡¥¤¥ë `%s' ¤ò¥Õ¥é¥Ã¥·¥å¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "»Äǰ¤Ê¤¬¤é¡¢/inet/raw ¥¯¥é¥¤¥¢¥ó¥È¤Î½àÈ÷¤¬¤Ç¤¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "`/inet/raw' ¤Ï root ¥æ¡¼¥¶¡¼¤Î¤ß»ÈÍѤǤ¤Þ¤¹¡£"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "»Äǰ¤Ê¤¬¤é¡¢/inet/raw ¥µ¡¼¥Ð¡¼¤Î½àÈ÷¤¬¤Ç¤¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+"¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë̾ `%s' ¤Ë¡Êǧ¼±¤Ç¤¤ë¡Ë¥×¥í¥È¥³¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë̾ `%s' ¤ÏÉÔ´°Á´¤Ç¤¹¡£"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "`%s' ¤Î¥í¡¼¥«¥ë¥Ý¡¼¥È¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "`/inet' ¤Ë¤Ï¥ê¥â¡¼¥È¥Û¥¹¥È̾¤¬É¬ÍפǤ¹¡£"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "`/inet' ¤Ë¤Ï¥ê¥â¡¼¥È¥Ý¡¼¥ÈÈֹ椬ɬÍפǤ¹¡£"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "`%s' ¤Î¥ê¥â¡¼¥È¥Ý¡¼¥È¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP Àܳ¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "¥Õ¥¡¥¤¥ë `%s' ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "`%2$s' ¤ÎÂå¤ï¤ê¤Ë `PROCINFO[\"%1$s\"]' ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "`/dev/user' ¤ÎÂå¤ï¤ê¤Ë `PROCINFO[...]' ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "`%s' (¥â¡¼¥É `%s') ¤ò³«¤±¤Þ¤»¤ó¡£"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "¥Þ¥¹¥¿¡¼ pty ¤òÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬É¸½à½ÐÎϤòÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬¥¹¥ì¡¼¥Ö pty ¤òɸ½à½ÐÎÏ¤Ë°ÜÆ°¤Ç¤¤Þ¤»¤ó (dup: %s)¡£"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬É¸½àÆþÎϤòÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬¥¹¥ì¡¼¥Ö pty ¤òɸ½àÆþÎÏ¤Ë°ÜÆ°¤Ç¤¤Þ¤»¤ó (dup: %s)¡£"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "¥¹¥ì¡¼¥Ö pty ¤òÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬¥Ñ¥¤¥×¤òɸ½à½ÐÎÏ¤Ë°ÜÆ°¤Ç¤¤Þ¤»¤ó (dup: %s)¡£"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "»Ò¥×¥í¥»¥¹¤¬¥Ñ¥¤¥×¤òɸ½àÆþÎÏ¤Ë°ÜÆ°¤Ç¤¤Þ¤»¤ó (dup: %s)¡£"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "¿Æ¥×¥í¥»¥¹¤¬É¸½à½ÐÎϤòÉüµì¤Ç¤¤Þ¤»¤ó¡£\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "¿Æ¥×¥í¥»¥¹¤¬É¸½àÆþÎϤòÉüµì¤Ç¤¤Þ¤»¤ó¡£\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "¥Ñ¥¤¥×¤òÊĤ¸¤é¤ì¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' ¤Ï»ÈÍѤǤ¤Þ¤»¤ó¡£"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "¥Ñ¥¤¥× `%s' ¤¬³«¤±¤Þ¤»¤ó (%s)¡£"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "`%s' ÍÑ¤Î»Ò¥×¥í¥»¥¹¤ò¼Â¹Ô¤Ç¤¤Þ¤»¤ó (fork: %s)¡£"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "¥Ç¡¼¥¿¥Õ¥¡¥¤¥ë `%s' ¤Ï¶õ¤Ç¤¹¡£"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "ÆþÎÏÍÑ¥á¥â¥ê¡¼¤ò¤³¤ì°Ê¾å³ÎÊݤǤ¤Þ¤»¤ó¡£"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "ÆþÎÏ¥Õ¥¡¥¤¥ë `%s' ¤òÆÉ¤ß¹þ¤ßÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿: %s¡£"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "Ê£¿ô¤Îʸ»ú¤ò `RS' ¤Ë»ÈÍѤ¹¤ë¤Î¤Ï gawk ÆÃͤγÈÄ¥¤Ç¤¹¡£"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "gawk ¤Ç¤Ï¥ª¥×¥·¥ç¥ó `-m[fr]' ¤Ë¸ú²Ì¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m ¥ª¥×¥·¥ç¥ó¤Î»ÈÍÑË¡: `-m[fr] ¿ôÃÍ'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: ¥ª¥×¥·¥ç¥ó `-W %s' ¤Ïǧ¼±¤Ç¤¤Þ¤»¤ó¡£Ìµ»ë¤·¤Þ¤¹¡£\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "¶õ°ú¿ô¤Î `--source' ¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"´Ä¶ÊÑ¿ô `POSIXLY_CORRECT' ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó `--posix' ¤ò͸ú¤Ë"
+"¤·¤Þ¤¹¡£"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "¥ª¥×¥·¥ç¥ó `--posix' ¤Ï `--traditional' ¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr ""
+"¥ª¥×¥·¥ç¥ó `--posix'/`--traditional' ¤Ï `--non-decimal-data' ¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr ""
+"setuid root ¤Ç %s ¤ò¼Â¹Ô¤¹¤ë¤È¡¢¥»¥¥å¥ê¥Æ¥£¾å¤ÎÌäÂ꤬ȯÀ¸¤¹¤ë¾ì¹ç¤¬¤¢¤ê¤Þ"
+"¤¹¡£"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "ɸ½àÆþÎϤò¥Ð¥¤¥Ê¥ê¥â¡¼¥É¤ËÀßÄê¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "ɸ½à½ÐÎϤò¥Ð¥¤¥Ê¥ê¥â¡¼¥É¤ËÀßÄê¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "ɸ½à¥¨¥é¡¼¤ò¥Ð¥¤¥Ê¥ê¥â¡¼¥É¤ËÀßÄê¤Ç¤¤Þ¤»¤ó (%s)¡£"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "¥×¥í¥°¥é¥àʸ¤¬Á´¤¯¤¢¤ê¤Þ¤»¤ó!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"»È¤¤Êý: %s [POSIX ¤Þ¤¿¤Ï GNU ·Á¼°¥ª¥×¥·¥ç¥ó] -f ¥×¥í¥°¥é¥à¥Õ¥¡¥¤¥ë [--] ÆþÎÏ"
+"¥Õ¥¡¥¤¥ë ¡Ä\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"»È¤¤Êý: %s [POSIX ¤Þ¤¿¤Ï GNU ·Á¼°¥ª¥×¥·¥ç¥ó] [--] %c¥×¥í¥°¥é¥à%c ÆþÎÏ¥Õ¥¡¥¤"
+"¥ë ¡Ä\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "POSIX ¥ª¥×¥·¥ç¥ó:\t\tGNU Ĺ·Á¼°¥ª¥×¥·¥ç¥ó\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f ¥×¥í¥°¥é¥à¥Õ¥¡¥¤¥ë\t\t--file=¥×¥í¥°¥é¥à¥Õ¥¡¥¤¥ë\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr ""
+"\t-F ¥Õ¥£¡¼¥ë¥É¥»¥Ñ¥ì¡¼¥¿\t\t\t--field-separator=¥Õ¥£¡¼¥ë¥É¥»¥Ñ¥ì¡¼¥¿\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v ÊÑ¿ô=ÂåÆþÃÍ\t\t--assign=ÊÑ¿ô=ÂåÆþÃÍ\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] ¿ôÃÍ\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=¥Õ¥¡¥¤¥ë]\t--dump-variables[=¥Õ¥¡¥¤¥ë]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=¥Õ¥¡¥¤¥ë\t\t--exec=¥Õ¥¡¥¤¥ë\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=¥Õ¥¡¥¤¥ë]\t--profile[=¥Õ¥¡¥¤¥ë]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=¥×¥í¥°¥é¥àʸ\t--source=¥×¥í¥°¥é¥àʸ\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"¥Ð¥°¤òÊó¹ð¤¹¤ë¤Ë¤Ï¡¢`gawk.info¡Ê±Ñʸ¡Ë' ¤Î `Bugs' ¥Î¡¼¥É¤ò\n"
+"»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ °õºþ¤µ¤ì¤¿¥Þ¥Ë¥å¥¢¥ë¤ÇÂбþ¤¹¤ë¥»¥¯¥·¥ç¥ó\n"
+"¤Ï¡¢`Reporting Problems and Bugs' ¤Ç¤¹¡£\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk ¤Ï¡¢¥Ñ¥¿¡¼¥ó¤ò¸¡º÷¡¢¤½¤·¤Æ½èÍý¤¹¤ë¸À¸ì¤Ç¤¹¡£\n"
+"¥Ç¥Õ¥©¥ë¥ÈÀßÄê¤Ç¤Ï¡¢É¸½àÆþÎϤòÆÉ¤ß¹þ¤ß¡¢É¸½à½ÐÎϤ˽ñ¤½Ð¤·¤Þ¤¹¡£\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"»ÈÍÑÎã:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' ÆþÎÏ¥Õ¥¡¥¤¥ë\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"ËÜ¥×¥í¥°¥é¥à¤Ï¥Õ¥ê¡¼¡¦¥½¥Õ¥È¥¦¥¨¥¢¤Ç¤¹¡£Free Software Foundation ¸øÉ½¤Î\n"
+"GNU General Public License¡Ê¥Ð¡¼¥¸¥ç¥ó£²¡¢¤Þ¤¿¤Ï¡¢¤³¤ì°Ê¸å¤Î¥Ð¡¼¥¸¥ç¥ó¡Ë\n"
+"¤Ë½¾¤¤ºÆÇÛÉÛ¡¢µÚ¤Ó/¤Þ¤¿¤Ï¡¢Êѹ¹¤ò²Ã¤¨¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"ËÜ¥×¥í¥°¥é¥à¤Ï¡¢ÍøÍѲÁÃͤ¬¤¢¤ë¤³¤È¤ò´üÂÔ¤·¤ÆÇÛÉÛ¤µ¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢\n"
+"¤³¤ì¤Ï¡¢ÆÃÄêÌÜŪ¤Ë»ÈÍѲÄǽ¤Ç¤¢¤ë¤³¤È¡¢µÚ¤Ó¡¢¾¦ÍÑÌÜŪ¤Ë»ÈÍѤǤ¤ë\n"
+"¤³¤È¤ò°Å¼¨¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¯¡¢¤¤¤«¤Ê¤ëÊݾڤâ°ìÀÚ¤¢¤ê¤Þ¤»¤ó¡£\n"
+"¾Ü¤·¤¯¤Ï¡¢GNU General Public License ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"ËÜ¥×¥í¥°¥é¥à¤Ë¤Ï¡¢GNU General Public License ¤¬ÅºÉÕ¤µ¤ì¤Æ¤¤¤ë¤Ï¤º¤Ç¤¹¡£\n"
+"¤â¤·¡¢ËÜ¥×¥í¥°¥é¥à¤È°ì½ï¤Ë GNU General Public License ¤òÆþ¼ê¤·¤Ê¤«¤Ã¤¿\n"
+"¾ì¹ç¤Ë¤Ï¡¢\n"
+"\tFree Software Foundation, Inc.,\n"
+"\t59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
+"¤Ø½ñÌ̤ǤªÃΤ餻¤¯¤À¤µ¤¤¡£\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "POSIX »ÅÍͤΠawk ¤Ç¤Ï -Ft ¤Ç FS ¤ò¥¿¥Ö¤ËÀßÄê¤Ç¤¤Þ¤»¤ó¡£"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: ¥ª¥×¥·¥ç¥ó `-v' ¤Î°ú¿ô `%s' ¤¬ `ÊÑ¿ô=ÂåÆþÃÍ' ¤Î·Á¼°¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤»¤ó¡£\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' ¤ÏÉÔÀµ¤ÊÊÑ¿ô̾¤Ç¤¹¡£"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' ¤ÏÊÑ¿ô̾¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£`%s=%s' ¤Î¥Õ¥¡¥¤¥ë¤òõ¤·¤Þ¤¹¡£"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "ÉâÆ°¾®¿ôÅÀÎã³°"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "Ã×̿Ū¥¨¥é¡¼: ÆâÉô¥¨¥é¡¼"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "fd %d ¤¬»öÁ°¤Ë³«¤¤¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "»öÁ°¤Ë fd %d ÍÑ¤Ë /dev/null ¤ò³«¤±¤Þ¤»¤ó¡£"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "¥°¥ë¡¼¥×¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "¥³¥Þ¥ó¥É¥é¥¤¥ó:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "·Ù¹ð: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "¥¨¥é¡¼: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "Ã×̿Ū: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "ʸ»úÎ󤫤éÉâÆ°¾®¿ô¤ËÊÑ´¹¤Ç¤¤Þ¤»¤ó¡£"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "ʸ»úÎó¤Î½ª¤ê¤Ë¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤¬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX ¤Ï `\\x' ¥¨¥¹¥±¡¼¥×¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "`\\x' ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤Ë 16 ¿Ê¿ô¤¬¤¢¤ê¤Þ¤»¤ó¡£"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹ `\\%c' ¤Ï `%c' ¤ÈƱÅù¤Ë°·¤ï¤ì¤Þ¤¹¡£"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': close-on-exec ¤òÀßÄê¤Ç¤¤Þ¤»¤ó: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "`%s' ¤ò½ñ¹þ¤ßÍѤ˳«¤±¤Þ¤»¤ó¤Ç¤·¤¿: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "ÆâÉô¥¨¥é¡¼: %s ¤Î vname ¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# ÆâÉô¤Ç¤Ï `delete' ¤È¤·¤Æ°·¤ï¤ì¤Þ¤·¤¿¡£"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# ¤³¤ì¤ÏưŪ¤Ë¥í¡¼¥É¤µ¤ì¤¿³ÈÄ¥µ¡Ç½¤Ç¤¹¡£"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawk ¥×¥í¥Õ¥¡¥¤¥ë¡¢ºîÀ®Æü»þ %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN ¥Ö¥í¥Ã¥¯\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# ¥ë¡¼¥ë\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END ¥Ö¥í¥Ã¥¯\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# ´Ø¿ô°ìÍ÷¡Ê¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È½ç¡Ë\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "prec_level Ãæ¤Î %s ¤ÏͽÁÛ³°¤Î¥¿¥¤¥×¤Ç¤¹¡£"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "À®¸ù"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "³ºÅö̵¤·"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "̵¸ú¤ÊÀµµ¬É½¸½"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "̵¸ú¤Ê¾È¹çʸ»ú"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "̵¸ú¤Êʸ»ú¥¯¥é¥¹Ì¾"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "ºÇ¸å¤Ë¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤¬ÉÕ¤¤¤Æ¤¤¤Þ¤¹¡£"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "¸åÊý¤Ø¤Î»²¾È¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ ¤Þ¤¿¤Ï [^ ¤¬Âбþ¤·¤Þ¤»¤ó¡£"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( ¤Þ¤¿¤Ï \\( ¤¬Âбþ¤·¤Þ¤»¤ó¡£"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ ¤¬Âбþ¤·¤Þ¤»¤ó¡£"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "\\{\\} ¤ÎÆâÍÆ¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "ÈϰϻØÄê¤Î½ªÃ¼¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó¡£"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Àè¹Ô¤ÎÀµµ¬É½¸½¤¬Ìµ¸ú¤Ç¤¹¡£"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Àµµ¬É½¸½¤¬½ªÃ¼¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Àµµ¬É½¸½¤¬Ä¹²á¤®¤Þ¤¹¡£"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") ¤Þ¤¿¤Ï \\) ¤¬Âбþ¤·¤Þ¤»¤ó¡£"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "¤³¤ì¤è¤êÁ°¤Ë»ÈÍѤ·¤¿Àµµ¬É½¸½¤Ï¤¢¤ê¤Þ¤»¤ó¡£"
--- /dev/null
+# Translation of gawk-3.1.4l to Dutch.
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# Benno Schulenberg <benno@nietvergeten.nl>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-24 22:39+0200\n"
+"Last-Translator: Benno Schulenberg <benno@nietvergeten.nl>\n"
+"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.10.1\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "functie '%s' wordt gebruikt als array"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "scalaire parameter '%s' wordt gebruikt als array"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "scalair '%s' wordt gebruikt als array"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "van %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "verwijzing naar ongeïnitialiseerd element '%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "index van array '%s' is lege string"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: index '%s' niet in array '%s' "
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: leeg (nil)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: leeg (nul)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: tabelgrootte = %d, arraygrootte = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: is een parameter\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array-verwijzing naar %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "%s-blokken horen een actiedeel te hebben"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "elke regel hoort een patroon of een actiedeel te hebben"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "'%s' is een ingebouwde functie en is niet te herdefiniëren"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "regexp-constante '/s/' lijkt C-commentaar, maar is het niet"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "regexp-constante '/%s/' lijkt C-commentaar, maar is het niet"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "opdracht heeft mogelijk geen effect"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "'%s' wordt gebruikt in %s-actie"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "'nextfile' is een gawk-uitbreiding"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "'return' wordt gebruikt buiten functiecontext"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"kale 'print' in BEGIN- of END-regel moet vermoedelijk 'print \"\"' zijn"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "'delete array' is een gawk-uitbreiding"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "'delete(array)' is een niet-overdraagbare tawk-uitbreiding"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "dubbele case-waarde in switch-opdracht: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "dubbele 'default' in switch-opdracht"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "meerfase-tweerichtings-pipelines werken niet"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "reguliere expressie rechts van toewijzing"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "reguliere expressie links van '~' of '!~' operator"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "reguliere expressie rechts van vergelijking"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "onherverwezen 'getline' is ongedefinieerd binnen END-actie"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "aanroep van 'length' zonder haakjes is niet overdraagbaar"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "aanroep van 'length' zonder haakjes wordt door POSIX afgeraden"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "non-array wordt gebruikt als array"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "ongeldige index-expressie"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "onverwacht regeleinde of einde van string"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "lege programmatekst op commandoregel"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "kan bronbestand '%s' niet openen om te lezen (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "kan bronbestand '%s' niet lezen (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "bronbestand '%s' is leeg"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "bronbestand eindigt niet met een regeleinde"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "onafgesloten reguliere expressie eindigt met '\\' aan bestandseinde"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "%s: %d: regex-optie '/.../%c' van tawk werkt niet in gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "regex-optie '/.../%c' van tawk werkt niet in gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "onafgesloten reguliere expressie"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "onafgesloten reguliere expressie aan bestandseinde"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "gebruik van regelvoortzetting '\\ #...' is niet overdraagbaar"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "backslash is niet het laatste teken op de regel"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX staat operator '**=' niet toe"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "oude awk ondersteunt operator '**=' niet"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX staat operator '**' niet toe"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "oude awk ondersteunt operator '**' niet"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "oude awk ondersteunt operator '^=' niet"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "oude awk ondersteunt operator '^' niet"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "onafgesloten string"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "ongeldig teken '%c' in expressie"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "'%s' is een gawk-uitbreiding"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "'%s' is een uitbreiding door Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX staat '%s' niet toe"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "oude awk ondersteunt '%s' niet"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "'goto' wordt als schadelijk beschouwd!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d is een ongeldig aantal argumenten voor %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: derde argument is een gawk-uitbreiding"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: een stringwaarde als laatste vervangingsargument heeft geen effect"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "%s: derde parameter is geen veranderbaar object"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: tweede argument is een gawk-uitbreiding"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dcgettext(_\"...\") is onjuist: verwijder het liggende streepje"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dcngettext(_\"...\") is onjuist: verwijder het liggende streepje"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "functie '%s': parameter #%d, '%s', dupliceert parameter #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "functie '%s': parameter '%s' schaduwt een globale variabele"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "kan '%s' niet openen om te schrijven (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "profiel gaat naar standaardfoutuitvoer"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: sluiten is mislukt (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() twee keer aangeroepen!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "er waren geschaduwde variabelen."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "functie '%s': kan functienaam niet als parameternaam gebruiken"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "functienaam '%s' is al eerder gedefinieerd"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "functie '%s' aangeroepen maar nergens gedefinieerd"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "functie '%s' gedefinieerd maar nergens aangeroepen"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "regexp-constante als parameter #%d levert booleanwaarde op"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"functie '%s' aangeroepen met spatie tussen naam en '(',\n"
+"of gebruikt als variabele of array"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s naar \"%s\" is mislukt (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standaarduitvoer"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "reden onbekend"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: argument is geen getal"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argument %g ligt buiten toegestane bereik"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kan pipe niet leegmaken: '%s' is geopend om te lezen, niet om te "
+"schrijven"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kan bestand niet leegmaken: '%s' is geopend om te lezen, niet om te "
+"schrijven"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: '%s' is geen geopend bestand, pipe, of co-proces"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: eerste argument is geen string"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: tweede argument is geen string"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: argument is geen getal"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "'delete array' is een gawk-uitbreiding"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: argument is geen string"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: argument is geen getal"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: argument %g is negatief"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "'count$' hoort in alle opmaken gebruikt te worden, of in geen"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "'$' is niet toegestaan in awk-opmaak"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "het aantal argumenten met '$' moet > 0 zijn"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "argumentental %ld is groter dan het gegeven aantal argumenten"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "'$' is niet toegestaan na een punt in de opmaak"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "geen '$' opgegeven bij positionele veldbreedte of -precisie"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "'l' is betekenisloos in awk-opmaak; genegeerd"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "'l' is niet toegestaan in POSIX awk-opmaak"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "'L' is betekenisloos in awk-opmaak; genegeerd"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "'L' is niet toegestaan in POSIX awk-opmaak"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "'h' is betekenisloos in awk-opmaak; genegeerd"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "'h' is niet toegestaan in POSIX awk-opmaak"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: waarde %g ligt buiten toegestaan bereik voor opmaak '%%%c'"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "niet genoeg argumenten voor opmaakstring"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "niet genoeg ^ voor deze"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: opmaakaanduiding mist een stuurletter"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "te veel argumenten voor opmaakstring"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: geen argumenten"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: argument is geen getal"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: argument %g is negatief"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: startindex %g is ongeldig, 1 wordt gebruikt"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: startindex %g is geen integer, wordt afgekapt"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: lengte %g is niet >= 1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: lengte %g is niet >= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: lengte %g is geen integer, wordt afgekapt"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+"substr: lengte %g is te groot voor stringindexering, wordt verkort tot %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: bronstring heeft lengte nul"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: startindex %g ligt voorbij het einde van de string"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: lengte %g bij startindex %g is groter dan de lengte van het eerste "
+"argument (%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: eerste argument is geen string"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: opmaakstring is leeg"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: tweede argument is geen getal"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: argument is geen string"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: argument is geen string"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "verwijzing naar ongeïnitialiseerd veld '$%d'"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: argument is geen string"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: argument is geen string"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: eerste argument is geen getal"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: tweede argument is geen getal"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: argument is geen getal"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: argument is geen getal"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: argument is geen getal"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: derde argument is geen array"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: derde argument is 0, wordt beschouwd als 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: eerste argument is geen getal"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: tweede argument is geen getal"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): te grote opschuifwaarden geven rare resultaten"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: eerste argument is geen getal"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: tweede argument is geen getal"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): te grote opschuifwaarden geven rare resultaten"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: eerste argument is geen getal"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: tweede argument is geen getal"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: eerste argument is geen getal"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: tweede argument is geen getal"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: eerste argument is geen getal"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: tweede argument is geen getal"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: argument is geen getal"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): negatieve waarden geven rare resultaten"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): cijfers na de komma worden afgekapt"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: '%s' is geen geldige lokale categorie"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "onbekend nodetype %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "bufferoverloop in genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "array '%s' wordt gebruikt in een scalaire context"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for: array '%s' veranderde van grootte %ld naar %ld tijdens uitvoer van de "
+"lus"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "'break' buiten een lus is niet overdraagbaar"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "'break' buiten een lus is niet toegestaan"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "'continue' buiten een lus is niet overdraagbaar"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "'continue' buiten een lus is niet toegestaan"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "'next' kan niet aangeroepen worden in een BEGIN-regel"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "'next' kan niet aangeroepen worden in een END-regel"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "'nextfile' kan niet aangeroepen worden in een BEGIN-regel"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "'nextfile' kan niet aangeroepen worden in een END-regel"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "opdracht heeft geen effect"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "kan functienaam '%s' niet als variabele of array gebruiken"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "verwijzing naar ongeïnitialiseerd argument '%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "verwijzing naar ongeïnitialiseerde variabele '%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation: neveneffecten in de ene expressie hebben de lengte van een "
+"andere veranderd!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "toewijzing wordt gebruikt in een conditionele context"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "deling door nul"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "deling door nul in '%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "ongeldig type (%s) in tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "deling door nul in '/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "deling door nul in '%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "functie '%s' aangeroepen met meer argumenten dan gedeclareerd"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "functie '%s' is niet gedefinieerd"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Functieaanroepen-stack:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- hoofd --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "veldverwijzingspoging via een waarde die geen getal is"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "verwijzingspoging via een lege string"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "toegangspoging tot veld %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr ""
+"toewijzing aan het resultaat van een ingebouwde functie is niet toegestaan"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "'IGNORECASE' is een gawk-uitbreiding"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "'BINMODE' is een gawk-uitbreiding"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "onjuiste opgave van '%sFMT': '%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "'--lint' wordt uitgeschakeld wegens toewijzing aan 'LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "'extension' is een gawk-uitbreiding"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: kan '%s' niet openen (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: bibliotheek '%s': kan functie '%s' niet aanroepen (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: ontbrekende functienaam"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: ongeldig teken '%c' in functienaam '%s'"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: kan functie '%s' niet herdefiniëren"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: functie '%s' is al gedefinieerd"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr "extension: kan in gawk ingebouwde '%s' niet als functienaam gebruiken"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: functienaam '%s' is al eerder gedefinieerd"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr ""
+"functie '%s' is gedefinieerd om niet meer dan %d argument(en) te accepteren"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "functie '%s': ontbrekend argument #%d"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "functie '%s': argument #%d: een scalair wordt gebruikt als array"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "functie '%s': argument #%d: een array wordt gebruikt als scalair"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Actie wordt niet ondersteund"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF is op een negatieve waarde gezet"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: tweede argument is geen array"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: lege string als derde argument is een gawk-uitbreiding"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "'FIELDWIDTHS' is een gawk-uitbreiding"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "ongeldige waarde voor FIELDWIDTHS, nabij '%s'"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "een lege string als 'FS' is een gawk-uitbreiding"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: optie '%s' is niet eenduidig\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: optie '--%s' staat geen argument toe\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: optie '%c%s' staat geen argument toe\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: optie '%s' vereist een argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: onbekende optie '--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: onbekende optie '%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: ongeldige optie -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: ongeldige optie -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: optie vereist een argument -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: optie '-W %s' is niet eenduidig\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: optie '-W %s' staat geen argument toe\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "kan bestand '%s' niet openen om te lezen (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "sluiten van fd %d ('%s') is mislukt (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "ongeldig boomtype %s in redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "expressie in omleiding '%s' heeft alleen een getal als waarde"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "expressie voor omleiding '%s' heeft een lege string als waarde"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"bestandsnaam '%s' voor omleiding '%s' kan het resultaat zijn van een "
+"logische expressie"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "onnodige mix van '>' en '>>' voor bestand '%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "kan pipe '%s' niet openen voor uitvoer (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "kan pipe '%s' niet openen voor invoer (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "kan tweerichtings-socket '%s' niet openen voor invoer/uitvoer (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "kan tweerichtings-pipe '%s' niet openen voor invoer/uitvoer (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "kan niet omleiden van '%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "kan niet omleiden naar '%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"systeemgrens voor aantal open bestanden is bereikt: begonnen met multiplexen"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "sluiten van '%s' is mislukt (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "te veel pipes of invoerbestanden geopend"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: tweede argument moet 'to' of 'from' zijn"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: '%.*s' is geen open bestand, pipe, of co-proces"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "sluiten van een nooit-geopende omleiding"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: omleiding '%s' is niet geopend met '|&'; tweede argument genegeerd"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "afsluitwaarde %d bij mislukte sluiting van pipe '%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "afsluitwaarde %d bij mislukte sluiting van bestand '%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "geen expliciete sluiting van socket '%s' aangegeven"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "geen expliciete sluiting van co-proces '%s' aangegeven"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "geen expliciete sluiting van pipe '%s' aangegeven"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "geen expliciete sluiting van bestand '%s' aangegeven"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "fout tijdens schrijven van standaarduitvoer (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "fout tijdens schrijven van standaardfoutuitvoer (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "leegmaken van pipe '%s' is mislukt (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "leegmaken door co-proces van pipe naar '%s' is mislukt (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "leegmaken van bestand '%s' is mislukt (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "cliënt van /inet/raw is nog niet klaar, sorry"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "alleen root mag '/inet/raw' gebruiken."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "server van /inet/raw is nog niet klaar, sorry"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "geen (bekend) protocol aangegeven in speciale bestandsnaam '%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "speciale bestandsnaam '%s' is onvolledig"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "ongeldige lokale poort in '%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "'/inet' heeft een gindse hostnaam nodig"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "'/inet' heeft een gindse poort nodig"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "ongeldige gindse poort in '%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP-communicatie wordt niet ondersteund"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "bestand '%s' is een map"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "gebruik 'PROCINFO[\"%s\"]' in plaats van '%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "gebruik 'PROCINFO[...]' in plaats van '/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "kan '%s' niet openen, modus '%s'"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "kan meester-pty van kindproces niet sluiten (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "kan standaarduitvoer van kindproces niet sluiten (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"kan slaaf-pty niet overzetten naar standaarduitvoer van kindproces (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "kan standaardinvoer van kindproces niet sluiten (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"kan slaaf-pty niet overzetten naar standaardinvoer van kindproces (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "kan slaaf-pty niet sluiten (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+"kan pipe niet overzetten naar standaarduitvoer van kindproces (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "kan pipe niet overzetten naar standaardinvoer van kindproces (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "kan standaarduitvoer van ouderproces niet herstellen\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "kan standaardinvoer van ouderproces niet herstellen\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "kan pipe niet sluiten (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "'|&' wordt niet ondersteund"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "kan pipe '%s' niet openen (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "kan voor '%s' geen kindproces maken (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "databestand '%s' is leeg"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "kan geen extra invoergeheugen meer toewijzen"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "fout tijdens lezen van invoerbestand '%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "een 'RS' van meerdere tekens is een gawk-uitbreiding"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "optie '-m[fr]' is irrelevant in gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "gebruikswijze van optie -m: '-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: optie '-W %s' is onbekend; genegeerd\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "argument van '--source' is leeg; genegeerd"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "omgevingsvariabele 'POSIXLY_CORRECT' is gezet: '--posix' ingeschakeld"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "'--posix' overstijgt '--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "'--posix'/'--traditional' overstijgen '--non-decimal-data'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "het uitvoeren van %s als setuid root kan een veiligheidsrisico zijn"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "kan standaardinvoer niet in binaire modus plaatsen (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "kan standaarduitvoer niet in binaire modus plaatsen (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "kan standaardfoutuitvoer niet in binaire modus plaatsen (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "helemaal geen programmatekst!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Gebruik: %s [opties in POSIX- of GNU-stijl] -f programmabestand [--] "
+"bestand ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Gebruik: %s [opties in POSIX- of GNU-stijl] [--] %cprogramma%c bestand ...\n"
+"\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "\tPOSIX-opties:\t\t\tlange GNU-opties:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f programmabestand\t\t--file=programmabestand\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F veldscheidingsteken\t\t--field-separator=veldscheidingsteken\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=waarde\t\t\t--assign=var=waarde\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] waarde\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=bestand]\t--dump-variables[=bestand]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=bestand\t\t\t--exec=bestand\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=bestand]\t\t--profile[=bestand]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=programmatekst\t--source=programmatekst\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Voor het rapporteren van gebreken, zie de node 'Bugs' in 'gawk.info',\n"
+"ofwel de sectie 'Reporting Problems and Bugs' in de gedrukte versie.\n"
+"Meld fouten in de vertaling aan <vertaling@vrijschrift.org>.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk is een patroonherkennings- en bewerkingsprogramma.\n"
+"Bij verstek leest het standaardinvoer en schrijft naar standaarduitvoer.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Voorbeelden:\n"
+"\tgawk '{ som += $1 }; END { print som }' bestand\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Dit is vrije programmatuur; u mag het verspreiden en/of wijzigen\n"
+"onder de voorwaarden van de GNU General Public License zoals uitgegeven\n"
+"door de Free Software Foundation; naar keuze ofwel onder versie 2\n"
+"of onder een nieuwere versie van die licentie.\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Dit programma wordt uitgegeven in de hoop dat het bruikbaar is,\n"
+"maar ZONDER ENIGE GARANTIE; zelfs zonder de impliciete garantie\n"
+"van VERKOOPBAARHEID of GESCHIKTHEID VOOR EEN BEPAALD DOEL.\n"
+"Zie de GNU General Public License voor nadere details.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Bij dit programma hoort u een kopie van de GNU General Public License\n"
+"ontvangen te hebben; is dat niet het geval, schrijf dan naar\n"
+"Free Software Foundation, Inc., 51 Franklin Street, fifth floor\n"
+"Boston, MA 02110-1301, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft maakt van FS geen tab in POSIX awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: argument '%s' van '-v' is niet van de vorm 'var=waarde'\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "'%s' is geen geldige variabelenaam"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "'%s' is geen variabelenaam, zoekend naar bestand '%s=%s'"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "drijvende-komma-berekeningsfout"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "fatale fout: interne fout"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "geen reeds-geopende fd %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "kan /dev/null niet openen voor fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "kan groepen niet vinden: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "commandoregel:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "waarschuwing: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "fout: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fataal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "kan string niet naar drijvende-komma-getal converteren"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "backslash aan het einde van de string"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX staat geen '\\x' stuurcodes toe"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "geen hex cijfers in stuurcodereeks '\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "stuurcodereeks '\\%c' behandeld als normale '%c'"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s '%s': kan close-on-exec niet activeren: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "kan '%s' niet openen om te schrijven: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "interne fout: %s heeft een lege vname"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# wordt intern behandeld als 'delete'"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# dit is een dynamisch geladen uitbreidingsfunctie"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawk-profiel, gemaakt %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN-blok(ken)\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regel(s)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END-blok(ken)\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Functies, alfabetisch geordend\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "onverwacht type %s in prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Gelukt"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Geen overeenkomsten"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Ongeldige reguliere expressie"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Ongeldig verbindingsteken"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Ongeldige tekenklassenaam"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Backslash aan het eind"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Ongeldige terugverwijzing"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Ongepaarde [ of [^"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Ongepaarde ( of \\("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Ongepaarde \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Ongeldige inhoud van \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Ongeldig reekseinde"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Onvoldoende geheugen"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Ongeldige voorafgaande reguliere expressie"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Voortijdig einde van reguliere expressie"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Reguliere expressie is te groot"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Ongepaarde ) of \\)"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Geen eerdere reguliere expressie"
--- /dev/null
+# Polish translations for GNU AWK package.
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+# Wojciech Polak <polak@gnu.org>, 2003, 2004, 2005.
+# additional help by Sergey Poznyakoff <gray@gnu.org>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-26 23:55+0200\n"
+"Last-Translator: Wojciech Polak <polak@gnu.org>\n"
+"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "próba u¿ycia funkcji `%s' jako tablicy"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "próba u¿ycia parametru `%s' skalaru jako tablicy"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "próba u¿ycia skalaru `%s' jako tablicy"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "od %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "odwo³anie do niezainicjowanego elementu `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "indeks tablicy `%s' jest zerowym ³añcuchem"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: indeks `%s' nie jest w tablicy `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: pusty (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: pusty (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: jest parametrem\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array_ref do %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "%s bloków musi posiadaæ czê¶æ dotycz±c± akcji"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "ka¿da regu³a musi posiadaæ wzorzec lub czê¶æ dotycz±c± akcji"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr ""
+"`%s' jest funkcj± wbudowan±, wiêc nie mo¿e zostaæ ponownie zdefiniowana"
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"sta³e wyra¿enie regularne `//' wygl±da jak komentarz C++, ale nim nie jest"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"sta³e wyra¿enie regularne `/%s/' wygl±da jak komentarz C, ale nim nie jest"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "instrukcja mo¿e nie mieæ ¿adnego efektu"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s' u¿yty w akcji %s"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' jest rozszerzeniem gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' u¿yty poza kontekstem funkcji"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"zwyk³y `print' w regu³ach BEGIN lub END powinien prawdopodobnie byæ jako "
+"`print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete tablica' jest rozszerzeniem gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete(tablica)' jest nieprzeno¶nym rozszerzeniem tawk"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "powielone warto¶ci case w ciele switch: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "wykryto powielony `default' w ciele switch"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "wieloetapowe dwukierunkowe linie potokowe nie dzia³aj±"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "wyra¿anie regularne po prawej stronie przypisania"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "wyra¿enie regularne po lewej stronie operatora `~' lub `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "wyra¿enie regularne po prawej stronie porównania"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr ""
+"komenda `getline' bez przekierowania nie jest zdefiniowana wewn±trz akcji END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "wywo³anie `length' bez nawiasów jest nieprzeno¶ne"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "wywo³anie `length' bez podania nawiasów jest niezalecane przez POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "u¿ycie nie-tablicy jako tablicy"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "nieprawid³owe wyra¿enie indeksowe"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "niespodziewany znak nowego wiersza lub koñca ³añcucha"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "pusty tekst programu w linii poleceñ"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "nie mo¿na otworzyæ pliku ¼ród³owego `%s' do czytania (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "nie mo¿na otworzyæ pliku ¼ród³owego `%s' (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "plik ¼ród³owy `%s' jest pusty"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "plik ¼ród³owy nie posiada na koñcu znaku nowego wiersza"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+"niezakoñczone prawid³owo wyra¿enie regularne koñczy siê znakiem `\\' na "
+"koñcu pliku"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"%s: %d: modyfikator wyra¿enia regularnego `/.../%c' tawk nie dzia³a w gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr "modyfikator wyra¿enia regularnego `/.../%c' tawk nie dzia³a w gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "niezakoñczone wyra¿enie regularne"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "niezakoñczone wyra¿enie regularne na koñcu pliku"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "u¿ycie `\\ #...' kontynuacji linii nie jest przeno¶ne"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "backslash nie jest ostatnim znakiem w wierszu"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX nie zezwala na operator `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "stary awk nie wspiera operatora `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX nie zezwala na operator `**'"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "stary awk nie wspiera operatora `**'"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "operator `^=' nie jest wspierany w starym awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "operator `^' nie jest wspierany w starym awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "niezakoñczony ³añcuch"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "nieprawid³owy znak '%c' w wyra¿eniu"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' jest rozszerzeniem gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' jest rozszerzeniem Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX nie zezwala na `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' nie jest wspierany w starym awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' uwa¿ane za szkodliwe!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d jest nieprawid³owe jako liczba argumentów dla %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: trzeci argument jest rozszerzeniem gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: litera³ ³añcuchowy jako ostatni argument podstawienia nie ma ¿adnego "
+"efektu"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "%s trzeci parametr nie jest zmiennym obiektem"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: drugi argument jest rozszerzeniem gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "nieprawid³owe u¿ycie dcgettext(_\"...\"): usuñ znak podkre¶lenia"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "nieprawid³owe u¿ycie dcngettext(_\"...\"): usuñ znak podkre¶lenia"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funkcja `%s': parametr #%d, `%s', powiela parametr #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "funkcja `%s': parametr `%s' zas³ania globaln± zmienn±"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "nie mo¿na otworzyæ `%s' do zapisu (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "wysy³anie profilu na standardowe wyj¶cie diagnostyczne"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: zamkniêcie nie powiod³o siê (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() wywo³ana podwójnie!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "wyst±pi³y przykryte zmienne."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funkcja `%s': nie mo¿na u¿yæ nazwy funkcji jako nazwy parametru"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nazwa funkcji `%s' zosta³a zdefiniowana poprzednio"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "funkcja `%s' zosta³a wywo³ana, ale nigdy nie zosta³a zdefiniowana"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "funkcja `%s' zosta³a zdefiniowana, ale nigdy nie zosta³a wywo³ana"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "sta³e wyra¿enie regularne dla parametru #%d daje warto¶æ logiczn±"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"funkcja `%s' zosta³a wywo³ana z bia³ymi znakami pomiêdzy jej nazw± a znakiem "
+"`(',\n"
+"lub u¿yta jako zmienna lub jako tablica"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s do \"%s\" nie powiód³ siê (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standardowe wyj¶cie"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "nieznany powód"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: otrzymano argument nie bêd±cy liczb±"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argument %g jest poza zasiêgiem"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: nie mo¿na opró¿niæ: potok `%s' otwarty do czytania, a nie do zapisu"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: nie mo¿na opró¿niæ: plik `%s' otwarty do czytania, a nie do zapisu"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' nie jest ani otwartym plikiem, ani potokiem, ani procesem"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: otrzymano pierwszy argument, który nie jest ³añcuchem"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: otrzymano drugi argument, który nie jest ³añcuchem"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete tablica' jest rozszerzeniem gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: otrzymano argument, który nie jest ³añcuchem"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: otrzymano ujemny argument %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "nale¿y u¿yæ `count$' we wszystkich formatach lub nic"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' jest niedozwolony w formatach awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "argument count z `$' musi byæ > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "argument count %ld wiêkszy ni¿ ca³kowita suma argumentów dostarczonych"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' jest niedozwolony po kropce w formacie"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "brak `$' dla pozycyjnej szeroko¶ci pola lub precyzji"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' jest bezsensowny w formatach awk; zignorowany"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`l' jest niedozwolony w formatach POSIX awk"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' jest bezsensowny w formatach awk; zignorowany"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`L' jest niedozwolony w formatach POSIX awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' jest bezsensowny w formatach awk; zignorowany"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`h' jest niedozwolony w formatach POSIX awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: warto¶æ %g jest poza zasiêgiem dla formatu `%%%c'"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr ""
+"brak wystarczaj±cej liczby argumentów, aby zaspokoiæ ³añcuch formatuj±cy"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "zabrak³o ^"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: specyfikator formatu nie posiada kontrolnej litery"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "zbyt du¿o podanych argumentów w ³añcuchu formatuj±cym"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: brak argumentów"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: wywo³ana z ujemnym argumentem %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: pocz±tkowy indeks %g jest nieprawid³owy, nast±pi u¿ycie 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr ""
+"substr: pocz±tkowy indeks %g, który nie jest liczb± ca³kowit±, zostanie "
+"obciêty"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: d³ugo¶æ %g nie jest >= 1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: d³ugo¶æ %g nie jest >= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: d³ugo¶æ %g, która nie jest liczb± ca³kowit±, zostanie obciêta"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "substr: d³ugo¶æ %g zbyt du¿a dla indeksu ³añcucha, obcinanie do %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: ³añcuch ¼ród³owy ma zerow± d³ugo¶æ"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: pocz±tkowy indeks %g le¿y poza koñcem ³añcucha"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: d³ugo¶æ %g zaczynaj±c od %g przekracza d³ugo¶æ pierwszego argumentu "
+"(%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: otrzymano pierwszy argument, który nie jest ³añcuchem"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: otrzymano pusty ³añcuch formatuj±cy"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: otrzymano argument, który nie jest ³añcuchem"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: otrzymano argument, który nie jest ³añcuchem"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "odwo³anie do niezainicjowanego pola `$%d'"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: otrzymano argument, który nie jest ³añcuchem"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: otrzymano argument, który nie jest ³añcuchem"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: otrzymano trzeci argument, który nie jest tablic±"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: trzeci argument 0 potraktowany jako 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): zbyt du¿a warto¶æ przesuniêcia spowoduje dziwne wyniki"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): zbyt du¿a warto¶æ przesuniêcia spowoduje dziwne wyniki"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: otrzymano pierwszy argument, który nie jest liczb±"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: otrzymano drugi argument, który nie jest liczb±"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: otrzymano argument, który nie jest liczb±"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): ujemne warto¶ci spowoduj± dziwne wyniki"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): u³amkowe warto¶ci zostan± obciête"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' nie jest prawid³ow± kategori± lokalizacji"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "nieznany typ wêz³a %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "przepe³nienie bufora w genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "próba u¿ycia tablicy `%s' w kontek¶cie skalaru"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"pêtla for: tablica `%s' zmieni³a rozmiar z %ld do %ld podczas wykonywania "
+"pêtli"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "instrukcja `break' poza pêtl± jest nieprzeno¶na"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "instrukcja `break' poza pêtl± jest niedozwolona"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "instrukcja `continue' poza pêtl± jest nieprzeno¶na"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "instrukcja `continue' poza pêtl± jest niedozwolona"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "instrukcja `next' nie mo¿e byæ wywo³ana z wnêtrza regu³y BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "instrukcja `next' nie mo¿e byæ wywo³ana z wnêtrza regu³y END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "instrukcja `nextfile' nie mo¿e byæ wywo³ana z wnêtrza regu³y BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "instrukcja `nextfile' nie mo¿e byæ wywo³ana z wnêtrza regu³y END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "instrukcja nie ma ¿adnego efektu"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "nie mo¿na u¿yæ nazwy funkcji `%s' jako zmiennej lub tablicy"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "odwo³anie do niezainicjowanego argumentu `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "odwo³anie do niezainicjowanej zmiennej `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"konkatenacja: skutki uboczne w jednym wyra¿eniu spowodowa³y zmianê d³ugo¶ci "
+"innego wyra¿enia!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "przypisanie u¿yte w kontek¶cie warunkowym"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "próba dzielenia przez zero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "próba dzielenia przez zero w `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "nieprawid³owy typ (%s) w tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "próba dzielenia przez zero w `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "próba dzielenia przez zero w `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr ""
+"funkcja `%s' zosta³a wywo³ana z wiêksz± ilo¶ci± argumentów ni¿ zosta³o to "
+"zadeklarowane"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "funkcja `%s' nie zosta³a zdefiniowana"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Stos Wywo³awczy Funkcji:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- g³ówne --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "próba odwo³ania do pola poprzez nienumeryczn± warto¶æ"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "próba odwo³ania z zerowego ³añcucha"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "próba dostêpu do pola %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "przypisanie do wyniku wbudowanej funkcji nie jest dozwolone"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' jest rozszerzeniem gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' jest rozszerzeniem gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "z³a specyfikacja `%sFMT' `%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "wy³±czenie `--lint' z powodu przypisania do `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' jest rozszerzeniem gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "rozszerzenie: nie mo¿na otworzyæ `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "rozszerzenie: biblioteka `%s': nie mo¿na wywo³aæ funkcji `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "rozszerzenie: brakuj±ca nazwa funkcji"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "rozszerzenie: nieprawid³owy znak `%c' w nazwie funkcji `%s'"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "rozszerzenie: nie mo¿na zredefiniowaæ funkcji `%s'"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "rozserzenie: funkcja `%s' zosta³a ju¿ zdefiniowana"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr "rozszerzenie: nie mo¿na u¿yæ wbudowanej w gawk `%s' jako nazwy funkcji"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "rozserzenie: nazwa funkcji `%s' zosta³a zdefiniowana wcze¶niej"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "funkcja `%s' zdefiniowana aby pobraæ nie wiêcej ni¿ %d argument(ów)"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "funkcja `%s': brakuje #%d argumentu"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "funkcja `%s': argument #%d: próba u¿ycia skalaru jako tablicy"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "funkcja `%s': argument #%d: próba u¿ycia tablicy jako skalaru"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operacja nie jest wspierana"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF ustawiony na warto¶æ ujemn±"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: drugi argument nie jest tablic±"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: zerowy ³añcuch dla trzeciego argumentu jest rozszerzeniem gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' jest rozszerzeniem gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "nieprawid³owa warto¶æ FIELDWIDTHS, w pobli¿u `%s'"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "zerowy ³añcuch dla `FS' jest rozszerzeniem gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: opcja `%s' jest niejednoznaczna\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: opcja `--%s' nie mo¿e mieæ argumentów\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: opcja `%c%s' nie mo¿e mieæ argumentów\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: opcja `%s' musi mieæ argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: nieznana opcja `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: nieznana opcja `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: niew³a¶ciwa opcja -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: b³êdna opcja -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: opcja musi mieæ argument -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: opcja `-W %s' jest niejednoznaczna\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: opcja `-W %s' nie mo¿e mieæ argumentów\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "nie mo¿na otworzyæ pliku `%s' do czytania (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "zamkniêcie fd %d (`%s') nie powiod³o siê (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "nieprawid³owy typ drzewa %s w funkcji redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "wyra¿enie w przekierowaniu `%s' ma tylko warto¶æ numeryczn±"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "wyra¿enie dla przekierowania `%s' ma zerow± warto¶æ ³añcucha"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"nazwa pliku `%s' dla przekierowania `%s' mo¿e byæ rezultatem logicznego "
+"wyra¿enia"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "niepotrzebne mieszanie `>' i `>>' dla pliku `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "nie mo¿na otworzyæ potoku `%s' jako wyj¶cia (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "nie mo¿na otworzyæ potoku `%s' jako wej¶cia (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"nie mo¿na otworzyæ dwukierunkowego gniazda `%s' jako wej¶cia/wyj¶cia (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+"nie mo¿na otworzyæ dwukierunkowego potoku `%s' jako wej¶cia/wyj¶cia (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "nie mo¿na przekierowaæ z `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "nie mo¿na przekierowaæ do `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"osi±gniêto systemowy limit otwartych plików: rozpoczêcie multipleksowania "
+"deskryptorów plików"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "zamkniêcie `%s' nie powiod³o siê (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "zbyt du¿o otwartych potoków lub plików wej¶ciowych"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: drugim argumentem musi byæ `to' lub `from'"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+"close: `%.*s' nie jest ani otwartym plikiem, ani potokiem, ani procesem"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "zamkniêcie przekierowania, które nigdy nie zosta³o otwarte"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: przekierowanie `%s' nie zosta³o otwarte z `|&', drugi argument "
+"zignorowany"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "status awarii (%d) podczas zamykania potoku `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "status awarii (%d) podczas zamykania pliku `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "brak jawnego zamkniêcia gniazdka `%s'"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "brak jawnego zamkniêcia procesu pomocniczego `%s'"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "brak jawnego zamkniêcia potoku `%s'"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "brak jawnego zamkniêcia pliku `%s'"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "b³±d podczas zapisu na standardowe wyj¶cie (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "b³±d podczas zapisu na standardowe wyj¶cie diagnostyczne (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "opró¿nienie potoku `%s' nie powiod³o siê (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr ""
+"opró¿nienie potoku do `%s' przez proces pomocniczy nie powiod³o siê (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "opró¿nienie pliku `%s' nie powiod³o siê (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "klient /inet/raw nie jest jeszcze gotowy, przykro mi"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "tylko superu¿ytkownik (root) mo¿e u¿yæ `/inet/raw'."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "serwer /inet/raw nie jest jeszcze gotowy, przykro mi"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "nie dostarczono (znanego) protoko³u w specjalnym pliku `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "specjalna nazwa pliku `%s' jest niekompletna"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "nieprawid³owy lokalny port `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "nale¿y dostarczyæ nazwê zdalnego hosta do `/inet'"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "nale¿y dostarczyæ numer zdalnego portu do `/inet'"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "nieprawid³owy zdalny port w `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "Komunikacja TCP/IP nie jest wspierana"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "plik `%s' jest katalogiem"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "u¿yj `PROCINFO[\"%s\"]' zamiast `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "u¿yj `PROCINFO[...]' zamiast `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "nie mo¿na otworzyæ `%s', tryb `%s'"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "zamkniêcie nadrzêdnego pty nie powiod³o siê (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr ""
+"zamkniêcie standardowego wyj¶cia w procesie potomnym nie powiod³o siê (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"przesuniêcie podleg³ego pty na standardowe wyj¶cie w procesie potomnym nie "
+"powiod³o siê (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr ""
+"zamkniêcie standardowego wej¶cia w procesie potomnym nie powiod³o siê (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"przesuniêcie podleg³ego pty na standardowe wej¶cie w procesie potomnym nie "
+"powiod³o siê (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "zamkniêcie podleg³ego pty nie powiod³o siê (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+"przesuniêcie potoku na standardowe wyj¶cie w procesie potomnym nie powiod³o "
+"siê (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+"przesuniêcie potoku na standardowe wej¶cie w procesie potomnym nie powiod³o "
+"siê (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr ""
+"odzyskanie standardowego wyj¶cia w procesie potomnym nie powiod³o siê\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr ""
+"odzyskanie standardowego wej¶cia w procesie potomnym nie powiod³o siê\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "zamkniêcie potoku nie powiod³o siê (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' nie jest wspierany"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "nie mo¿na otworzyæ potoku `%s' (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "nie mo¿na utworzyæ procesu potomnego dla `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "plik danych `%s' jest pusty"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "nie mo¿na zarezerwowaæ wiêcej pamiêci wej¶ciowej"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "b³±d podczas czytania z pliku `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "wieloznakowa warto¶æ `RS' jest rozszerzeniem gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "nieistotna opcja `-m[fr]' w gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "u¿ycie opcji -m: `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: opcja `-W %s' nierozpoznana i zignorowana\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "pusty argument dla opcji `--source' zosta³ zignorowany"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"zmienna ¶rodowiskowa `POSIXLY_CORRECT' ustawiona: `--posix' zosta³ w³±czony"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "opcja `--posix' zostanie u¿yta nad `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--posix'/`--traditional' u¿yte nad opcj± `--non-decimal-data'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr ""
+"uruchamianie %s setuid root mo¿e byæ problemem pod wzglêdem bezpieczeñstwa"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "nie mo¿na ustawiæ trybu binarnego na standardowym wej¶ciu (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "nie mo¿na ustawiæ trybu binarnego na standardowym wyj¶ciu (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "nie mo¿na ustawiæ trybu binarnego na wyj¶ciu diagnostycznym (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "brak tekstu programu!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"U¿ycie: %s [styl opcji POSIX lub GNU] -f plik_z_programem [--] plik ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "U¿ycie: %s [styl opcji POSIX lub GNU] [--] %cprogram%c plik ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Opcje POSIX:\t\tD³ugie opcje GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f program\t\t--file=program\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v zmienna=warto¶æ\t--assign=zmienna=warto¶æ\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] warto¶æ\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=plik]\t--dump-variables[=plik]\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=plik\t\t--exec=plik\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=plik]\t--profile[=plik]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=tekst-programu\t--source=tekst-programu\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Aby zg³osiæ b³±d, prosimy zobaczyæ wêze³ `Bugs' w `gawk.info'\n"
+"lub rozdzia³ p.t. `Reporting Problems and Bugs' w wydrukowanej\n"
+"dokumentacji.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk jest jêzykiem skanowania i przetwarzania wzorców.\n"
+"Program domy¶lnie czyta standardowe wej¶cie i zapisuje standardowe wyj¶cie.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Przyk³ady:\n"
+"\tgawk '{ suma += $1 }; END { print suma }' plik\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Ten program jest wolnym oprogramowaniem; mo¿esz go rozprowadzaæ dalej\n"
+"i/lub modyfikowaæ na warunkach Powszechnej Licencji Publicznej GNU,\n"
+"wydanej przez Fundacjê Wolnego Oprogramowania - wed³ug wersji 2-giej\n"
+"tej Licencji lub której¶ z pó¼niejszych wersji.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Ten program rozpowszechniany jest z nadziej±, i¿ bêdzie on\n"
+"u¿yteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domy¶lnej\n"
+"gwarancji PRZYDATNO¦CI HANDLOWEJ albo PRZYDATNO¦CI DO OKRE¦LONYCH\n"
+"ZASTOSOWAÑ. W celu uzyskania bli¿szych informacji przeczytaj\n"
+"Powszechn± Licencjê Publiczn± GNU.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Z pewno¶ci± wraz z niniejszym programem otrzyma³e¶ te¿ egzemplarz\n"
+"Powszechnej Licencji Publicznej GNU (GNU General Public License);\n"
+"je¶li za¶ nie - napisz do Free Software Foundation, Inc.,\n"
+"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft nie ustawia FS na znak tabulatora w POSIX awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: argument `%s' dla `-v' nie jest zgodny ze sk³adni± `zmienna=warto¶æ'\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' nie jest dozwolon± nazw± zmiennej"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' nie jest nazw± zmiennej, szukanie pliku `%s=%s'"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "wyj±tek zmiennopozycyjny"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "fatalny b³±d: wewnêtrzny b³±d"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "brak ju¿ otwartego fd %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "nie mo¿na otworzyæ zawczasu /dev/null dla fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "nie mo¿na znale¼æ grup: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "linia poleceñ:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "ostrze¿enie: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "b³±d: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatalny b³±d: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "nie mo¿na zamieniæ ³añcucha do liczby zmiennopozycyjnej"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "backslash na koñcu ³añcucha"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX nie zezwala na sekwencjê ucieczki `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "brak liczb szesnastkowych w sekwencji ucieczki `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "sekwencja ucieczki `\\%c' potraktowana jako zwyk³e `%c'"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': nie mo¿na ustawiæ close-on-exec: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "nie mo¿na otworzyæ `%s' do zapisu: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "wewnêtrzny b³±d: %s z zerowym vname"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# potraktowany wewnêtrznie jako `delete'"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# to jest dynamicznie ³adowana funkcja rozszerzenie"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# profil programu gawk, utworzony %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# blok(i) BEGIN\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regu³y\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# blok(i) END\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funkcje, spis alfabetyczny\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "niespodziewany typ %s w prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Sukces"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Brak dopasowania"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Nieprawid³owe wyra¿enie regularne"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Nieprawid³owy znak porównania"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nieprawid³owa nazwa klasy znaku"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Koñcowy znak backslash"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Nieprawid³owe odwo³anie wsteczne"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Niedopasowany znak [ lub [^"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Niedopasowany znak ( lub \\("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Niedopasowany znak \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Nieprawid³owa zawarto¶æ \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Nieprawid³owy koniec zakresu"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Pamiêæ wyczerpana"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Nieprawid³owe poprzedzaj±ce wyra¿enie regularne"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Przedwczesny koniec wyra¿enia regularnego"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Wyra¿enie regularne jest zbyt du¿e"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Niedopasowany znak ) lub \\)"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Brak poprzedniego wyra¿enia regularnego"
+
+#~ msgid "function %s called\n"
+#~ msgstr "wywo³ano funkcjê %s\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "pole nr %d w FIELDWIDTHS musi byæ wiêksze od zera"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: nieprawid³owe u¿ycie zmiennej `%s' jako tablicy"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: pierwszy argument nie jest tablic±"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: drugi argument nie jest tablic±"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Aby zg³osiæ b³êdy, prosimy zobaczyæ wêze³ `Bugs' w `gawk.info', który "
+#~ "jest\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "b³±d sk³adni w nazwie `%s' dla przypisania zmiennej"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "wewnêtrzny b³±d: Node_var_array z zerowym vname"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "lub u¿yty w innym kontek¶cie wyra¿enia"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "`%s' jest funkcj±, zatem przypisanie nie jest dozwolone"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Blok BEGIN musi posiadaæ czê¶æ dotycz±c± akcji"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "`nextfile' u¿yty w akcji BEGIN lub END"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "komenda `getline' bez przekierowania nie jest zdefiniowana wewn±trz akcji "
+#~ "BEGIN lub END"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "brak fptr %x w tokentab\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "trzeci parametr gsub nie jest zmiennym obiektem"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Niedokoñczona sekwencja ucieczki \\"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "niedokoñczona liczba powtórzeñ"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "¼le sformatowana liczba powtórzeñ"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ nie do pary"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( nie do pary"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Nie zosta³y podane bity sk³adni wyra¿enia regularnego"
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") nie do pary"
+
+#~ msgid "out of memory"
+#~ msgstr "brak pamiêci"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "wewnêtrzny b³±d: plik `%s', linia %d\n"
--- /dev/null
+# gawk pt_BR translation.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is distributed under the same license as the PACKAGE package.
+# Juan Carlos Castro y Castro <jcastro@vialink.com.br>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.2g\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2003-06-26 16:18+0300\n"
+"Last-Translator: Juan Carlos Castro y Castro <jcastro@vialink.com.br>\n"
+"Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "tentativa de usar escalar `%s' como vetor"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "tentativa de usar parâmetro escalar `%s' como vetor"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "tentativa de usar escalar `%s' como vetor"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "de %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referência a elemento não inicializado `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "índice do vetor `%s' é uma string nula"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: índice `%s' não está no vetor `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: vazio (nulo)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: vazio (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: é parâmetro\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array_ref para %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "blocos %s devem ter uma parte de ação"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "cada regra deve ter um padrão ou uma parte de ação"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' é uma função intrínseca, não pode ser redefinida"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "constante de expr. reg. `/%s/' parece um comentário C, mas não é"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "constante de expr. reg. `/%s/' parece um comentário C, mas não é"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "declaração pode não ter efeito"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s' usado em ação %s"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' é uma extensão do gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' usado fora do contexto de função"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"`print' sozinho em regra BEGIN ou END provavelmente deveria ser `print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' é uma extensão do gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete(array)' é uma extensão não-portável do tawk"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "valores de case duplicados no corpo do switch: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "Detectado `default' duplicado no corpo do switch"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "pipelines bidirecionais de múltiplos estágios não funcionam"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "expressão regular à direita de atribuição"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "expressão regular à esquerda de operador `~' ou `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "expressão regular à direita de comparação"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "`getline' não-redirecionado não é definido dentro da ação END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "chamada a `length' sem parênteses não é portável"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "chamada a `length' sem parênteses é obsoleta de acordo com POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "uso de não-vetor como vetor"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "expressão de índice inválida"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "fim de linha ou de string inesperado"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "texto de programa vazio na linha de comando"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "impossível abrir arquivo-fonte `%s' para leitura (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "impossível ler arquivo-fonte `%s' (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "arquivo-fonte `%s' está vazio"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "arquivo-fonte não termina em fim-de-linha"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "expressão regular inacabada termina com `\\' ao fim do arquivo"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "expressão regular inacabada"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "expressão regular inacabada no fim do arquivo"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "uso da continuação de linha `\\ #...' não é portável"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "`\\' não é o último caracter da linha"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX não permite o operador `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "o velho awk não suporta o operador `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX não permite o operador `**'"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "o velho awk não suporta o operador `**'"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "o velho awk não suporta o operador `^='"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "o velho awk não suporta o operador `^'"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "string inacabada"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "caracter inválido '%c' em expressão"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' é uma extensão do gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' é uma extensão da Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX não permite `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' não é suportado no velho awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' é considerado danoso!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d é inválido como número de argumentos para %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: terceiro argumento é uma extensão do gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: string literal como último argumento de substituição não tem efeito"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "terceiro parâmetro %s não é um objeto modificável"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: segundo argumento é uma extensão do gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "uso de dcgettext(_\"...\") é incorreto: remova o `_' precedente"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "uso de dcngettext(_\"...\") é incorreto: remova o `_' precedente"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "função `%s': parâmetro #%d, `%s', duplica parâmetro #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "função `%s': parâmetro `%s' encobre variável global"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "impossível abrir `%s' para escrita (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "enviando perfil para saída de erros"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: `close' falhou (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() chamada duas vezes!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "houve variáveis encobertas."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "função `%s': não se pode usar o nome da função como nome de parâmetro"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nome de função `%s' definido anteriormente"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "função `%s' chamada mas nunca definida"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "função `%s' definida mas nunca chamada"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"constante com expr. regular para parâmetro nº %d retorna valor booleano"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"função `%s' chamada com espaço entre o nome e o `(',\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s para \"%s\" falhou (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "saída padrão"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "motivo desconhecido"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: recebeu argumento não-numérico"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argumento %g está fora da faixa"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: erro ao descarregar: pipe `%s' aberto para leitura, não gravação"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: erro ao descarregar: arquivo `%s' aberto para leitura, não gravação"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' não é um arquivo aberto, pipe ou co-processo"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: recebeu primeiro argumento não-string"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: recebeu segundo argumento não-string"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: recebeu argumento não-numérico"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete array' é uma extensão do gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: recebeu argumento não-string"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: recebeu argumento não-numérico"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: recebeu argumento negativo %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "deve usar `count$' em todos os formatos ou nenhum"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' não é permitido em formatos awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "nº de argumentos com `$' deve ser > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "nº de argumentos %ld maior que nº total de argumentos fornecidos"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' não é permitido depois de ponto no formato"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "nenhum `$' fornecido para tamanho ou precisão de campo posicional"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' não faz sentido em formatos awk; ignorado"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`l' não é permitido em formatos POSIX awk"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' não faz sentido em formatos awk; ignorado"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`L' não é permitido em formatos POSIX awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' não faz sentido em formatos awk; ignorado"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`h' não é permitido em formatos POSIX awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: valor %g fora da faixa para formato `%%%c'"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "argumentos insuficientes para a string de formato"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ acabou para este aqui"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: declaração de formato não tem letra de controle"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "excesso de argumentos para a string de formato"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: nenhum argumento"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: recebeu argumento não-numérico"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: chamada com argumento negativo %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: posição inicial %g é inválida, usando 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: posição inicial %g não-inteira será truncada"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: comprimento %g é <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: comprimento %g é <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: comprimento %g não-inteiro será truncado"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "substr: comprimento %g excessivo para indexação, truncando para %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: string origem tem comprimento zero"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: posição inicial %g além do fim da string"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: comprimento %g a partir da posição %g excede tamanho do 1º argumento "
+"(%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: recebeu primeiro argumento não-string"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: recebeu string de formato vazia"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: recebeu segundo argumento não-numérico"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: recebeu argumento não-string"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: recebeu argumento não-string"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referência a campo não inicializado `$%d'"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: recebeu argumento não-string"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: recebeu argumento não-string"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: recebeu segundo argumento não-numérico"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: recebeu argumento não-numérico"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: recebeu argumento não-numérico"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: recebeu argumento não-numérico"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: terceiro argumento não é um vetor"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: 3º argumento 0 tratado como 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime: recebeu segundo argumento não-numérico"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): valores fracionários serão truncados"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): deslocamento excessivo dará resultados estranhos"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime: recebeu segundo argumento não-numérico"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): valores fracionários serão truncados"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): deslocamento excessivo dará resultados estranhos"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: recebeu segundo argumento não-numérico"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): valores fracionários serão truncados"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: recebeu segundo argumento não-numérico"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): valores fracionários serão truncados"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: recebeu segundo argumento não-numérico"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): valores fracionários serão truncados"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: recebeu primeiro argumento não-numérico"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): valores negativos darão resultados estranhos"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): valores fracionários serão truncados"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' não é uma categoria de \"locale\" válida"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "tipo de nodo desconhecido %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "estouro de buffer em genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "tentativa de usar vetor `%s' em um contexto escalar"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"loop for: vetor `%s' mudou de tamanho de %ld para %ld durante a execução"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "`break' fora de um loop não é portável"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "`break' fora de um loop não é permitido"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "`continue' fora de um loop não é portável"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "`continue' fora de um loop não é permitido"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`next' não pode ser chamado de uma regra BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "`next' não pode ser chamado de uma regra END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`nextfile' não pode ser chamado de uma regra BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`nextfile' não pode ser chamado de uma regra END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "declaração não tem efeito"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "não se pode usar o nome de função `%s' como variável ou vetor"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referência a argumento não inicializado `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referência a variável não inicializada `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenação: efeitos colaterais em um contexto mudaram o comprimento de "
+"outro!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "atribuição usada em contexto condicional"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "tentativa de divisão por zero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "tentativa de divisão por zero em `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tipo ilegal (%s) em tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "tentativa de divisão por zero em `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "tentativa de divisão por zero em `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "função `%s' chamada com mais argumentos que os declarados"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "função `%s' não definida"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Pilha de Chamadas de Função:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "tentativa de referência a campo a partir de valor não-numérico"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "tentativa de referência a partir de string nula"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "tentativa de acessar campo %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "atribuição não pode resultar de funções intrínsecas"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' é uma extensão do gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' é uma extensão do gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "especificação `%sFMT' inválida `%s'"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "desativando `--lint' devido a atribuição a `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' é uma extensão do gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: impossível abrir `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: biblioteca `%s': impossível chamar função `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: biblioteca `%s': impossível chamar função `%s' (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: impossível abrir `%s' (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "função `%s' não definida"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "nome de função `%s' definido anteriormente"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "função `%s' definida mas nunca chamada"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "função `%s' não definida"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "tentativa de usar escalar `%s' como vetor"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operação Não Suportada"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "valor negativo atribuído a NF"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: segundo argumento não é um vetor"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: string nula para segundo argumento é uma extensão do gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' é uma extensão do gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "string nula para `FS' é uma extensão do gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: opção `%s' é ambígua\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: opção `--%s' não aceita argumento\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: opção `%c%s' não aceita argumento\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: opção `%s' requer argumento\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: opção não reconhecida `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: opção não reconhecida `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: opção ilegal -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: opção inválida -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: opção requer argumento -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: opção `-W %s' é ambígua\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: opção `-W %s' não aceita argumento\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "impossível abrir arquivo `%s' para leitura (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "fechamento do descritor %d (`%s') falhou (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "tipo de árvore %s inválido em redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "expressão no redirecionamento `%s' só tem valor numérico"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "expressão para o redirecionamento `%s' tem valor string nulo"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"nome de arquivo `%s' para redirecionamento `%s' pode ser resultado de "
+"expressão lógica"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "mistura desnecessária de `>' e `>>' para arquivo `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "impossível abrir pipe `%s' para saída (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "impossível abrir pipe `%s' para entrada (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "impossível abrir socket bidirecional `%s' para entrada/saída (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "impossível abrir pipe bidirecional `%s' para entrada/saída (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "impossível redirecionar de `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "impossível redirecionar para `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"alcançado limite do sistema para arquivos abertos; começando a multiplexar "
+"descritores de arquivos"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "fechamento de `%s' falhou (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "excesso de pipes ou arquivos de entrada abertos"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: segundo argumento deve ser `to' ou `from'"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: `%.*s' não é um arquivo aberto, pipe ou co-processo"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "fechamento de redirecionamento que nunca foi aberto"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: redirecionamento `%s' não foi aberto com `|&', segundo argumento "
+"ignorado"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "status de falha (%d) ao fechar pipe de `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "status de falha (%d) ao fechar arquivo de `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "fechamento explícito do socket `%s' não fornecido"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "fechamento explícito do co-processo `%s' não fornecido"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "fechamento explícito do pipe `%s' não fornecido"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "fechamento explícito do arquivo `%s' não fornecido"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "erro ao escrever na saída padrão (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "erro ao escrever na saída padrão de erros (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "descarga de pipe de `%s' falhou (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "descarga de co-processo de pipe para `%s' falhou (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "descarga de arquivo de `%s' falhou (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "infelizmente, o cliente de /inet/raw não está concluído"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "apenas root pode usar `/inet/raw'."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "infelizmente, o servidor de /inet/raw não está concluído"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+"nenhum protocolo (conhecido) fornecido em nome de arquivo especial `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "nome de arquivo especial `%s' está incompleto"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "porta local inválida em `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "deve ser fornecido um nome de host remoto para `/inet'"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "deve ser fornecida uma porta remota para `/inet'"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "porta remota inválida em `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "comunicação TCP/IP não é suportada"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "arquivo `%s' é um diretório"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "use `PROCINFO[\"%s\"]' em vez de `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "use `PROCINFO[...]' em vez de `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "impossível abrir `%s', modo `%s'"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "falha ao fechar pty mestre (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "falha ao fechar stdout em filho (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "falha ao mover pty escrava para stdout em filho (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "falha ao fechar stdin em filho (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "falha ao mover pty escrava para stdin em filho (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "falha ao fechar pty escrava (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "falha ao mover pipe para stdout em processo pai (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "falha ao mover pipe para stdin em processo pai (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "falha ao restaurar stdout em processo pai\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "falha ao restaurar stdin em processo pai\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "falha ao fechar pipe (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' não suportado"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "impossível abrir pipe `%s' (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "impossível criar processo filho para `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "arquivo de dados `%s' vazio"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "impossível alocar mais memória de entrada"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "erro ao ler arquivo de entrada `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "valor de múltiplos caracteres para `RS' é uma extensão do gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "opção `-m[fr] é irrelevante no gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "uso da opção -m: `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: opção `-W %s' não reconhecida, ignorada\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "argumento vazio para --source ignorado"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "variável de ambiente `POSIXLY_CORRECT' ativada: ligando `--posix'"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--posix' sobrepõe `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--posix'/`--traditional' sobrepõe `--non-decimal-data'"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "rodar %s com setuid root pode ser um problema de segurança"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "impossível ativar modo binário em stdin (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "impossível ativar modo binário em stdout (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "impossível ativar modo binário em stderr (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "nenhum texto de programa"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Uso: %s [opções estilo POSIX ou GNU] -f arqprog [--] arquivo ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Uso: %s [opções estilo POSIX ou GNU] [--] %cprograma%c arquivo ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Opções POSIX: \t\tOpções longas GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f arqprog \t\t--file=arqprog\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=val\t\t--assign=var=val\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] val\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=arq] \t--dump-variables[=arq]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=arq] \t--profile[=arq]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=arq] \t--profile[=arq]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=program-text\t--source=program-text\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Em caso de defeito, veja o nodo `Bugs' em `gawk.info', que é a\n"
+"seção `Reportando Problemas e Bugs' na versão impressa.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk é uma linguagem de processamento e busca de padrões.\n"
+"Por padrão, o gawk lê a entrada padrão e escreve na saída padrão.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Exemplos:\n"
+"\tgawk '{ soma += $1 }; END { print soma }' arquivo\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Este programa é Software Livre; você pode redistribuí-lo e/ou modificá-lo\n"
+"de acordo com os termos da Licença Pública Geral GNU (GNU GPL) na "
+"formapublicada pela Free Software Foundation; ou a versão 2 da licença ou "
+"(aoseu critério) qualquer versão posterior.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Este programa é distribuído na esperança de ser útil, mas SEM\n"
+"QUALQUER GARANTIA. Veja a Licença Pública Geral GNU (GNU GPL)\n"
+"para mais detalhes.\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Você deve ter recebido uma cópia da Licença Pública Geral GNU (GNU GPL)\n"
+"junto com este programa; caso contrário, escreva à Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft não faz FS ser tab no awk POSIX"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: argumento `%s' para `-v' não está na forma `var=valor'\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' não é um nome legal de variável"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' não é um nome de variável, procurando arquivo `%s=%s'"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "exceção de ponto flutuante"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "erro fatal: erro interno"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "nenhum descritor pré-aberto %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "impossível pré-abrir /dev/null para descritor %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "impossível achar grupos: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "lin. de com.:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "aviso: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "erro: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "impossível converter string para float"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "barra invertida (\\) no fim da string"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX não permite escapes do tipo `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "nenhum dígito hexa em seqüência de escape `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "seqüência de escape `\\%c' tratada como `%c' normal"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': impossível ativar fechar-ao-executar: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "impossível abrir `%s' para escrita: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "erro interno: %s com vname nulo"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# tratado internamente como `delete'"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# perfil gawk, criado %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# bloco(s) BEGIN\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regra(s)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# bloco(s) END\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funções, listadas alfabeticamente\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "tipo inesperado %s em prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Sucesso"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Sem combinação"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Expressão regular inválida"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Caracter de combinação inválido"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Nome de classe de caracter inválido"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "contra-barra (\\) finalizando"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Referência anterior inválida"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ ou [^ não emparelhado"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( ou \\( não emparelhado"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ não emparelhado"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Conteúdo inválido de \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Fim de faixa inválido"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Memória esgotada"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Expressão regular anterior inválida"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Fim prematuro da expressão regular"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Expressão regular grande demais"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") ou \\) desemparelhado"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Nenhuma expressão regular anterior"
+
+#~ msgid "function %s called\n"
+#~ msgstr "função %s chamada\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "campo %d em FIELDWIDTHS deve ser > 0"
+
+#~ msgid "or used as a variable or an array"
+#~ msgstr "ou usado como uma variável ou vetor"
+
+#~ msgid "regex match failed, not enough memory to match string \"%.*s%s\""
+#~ msgstr ""
+#~ "busca por exp. reg. falhou, memória insuficiente para testar string \"%.*s"
+#~ "%s\""
+
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: comprimento %g é < 0"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: uso ilegal da variável `%s' como vetor"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: primeiro argumento não é um vetor"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: segundo argumento não é um vetor"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "erro interno: Node_var_array com vname nulo"
--- /dev/null
+s/"\([^"]*\)"/“\1”/g
+s/`\([^`']*\)'/‘\1’/g
+s/ '\([^`']*\)' / ‘\1’ /g
+s/ '\([^`']*\)'$/ ‘\1’/g
+s/^'\([^`']*\)' /‘\1’ /g
+s/“”/""/g
--- /dev/null
+# Sed script that remove the POT-Creation-Date line in the header entry
+# from a POT file.
+#
+# The distinction between the first and the following occurrences of the
+# pattern is achieved by looking at the hold space.
+/^"POT-Creation-Date: .*"$/{
+x
+# Test if the hold space is empty.
+s/P/P/
+ta
+# Yes it was empty. First occurrence. Remove the line.
+g
+d
+bb
+:a
+# The hold space was nonempty. Following occurrences. Do nothing.
+x
+:b
+}
--- /dev/null
+# Mesajele în limba românã pentru pachetul gawk
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Eugen Hoanca <eugenh@urban-grafx.ro>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.31\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2003-09-15 17:48+0300\n"
+"Last-Translator: Eugen Hoanca <eugenh@urban-grafx.ro>\n"
+"Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "încercare de folosire a funcþiei `%s' ca array"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "încercare de utilizare a parametrului scalar `%s' drept array"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "încercare de a utiliza scalarul `%s' ca array"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (din %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referinþã la elementul neiniþializat `%s[\"%s\"]'"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "înscrierea array-ului `%s' este ºir null"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: indexul `%s' nu este în array-ul `%s'"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: vid (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: vid (zero)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: table_size = %d, array_size = %d\n"
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: este parametru!\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: array_ref cãtre %s\n"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "Blocurile de END trebuie sã aibã un fragment de acþiune"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "Blocurile de END trebuie sã aibã un fragment de acþiune"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' este funcþie internã, nu poate fi redefinitã"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "constanta regexp `/%s/' aratã ca un comentariu C, dar nu este"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "constanta regexp `/%s/' aratã ca un comentariu C, dar nu este"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "declaraþia poate sã nu aibã nici un efect"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "`next' folosit în acþiune BEGIN sau END"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' este extensie gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' folosit în afara contextului funcþiei"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"`print' simplu din regulile BEGIN sau END ar trebui sã fie probabil `print "
+"\"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' este extensie gawk"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete array' este extensie gawk"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "legãturile(pipelines) bidirecþionale multistage nu vor funcþiona"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "expresie regularã în dreapta atribuirii"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "expresie regularã în stânga operatorului `~' sau `!~'"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "expresie regularã în dreapta comparaþiei"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "`getline' nedefinitã ºi neredirectatã înãuntrul unei acþiuni END"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "apelarea lui `legth' fãrã paranteze nu este portabilã"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "apelarea lui `length' fãrã paranteze nu mai este folositã în POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "expresie subscript invalidã"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "linie nouã neaºteptatã"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "text program vid în linia de comandã"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "nu se poate deschide fiºierul sursã `%s' pentru citire (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "nu se poate citi fiºierul sursã `%s' (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "fiºierul sursã `%s' este vid"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "fiºierul sursã nu se terminã în linie nouã"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "regexp-ul neterminat se terminã cu `\\'` la sfârºitul fiºierului"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "regexp neterminat"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "regexp neterminat la sfârºitul fiºierului"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "folosirea continuãrii liniei `\\ #...' nu este portabilã"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "backslash nu este ultimul caracter din linie"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX nu permite operatorul `**='"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "vechiul awk nu suportã operatorul `**='"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX nu permite operatorul `**'"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "vechiul awk nu supoortã operatorul `**'"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "operatorul `^=' nu este suportat în vechiul awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "operator `^' nu este suportat în vechiul awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "ºir de caractere neterminat"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "caracter invalid `%c' în expresie"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' este extensie gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' este extensie Bell Labs"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX nu permite `%s'"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' nu este suportat în vechiul awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' este considerat periculos!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d este invalid ca numãr de argumente pentru %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: al treilea argument este extensie gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: ºirul de caractere literal ca ultim argument al înlocuitorului nu are "
+"nici un efect"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "al treilea parametru al sub nu este un obiect modificabil"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: al doilea argument este extensie gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"folosirea lui dcgettext(_\"...\") este incorectã: eliminaþi liniuþa_jos de "
+"la început"
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"folosirea lui dcgettext(_\"...\") este incorectã: eliminaþi liniuþa_jos de "
+"la început"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funcþia `%s': parametrul #%d, `%s', parametrul duplicat #%d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr ""
+"funcþia `%s': parametrul `%s' nu mai þine cont de(shadows) variabila globalã"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "nu s-a putut deschide `%s' pentru scriere (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "se trimite profilul la dipsozitivul de eroare standard"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: închidere eºuatã (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() apelatã de douã ori!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funcþia `%s': nu se poate folosi numele funcþiei ca nume de parametru"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "numele funcþiei `%s' a mai fost definit înainte"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "funcþia `%s' este apelatã dar niciodatã definitã"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "funcþia `%s' este definitã dar niciodatã apelatã"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+"regexp constant pentru parametrul #%d solicitã(yields) valoare booleanã"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"funcþia `%s' apelatã cu un spaþiu între nume ºi `(',\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s cãtre \"%s\" eºuatã (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "ieºire(output) standard"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "motiv necunoscut"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: s-a primit argument nenumeric"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argumentul %g este în afara domeniului"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: nu s-a putut face flush: legãtura(pipe) `%s' a fost deschisã pentru "
+"citire, nu scriere"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: nu s-a putut face flush: fiºierul `%s' a fost deschis pentru citire, "
+"nu scriere"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' nu este fiºier deschis, legãturã(pipe) sau co-proces"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: s-a primit un prim argument non-ºir de caractere"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: s-a primit un al doilea argument non-ºir de caractere"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: s-a primit argument nenumeric"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete array' este extensie gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "legth: s-a primit argument non-string"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: s-a primit argument nenumeric"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: s-a primit argument %g negativ"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' nu este permis în formatele awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "numãrul de arg cu `%' trebuie sã fie > 0"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"numãrul de arg %d este mai mare decât numãrul total de argumente furnizate"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' nu este permis în format dupã punct"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr ""
+"nu s-a furnizat nici un `$' pentru câmpul poziþional lungime sau precisie"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' nu are sens în formatele awk; ignorat"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`l' nu este permis în formatele awk POSIX"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' nu are sens în formatele awk; ignorat"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`L' nu este permis în formatele POSIX awk"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' nu are sens în formatele awl; ignorat"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`h' nu este permis în formatele POSIX awk"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr ""
+"nu existã destule argumente pentru satisfacerea formatului ºirului de "
+"caractere"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ insuficient pentru aceasta"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: specificatorul de format nu are literã de control"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "prea multe argumente furnizate pentru formatul ºirului de caractere"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: nici un argument"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: s-a primit argument nenumeric"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: apelat cu argumentul negativ %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: indexul de start %g este invalid, se foloseºte -1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: indexul de start ne-întreg(integer) %g va fi trunchiat"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: lungimea %g este <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: lungimea %g este <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr lungimea ne-întregului(integer) %g va fi trunchiatã"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: ºirul de caractere sursã are lungime zero"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: indexul de start %d este fostul sfârºit de ºir de caractere"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: lungimea %d la indexul de start %d depãºeºte lungimea primului "
+"argument (%d)"
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "strftime: s-a primit primul argument non ºir de caractere"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: s-a primit ºir de caractere în format vid"
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: s-a primit argument non ºir de caractere"
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "system: s-a primit argument non ºir de caractere"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referinþã la variabila neiniþializatã `%s'"
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "tolower: s-a primit argument non-ºir de caractere"
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "toupper: s-a primit argument non-ºir de caractere"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: s-a primit un prim argument nenumeric"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: s-a primit un argument nenumeric"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: s-a primit un argument nenumeric"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: s-a primit un argument nenumeric"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: al treilea argument nu este un array"
+
+#: builtin.c:2555
+#, fuzzy
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: al 3-lea argument care este 0 va fi considerat 1"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: s-a primit un prim argument nenumeric"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): valorile negative vor furniza rezultate ciudate"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"lshift(%lf, %lf): valorile schimbate prea mult vor da rezultate ciudate"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: s-a primit un prim argument nenumeric"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): valorile negative vor da rezultate ciudate"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): valorile schimbate prea mult vor da rezultate ciudate"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: s-a primit un prim argument nenumeric"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): valorile negative vor da rezultate ciudate"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: s-a primit un prim argument nenumeric"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): valorile negative for da rezultate ciudate"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: s-a primit un prim argument nenumeric"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: s-a primit un al doilea argument nenumeric"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): valorile negative vor da rezultate ciudate"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: s-a primit argument nenumeric"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): valorile negative vor da rezultate ciudate"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): valorile fracþionale vor fi trunchiate"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' nu este o categorie localã validã"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "tip nod %d necunoscut"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "depãºire(overflow) de buffer în genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "încercare de a utiliza array-ul `%s' într-un context scalar"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for loop: array-ul `%s' ºi-a schimbat mãrimea din %d în %d în timpul "
+"execuþiei buclei"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "`break' în afara buclei nu este portabil"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "`break' în afara buclei nu este permis"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "`continue' în afara buclei nu este portabil"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "`continue' în afara buclei nu este permis"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`next' nu poate fi apelat dintr-o regulã BEGIN"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "`next' nu poate fi apelat dintr-o regulã END"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`nextfile' nu poate fi apelat dintr-o regulã BEGIN"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`nextfile' nu poate fi apelat dintr-o regulã END"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "declaraþia nu are nici un efect"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "nu se poate folosi numele funcþiei `%s' ca variabilã sau array"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referinþã la argumentul neiniþializat `%s'"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referinþã la variabila neiniþializatã `%s'"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation: efectele secundare dintr-o expresie au schimbat lungimea "
+"alteia!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "atribuire folositã în context condiþional"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "s-a încercat împãrþire la zero"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "s-a încercat împãrþire la zero în `%%'"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tip ilegal (%s) în tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "s-a încercat împãrþire la zero în `/='"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "s-a încercat împãrþire la zero în `%%='"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr ""
+"funcþia `%s' a fost apelatã cu mai multe argumente decât cele declarate"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "funcþia `%s' nu este definitã"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Stiva de Apelare a Funcþiei:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- principal(main) --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "încercare de referinþã la câmp din valoare nenumericã"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "încercare de referinþã din ºir de caractere vid(null)"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "încercare de accesare a câmpului %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "atribuirea nu este permisã rezultatului funcþiei interne"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' este extensie gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' este extensie gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "`%sFMT' specificaþie `%s' invalidã"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "se dezactiveazã `--lint' din cauza atribuirii lui `LINT'"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' este o extensie gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: nu s-a putut deschide `%s' (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: biblioteca `%s': nu pot apela funcþia `%s' (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: biblioteca `%s': nu pot apela funcþia `%s' (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: nu s-a putut deschide `%s' (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "funcþia `%s' nu este definitã"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "numele funcþiei `%s' a mai fost definit înainte"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "funcþia `%s' este definitã dar niciodatã apelatã"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "funcþia `%s' nu este definitã"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "încercare de a utiliza scalarul `%s' ca array"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operaþie NeSuportatã"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF setat la valoare negativã"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: al doilea argument nu este un array"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: ºirul nul pentru al treilea arg este o extensie gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' este extensie gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "ºirul de caractere null pentru `FS' este extensie gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: opþiunea `%s' este ambiguã\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: opþiunea `--%s' nu permite parametri\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: opþiunea `%c%s' nu permite parametri\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: opþiunea `%s' necesitã un parametru\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: opþiune necunoscutã `--%s'\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: opþiune necunoscutã `%c%s'\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: opþiune ilegalã -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: opþiune invalidã -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: opþiunea necesitã un parametru -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: opþiunea `-W %s' este ambiguã\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: opþiunea `-W %s' nu permite parametri\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "nu s-a putu deschide `%s' pentru citire (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "închiderea lui fd %d (`%s') eºuatã (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "tip arbore(tree) invalid %s în redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "expresia din redirectarea `%s' are doar valoare numericã"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "expresia din redirectarea `%s' are valoar de ºir null"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"numele de fiºier `%s' pentru redirectarea `%s' poate fi rezultatul unei "
+"expresii logice"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "amestecare nenecesarã a `>' ºi `>>' pentru fiºierul `%.*s'"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "nu se poate deschide legãtura(pipe) `%s' pentru output (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "nu se poate deschide legãtura(pipe) `%s' pentru input (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr ""
+"nu se poate deschide socketul bidirecþional `%s' pentru input/output (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+"nu se poate deschide legãtura(pipe) bidirecþionalã `%s' pentru input/output "
+"(%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "nu se poate redirecta din `%s' (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "nu se poate redirecta cãtre `%s' (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"s-a atins limita sistemului pentru fiºiere deschise: se începe muliplexarea "
+"desciptorilor de fiºier"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "închiderea `%s' eºuatã (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "prea multe legãturi(pipe) sau fiºiere de intrare(input) deschise"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: al doilea argument trebuie sã fie `to' sau `from'"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+"close: `%.*s' nu este un fiºier deschis, o legãturã(pipe) sau un coproces"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "închiderea unei redirectãri care n-a fost deschisã niciodatã"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: redirectarea `%s' nu a fost deschisã cu `|&', al doilea argument "
+"ignorat"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "stare de avarie (%d) în legãtura(pipe) închisã în `%s' (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "stare de avarie (%d) în fiºierul închis în `%s' (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "nu s-a furnizat închiderea explicitã a socketului `%s'"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "nu s-a furnizat închiderea explicitã a coprocesului `%s' "
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "nu s-a furnizat închiderea explicitã a legãturii(pipe) `%s'"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "nu s-a furnizat închiderea explicitã a fiºierului `%s'"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "eroare în scrierea la ieºirea(output) standard (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "eroare în scrierea la dispozitivul standard de eroare (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "flush-ul legãturii(pipe) `%s' eºuat (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "flush-ul legãturii(pipe) coprocesului la `%s' eºuat (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "flush-ul de fiºier al `%s' eºuat (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "clientul /inet/raw nu este pregãtit încã, scuze"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "doar root-ul poate folosi `/inet/raw'."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "serverul /inet/raw nu este pregãtit încã, scuze"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "nici un protocol (cunoscut) furnizat în numele de fiºier special `%s'"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "numele special de fiºier `%s' nu este complet"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "port local invalid în `%s'"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "trebuie furnizat un nume de host remote pentru `/inet'"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "trebuie furnizat un port remote pentru `/inet'"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "port remote invalid în `%s'"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "Comunicaþiile TCP/IP nu sunt suportate"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "fiºierul `%s' este director"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "folosiþi `PROCINFO[\"%s\"]' în loc de `%s'"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "folosiþi `PROCINFO[...]' în loc de `/dev/user'"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "nu s-a putut deschide `%s', modul `%s'"
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "închiderea legãturii(pipe) a eºuat (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "închiderea stdout în copil(child) a eºuat (%s)"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "mutarea legãturii(pipe) la stdout în copil(child) a eºuat (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "închiderea stdin în copil(child) a eºuat (%s)"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "mutarea legãturii(pipe) la stdin în copil(child) a eºuat (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "închiderea legãturii(pipe) a eºuat (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "mutarea legãturii(pipe) la stdout în copil(child) a eºuat (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "mutarea legãturii(pipe) la stdin în copil(child) a eºuat (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "refacerea stdout în procesul pãrinte a eºuat\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "refacerea stdin în procesul pãrinte a eºuat\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "închiderea legãturii(pipe) a eºuat (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' nesuportat"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "nu s-a putut deschide legãtura(pipe) `%s' (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "nu s-a putu crea proces copil(child) pentru `%s' (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "fiºierul de date `%s' este vid"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "eroare în citirea fiºierului de intrare(input) `%s': %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "valoarea multicaracter a `RS' este extensie gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "`-m[fr]' opþiune irelevantã în gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "folosirea opþiunii -m : `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: opþiunea `-W %s' nu e recunoscutã, ignoratã\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "argument vid pentru `--source' ignorat"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"este setatã variabila de mediu `POSIXLY_CORRECT': se activeazã `--posix'"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--posix' suprascrie `--traditional'"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--posix'/`--traditional' suprascrie `--non-decimal-data'"
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "dacã se ruleazã %s setuid root poate apãrea o problemã de securitate"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "nu se poate seta modul pe stdin (%s)"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "nu se poate seta modul pe stdout (%s)"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "nu se poate seta modul pe stderr (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "nu existã nici un text de program!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Folosire: %s [opþiuni stil POSIX sau GNU] -f fiºierprogram [--] fiºier ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Folosire: %s [opþiuni stil POSIX sau GNU] [--] %cprogram%c fiºier ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "opþiuni POSIX:\t\topþiuni lungi GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f fiºierprogram\t\t--file=fiºierprogram\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=val\t\t--assign=var=val\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] val\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fiºier]\t--dump-variables[=fiºier]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=fiºier]\t--profile[=fiºier]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fiºier]\t--profile[=fiºier]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=program-text\t--source=program-text\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr "secþiunea `Reporting Problems and Bugs' în versiunea tipãritã.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Acest program este software liber; poate fi redistribuit ºi/sau modificat\n"
+"sub termenii Licenþei Publice Generale GNU publicatã de \n"
+"Free Software Foundation; fie versiunea 2 a Licenþei, fie\n"
+"(la latitudinea dumneavoastrã) orice versiune ulterioarã.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Acest program este distribuit în speranþa cã va fi folositor,\n"
+"dar FÃRÃ NICI O GARANÞIE; chiar fãrã presupusa garanþie a\n"
+"VANDABILITÃÞII sau MODIFICÃRII ÎNTR-UN SCOP PRIVAT. Cititi\n"
+"Licenþa Publicã Generalã GNU pentru mai multe detalii.\n"
+"\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Ar fi trebuit sã primiþi o copie a Licenþei Publice Generale GNU\n"
+"împreunã cu acest program; dacã nu, scrieþi la Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft nu seteazã FS în tab în POSIX awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "excepþie virgulã mobilã"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "eroare fatalã: eroare internã"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "nici un fd predeschis %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "nu s-a putut predeschide /dev/null pentru fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "nu am putut gãsi grupurile: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "linie cmd:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "avertisment: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "eroare: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "fatal: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "nu se poate converti ºir de caractere în float"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "backslash la sfârºitul ºirului de caractere"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX nu permite escape-uri `\\x'"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "nu existã digiþi hexa în secvenþa de escape `\\x'"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "secvenþa de escape `\\%c' tratatã ca `%c' simplu"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': nu s-a putut seta close-on-exec: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "nu am putut deschide `%s' pentru scriere: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "eroare internã: Node_var cu vname null"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr ""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# profil gawk, creat %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# bloc(uri) BEGIN\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regulã(i)\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# bloc(uri) END\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funcþii, listate alfabetic\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "tip %s neaºteptat în prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Succes"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Nici o potrivire"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Expresie regularã invalidã"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Caracter de comparare invalid"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "nume clasã caracter invalid"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Backslash final"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "referinþã anterioarã(back) invalidã"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ sau [^ fãrã reciprocã"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( sau \\( fãrã reciprocã"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "{ fãrã reciprocã"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Conþinut invalid al \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Sfârºit de domeniu invalid"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Memorie plinã"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Expresie regularã anterioarã invalidã"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Sfârºit prematur de expresie regularã"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Expresie regularã prea mare"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") or \\) fãrã reciprocã"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Nu existã expresii regulare anterioare"
+
+#~ msgid "function %s called\n"
+#~ msgstr "funcþia %s a fost apelatã\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "câmpul %d din FIELDWIDTHS trebuie sã fie > 0"
+
+#, fuzzy
+#~ msgid "or used as a variable or an array"
+#~ msgstr "nu se poate folosi numele funcþiei `%s' ca variabilã sau array"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: folosire ilegalã a variabilei `%s' ca array"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: primul argument nu este un array"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: al doilea argument nu este un array"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Pentru a raporta bug-urile, citiþi nodul `Bugs' în `gawk.info', "
+#~ "reprezentând\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "sintaxã invalidã în numele `%s' pentru atribuire de variabilã"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "eroare internã: Node_var_array cu vname null"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "sau folositã în alt context al expresiei"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "`%s' este o funcþie, atribuirea nu este permisã"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Blocurile de BEGIN trebuie sa aibã un fragment de acþiune"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "`nextfile' folosit în acþiune BEGIN sau END"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "`getline' nedefinit ºi neredirectat înãuntrul unei acþiuni BEGIN sau END"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x nu este în tokentab\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "al treilea parametru al gsub nu este obiect modificabil"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "\\ escape neterminat"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "numãrãtoare repetatã neterminatã"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "numãrãtoare repetatã malformatã"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "[ fãrã reciproc"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "( fãrã reciproc"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Nu s-au specificat biþi pentru sintaxa regexp"
+
+#~ msgid "Unbalanced )"
+#~ msgstr ") fãrã reciproc"
+
+#~ msgid "out of memory"
+#~ msgstr "memorie plinã"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "eroare internã: fiºierul `%s', linia %d\n"
--- /dev/null
+# Kinyarwanda translations for gawk package.
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gawk package.
+# Steve Murphy <murf@e-tools.com>, 2005.
+# Steve performed initial rough translation from compendium built from translations provided by the following translators:
+# Philibert Ndandali <ndandali@yahoo.fr>, 2005.
+# Viateur MUGENZI <muvia1@yahoo.fr>, 2005.
+# Noëlla Mupole <s24211045@tuks.co.za>, 2005.
+# Carole Karema <karemacarole@hotmail.com>, 2005.
+# JEAN BAPTISTE NGENDAHAYO <ngenda_denis@yahoo.co.uk>, 2005.
+# Augustin KIBERWA <akiberwa@yahoo.co.uk>, 2005.
+# Donatien NSENGIYUMVA <ndonatienuk@yahoo.co.uk>, 2005.
+# Antoine Bigirimana <antoine@e-tools.com>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-04-04 10:55-0700\n"
+"Last-Translator: Steven Michael Murphy <murf@e-tools.com>\n"
+"Language-Team: Kinyarwanda <translation-team-rw@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "Kuri Gukoresha Umumaro Nka Imbonerahamwe"
+
+#: array.c:115
+#, fuzzy, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "Kuri Gukoresha Nka Imbonerahamwe"
+
+#: array.c:118
+#, fuzzy, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "Kuri Gukoresha Nka Imbonerahamwe"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "Kuva:"
+
+#: array.c:511
+#, fuzzy, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "Indango Kuri Itatangijwe Ikigize:"
+
+#: array.c:517
+#, fuzzy, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "Inyandiko nyesi Bya Imbonerahamwe ni NTAGIHARI Ikurikiranyanyuguti"
+
+#: array.c:621
+#, fuzzy, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "Gusiba Umubarendanga OYA in Imbonerahamwe"
+
+#: array.c:791
+#, fuzzy, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s:ubusa NTAGIHARI"
+
+#: array.c:796
+#, fuzzy, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s:ubusa Zeru"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr ""
+
+#: array.c:829
+#, fuzzy, c-format
+msgid "%s: is parameter\n"
+msgstr "%s:ni"
+
+#: array.c:834
+#, fuzzy, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s:Kuri"
+
+#: awkgram.y:208
+#, fuzzy, c-format
+msgid "%s blocks must have an action part"
+msgstr "%sIgikorwa"
+
+#: awkgram.y:211
+#, fuzzy
+msgid "each rule must have a pattern or an action part"
+msgstr "a Ishusho Cyangwa Igikorwa"
+
+#: awkgram.y:267
+#, fuzzy, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s'ni a in Umumaro"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "nka a C Icyo wongeraho ni OYA"
+
+#: awkgram.y:316
+#, fuzzy, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "nka a C Icyo wongeraho ni OYA"
+
+#: awkgram.y:343 awkgram.y:623
+#, fuzzy
+msgid "statement may have no effect"
+msgstr "Inyandiko Gicurasi Oya INGARUKA"
+
+#: awkgram.y:440 awkgram.y:460
+#, fuzzy, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s'in Igikorwa"
+
+#: awkgram.y:453 awkgram.y:456
+#, fuzzy
+msgid "`nextfile' is a gawk extension"
+msgstr "`ni a Umugereka"
+
+#: awkgram.y:470
+#, fuzzy
+msgid "`return' used outside function context"
+msgstr "`Hanze Umumaro Imvugiro"
+
+#: awkgram.y:512
+#, fuzzy
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr "Byuzuye in Cyangwa Gucapa"
+
+#: awkgram.y:525 awkgram.y:532
+#, fuzzy
+msgid "`delete array' is a gawk extension"
+msgstr "`Gusiba ni a Umugereka"
+
+#: awkgram.y:540 awkgram.y:547
+#, fuzzy
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`Gusiba Imbonerahamwe ni a Umugereka"
+
+#: awkgram.y:591
+#, fuzzy, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "Gusubiramo Uduciro in Hindura Umubiri"
+
+#: awkgram.y:601
+#, fuzzy
+msgid "Duplicate `default' detected in switch body"
+msgstr "in Hindura Umubiri"
+
+#: awkgram.y:690
+#, fuzzy
+msgid "multistage two-way pipelines don't work"
+msgstr "Akazi"
+
+#: awkgram.y:781
+#, fuzzy
+msgid "regular expression on right of assignment"
+msgstr "Ibisanzwe imvugo ku Iburyo: Bya Igenera"
+
+#: awkgram.y:804
+#, fuzzy
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "Ibisanzwe imvugo ku Ibumoso: Bya Cyangwa Mukoresha"
+
+#: awkgram.y:812
+#, fuzzy
+msgid "regular expression on right of comparison"
+msgstr "Ibisanzwe imvugo ku Iburyo: Bya"
+
+#: awkgram.y:879
+#, fuzzy
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "kidasobanuye Mo Imbere Igikorwa"
+
+#: awkgram.y:906
+#, fuzzy
+msgid "call of `length' without parentheses is not portable"
+msgstr "Bya ni OYA"
+
+#: awkgram.y:909
+#, fuzzy
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "Bya ni Bitemewe. ku"
+
+#: awkgram.y:962
+#, fuzzy
+msgid "use of non-array as array"
+msgstr "Gukoresha Bya Imbonerahamwe Nka Imbonerahamwe"
+
+#: awkgram.y:964
+#, fuzzy
+msgid "invalid subscript expression"
+msgstr "Sibyo Inyandiko nyesi imvugo"
+
+#: awkgram.y:1171
+#, fuzzy
+msgid "unexpected newline or end of string"
+msgstr "Cyangwa Impera Bya Ikurikiranyanyuguti"
+
+#: awkgram.y:1267
+#, fuzzy
+msgid "empty program text on command line"
+msgstr "ubusa Porogaramu Umwandiko ku Komandi: Umurongo"
+
+#: awkgram.y:1320
+#, fuzzy, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "Gufungura Inkomoko IDOSIYE kugirango"
+
+#: awkgram.y:1397
+#, fuzzy, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "Gusoma"
+
+#: awkgram.y:1405
+#, fuzzy, c-format
+msgid "source file `%s' is empty"
+msgstr "Inkomoko IDOSIYE ni ubusa"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+#, fuzzy
+msgid "source file does not end in newline"
+msgstr "Inkomoko IDOSIYE OYA Impera in"
+
+#: awkgram.y:1658
+#, fuzzy
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "Na: ku Impera Bya IDOSIYE"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr ""
+
+#: awkgram.y:1696
+#, fuzzy
+msgid "unterminated regexp at end of file"
+msgstr "ku Impera Bya IDOSIYE"
+
+#: awkgram.y:1762
+#, fuzzy
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "Gukoresha Bya Umurongo ni OYA"
+
+#: awkgram.y:1774
+#, fuzzy
+msgid "backslash not last character on line"
+msgstr "OYA Iheruka Inyuguti ku Umurongo"
+
+#: awkgram.y:1819
+#, fuzzy
+msgid "POSIX does not allow operator `**='"
+msgstr "OYA Kwemerera Mukoresha"
+
+#: awkgram.y:1821
+#, fuzzy
+msgid "old awk does not support operator `**='"
+msgstr "ki/ bishaje OYA Gushigikira Mukoresha"
+
+#: awkgram.y:1830
+#, fuzzy
+msgid "POSIX does not allow operator `**'"
+msgstr "OYA Kwemerera Mukoresha"
+
+#: awkgram.y:1832
+#, fuzzy
+msgid "old awk does not support operator `**'"
+msgstr "ki/ bishaje OYA Gushigikira Mukoresha"
+
+#: awkgram.y:1863
+#, fuzzy
+msgid "operator `^=' is not supported in old awk"
+msgstr "Mukoresha ni OYA in ki/ bishaje"
+
+#: awkgram.y:1871
+#, fuzzy
+msgid "operator `^' is not supported in old awk"
+msgstr "Mukoresha ni OYA in ki/ bishaje"
+
+#: awkgram.y:1955 awkgram.y:1970
+#, fuzzy
+msgid "unterminated string"
+msgstr "Ikurikiranyanyuguti"
+
+#: awkgram.y:2155
+#, fuzzy, c-format
+msgid "invalid char '%c' in expression"
+msgstr "Sibyo INYUGUTI in imvugo"
+
+#: awkgram.y:2203
+#, fuzzy, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s'ni a Umugereka"
+
+#: awkgram.y:2206
+#, fuzzy, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s'ni a Umugereka"
+
+#: awkgram.y:2209
+#, fuzzy, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "OYA Kwemerera"
+
+#: awkgram.y:2213
+#, fuzzy, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s'ni OYA in ki/ bishaje"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr ""
+
+#: awkgram.y:2301
+#, fuzzy, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%dni Sibyo Nka Umubare Bya ingingo kugirango"
+
+#: awkgram.y:2320 awkgram.y:2323
+#, fuzzy
+msgid "match: third argument is a gawk extension"
+msgstr "BIHUYE ni a Umugereka"
+
+#: awkgram.y:2336
+#, fuzzy, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s:Ikurikiranyanyuguti Nka Iheruka Bya GUSIMBURANYA Oya INGARUKA"
+
+#: awkgram.y:2339
+#, fuzzy, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "%sni OYA a Igikoresho"
+
+#: awkgram.y:2366 awkgram.y:2369
+#, fuzzy
+msgid "close: second argument is a gawk extension"
+msgstr "Gufunga ISEGONDA ni a Umugereka"
+
+#: awkgram.y:2379
+#, fuzzy
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "Gukoresha Bya ni Gukuraho... Nyobora"
+
+#: awkgram.y:2394
+#, fuzzy
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "Gukoresha Bya ni Gukuraho... Nyobora"
+
+#: awkgram.y:2465
+#, fuzzy, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "Umumaro"
+
+#: awkgram.y:2498
+#, fuzzy, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "Umumaro IMPINDURAGACIRO"
+
+#: awkgram.y:2610
+#, fuzzy, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "OYA Gufungura kugirango"
+
+#: awkgram.y:2611 profile.c:93
+#, fuzzy
+msgid "sending profile to standard error"
+msgstr "Ibijyana Kuri Bisanzwe Ikosa"
+
+#: awkgram.y:2643
+#, fuzzy, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s:Gufunga Byanze"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr ""
+
+#: awkgram.y:2791
+#, fuzzy
+msgid "there were shadowed variables."
+msgstr "Bihawe igicucu Ibihinduka"
+
+#: awkgram.y:2864
+#, fuzzy, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "Umumaro Gukoresha Umumaro Izina: Nka Izina:"
+
+#: awkgram.y:2874
+#, fuzzy, c-format
+msgid "function name `%s' previously defined"
+msgstr "Umumaro Izina:"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, fuzzy, c-format
+msgid "function `%s' called but never defined"
+msgstr "Umumaro Nta narimwe"
+
+#: awkgram.y:3034
+#, fuzzy, c-format
+msgid "function `%s' defined but never called"
+msgstr "Umumaro Nta narimwe"
+
+#: awkgram.y:3061
+#, fuzzy, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "kugirango Icyungo Agaciro"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"Umumaro Na: Umwanya hagati Izina: Na Cyangwa Nka a IMPINDURAGACIRO Cyangwa "
+"Imbonerahamwe"
+
+#: builtin.c:145
+#, fuzzy, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%sKuri Byanze"
+
+#: builtin.c:146
+#, fuzzy
+msgid "standard output"
+msgstr "Bisanzwe Ibisohoka"
+
+#: builtin.c:147
+#, fuzzy
+msgid "reason unknown"
+msgstr "Kitazwi"
+
+#: builtin.c:160
+#, fuzzy
+msgid "exp: received non-numeric argument"
+msgstr "EXP BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:166
+#, fuzzy, c-format
+msgid "exp: argument %g is out of range"
+msgstr "EXP ni Inyuma Bya Urutonde"
+
+#: builtin.c:224
+#, fuzzy, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr "kugirango OYA"
+
+#: builtin.c:227
+#, fuzzy, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr "IDOSIYE kugirango OYA"
+
+#: builtin.c:239
+#, fuzzy, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "ni OYA Gufungura IDOSIYE Cyangwa"
+
+#: builtin.c:332
+#, fuzzy
+msgid "index: received non-string first argument"
+msgstr "Umubarendanga BYAKIRIWE Ikurikiranyanyuguti Itangira"
+
+#: builtin.c:334
+#, fuzzy
+msgid "index: received non-string second argument"
+msgstr "Umubarendanga BYAKIRIWE Ikurikiranyanyuguti ISEGONDA"
+
+#: builtin.c:449
+#, fuzzy
+msgid "int: received non-numeric argument"
+msgstr "INT BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`Gusiba ni a Umugereka"
+
+#: builtin.c:481
+#, fuzzy
+msgid "length: received non-string argument"
+msgstr "Uburebure BYAKIRIWE Ikurikiranyanyuguti"
+
+#: builtin.c:506
+#, fuzzy
+msgid "log: received non-numeric argument"
+msgstr "LOG BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:509
+#, fuzzy, c-format
+msgid "log: received negative argument %g"
+msgstr "LOG BYAKIRIWE"
+
+#: builtin.c:673 builtin.c:676
+#, fuzzy
+msgid "must use `count$' on all formats or none"
+msgstr "Gukoresha IBARA ku Byose Imiterere Cyangwa Ntacyo"
+
+#: builtin.c:778
+#, fuzzy
+msgid "`$' is not permitted in awk formats"
+msgstr "`$'ni OYA in Imiterere"
+
+#: builtin.c:784
+#, fuzzy
+msgid "arg count with `$' must be > 0"
+msgstr "IBARA Na: 0"
+
+#: builtin.c:786
+#, fuzzy, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "IBARA Biruta Igiteranyo Umubare Bya ingingo"
+
+#: builtin.c:788
+#, fuzzy
+msgid "`$' not permitted after period in format"
+msgstr "`$'OYA Nyuma Igihe in Imiterere"
+
+#: builtin.c:801
+#, fuzzy
+msgid "no `$' supplied for positional field width or precision"
+msgstr "Oya kugirango Umwanya Ubugari Cyangwa"
+
+#: builtin.c:867
+#, fuzzy
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`ni in Imiterere"
+
+#: builtin.c:871
+#, fuzzy
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`ni OYA in Imiterere"
+
+#: builtin.c:882
+#, fuzzy
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`ni in Imiterere"
+
+#: builtin.c:886
+#, fuzzy
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`ni OYA in Imiterere"
+
+#: builtin.c:897
+#, fuzzy
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`ni in Imiterere"
+
+#: builtin.c:901
+#, fuzzy
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`ni OYA in Imiterere"
+
+#: builtin.c:1132
+#, fuzzy, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[S Agaciro ni Inyuma Bya Urutonde kugirango Imiterere"
+
+#: builtin.c:1198
+#, fuzzy
+msgid "not enough arguments to satisfy format string"
+msgstr "OYA ingingo Kuri Imiterere Ikurikiranyanyuguti"
+
+#: builtin.c:1200
+#, fuzzy
+msgid "^ ran out for this one"
+msgstr "^Inyuma kugirango iyi"
+
+#: builtin.c:1205
+#, fuzzy
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[S Imiterere OYA Igenzura Ibaruwa..."
+
+#: builtin.c:1208
+#, fuzzy
+msgid "too many arguments supplied for format string"
+msgstr "ingingo kugirango Imiterere Ikurikiranyanyuguti"
+
+#: builtin.c:1274 builtin.c:1277
+#, fuzzy
+msgid "printf: no arguments"
+msgstr "Oya ingingo"
+
+#: builtin.c:1301
+#, fuzzy
+msgid "sqrt: received non-numeric argument"
+msgstr "SQRT BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:1305
+#, fuzzy, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "SQRT Na:"
+
+#: builtin.c:1329
+#, fuzzy, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "Gutangira Umubarendanga ni Sibyo ikoresha 1."
+
+#: builtin.c:1334
+#, fuzzy, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "Umubare wuzuye Gutangira Umubarendanga"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "Uburebure ni OYA 1."
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "Uburebure ni OYA 0"
+
+#: builtin.c:1362
+#, fuzzy, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "Umubare wuzuye Uburebure"
+
+#: builtin.c:1367
+#, fuzzy, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "Uburebure kugirango Ikurikiranyanyuguti gushyiraho umugereka Kuri"
+
+#: builtin.c:1379
+#, fuzzy
+msgid "substr: source string is zero length"
+msgstr "Inkomoko Ikurikiranyanyuguti ni Zeru Uburebure"
+
+#: builtin.c:1395
+#, fuzzy, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "Gutangira Umubarendanga ni Impera Bya Ikurikiranyanyuguti"
+
+#: builtin.c:1403
+#, fuzzy, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr "Uburebure ku Gutangira Umubarendanga Uburebure Bya Itangira"
+
+#: builtin.c:1478
+#, fuzzy
+msgid "strftime: received non-string first argument"
+msgstr "BYAKIRIWE Ikurikiranyanyuguti Itangira"
+
+#: builtin.c:1484
+#, fuzzy
+msgid "strftime: received empty format string"
+msgstr "BYAKIRIWE ubusa Imiterere Ikurikiranyanyuguti"
+
+#: builtin.c:1493
+#, fuzzy
+msgid "strftime: received non-numeric second argument"
+msgstr "BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:1556
+#, fuzzy
+msgid "mktime: received non-string argument"
+msgstr "BYAKIRIWE Ikurikiranyanyuguti"
+
+#: builtin.c:1601
+#, fuzzy
+msgid "system: received non-string argument"
+msgstr "Sisitemu BYAKIRIWE Ikurikiranyanyuguti"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "Indango Kuri Itatangijwe Umwanya"
+
+#: builtin.c:1827
+#, fuzzy
+msgid "tolower: received non-string argument"
+msgstr "BYAKIRIWE Ikurikiranyanyuguti"
+
+#: builtin.c:1857
+#, fuzzy
+msgid "toupper: received non-string argument"
+msgstr "BYAKIRIWE Ikurikiranyanyuguti"
+
+#: builtin.c:1890
+#, fuzzy
+msgid "atan2: received non-numeric first argument"
+msgstr "ATAN2 BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:1892
+#, fuzzy
+msgid "atan2: received non-numeric second argument"
+msgstr "ATAN2 BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:1911
+#, fuzzy
+msgid "sin: received non-numeric argument"
+msgstr "SIN BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:1927
+#, fuzzy
+msgid "cos: received non-numeric argument"
+msgstr "COS BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:1977
+#, fuzzy
+msgid "srand: received non-numeric argument"
+msgstr "BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:2012
+#, fuzzy
+msgid "match: third argument is not an array"
+msgstr "BIHUYE ni OYA Imbonerahamwe"
+
+#: builtin.c:2555
+#, fuzzy
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "Bya 0 Nka 1."
+
+#: builtin.c:2715
+#, fuzzy
+msgid "lshift: received non-numeric first argument"
+msgstr "BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:2723
+#, fuzzy, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "Uduciro Ibisubizo ku"
+
+#: builtin.c:2725
+#, fuzzy, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "Uduciro"
+
+#: builtin.c:2727
+#, fuzzy, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "Binini Gusunika Agaciro Ibisubizo ku"
+
+#: builtin.c:2753
+#, fuzzy
+msgid "rshift: received non-numeric first argument"
+msgstr "BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:2761
+#, fuzzy, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "Uduciro Ibisubizo ku"
+
+#: builtin.c:2763
+#, fuzzy, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "Uduciro"
+
+#: builtin.c:2765
+#, fuzzy, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "Binini Gusunika Agaciro Ibisubizo ku"
+
+#: builtin.c:2791
+#, fuzzy
+msgid "and: received non-numeric first argument"
+msgstr "Na BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "Na BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:2799
+#, fuzzy, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "Na Uduciro Ibisubizo ku"
+
+#: builtin.c:2801
+#, fuzzy, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "Na Uduciro"
+
+#: builtin.c:2827
+#, fuzzy
+msgid "or: received non-numeric first argument"
+msgstr "Cyangwa BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "Cyangwa BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:2835
+#, fuzzy, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "Cyangwa Uduciro Ibisubizo ku"
+
+#: builtin.c:2837
+#, fuzzy, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "Cyangwa Uduciro"
+
+#: builtin.c:2863
+#, fuzzy
+msgid "xor: received non-numeric first argument"
+msgstr "BYAKIRIWE Bikurikije umubare Itangira"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "BYAKIRIWE Bikurikije umubare ISEGONDA"
+
+#: builtin.c:2871
+#, fuzzy, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "Uduciro Ibisubizo ku"
+
+#: builtin.c:2873
+#, fuzzy, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "Uduciro"
+
+#: builtin.c:2897
+#, fuzzy
+msgid "compl: received non-numeric argument"
+msgstr "BYAKIRIWE Bikurikije umubare"
+
+#: builtin.c:2903
+#, fuzzy, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "Agaciro Ibisubizo ku"
+
+#: builtin.c:2905
+#, fuzzy, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "Agaciro"
+
+#: builtin.c:3078
+#, fuzzy, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "ni OYA a Byemewe Umwanya Icyiciro"
+
+#: eval.c:303
+#, fuzzy, c-format
+msgid "unknown nodetype %d"
+msgstr "Kitazwi"
+
+#: eval.c:353
+#, fuzzy
+msgid "buffer overflow in genflags2str"
+msgstr "Byarenze urugero in"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, fuzzy, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "Kuri Gukoresha Imbonerahamwe in a Imvugiro"
+
+#: eval.c:733
+#, fuzzy, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr "kugirango Imbonerahamwe Byahinduwe Ingano Bivuye Kuri"
+
+#: eval.c:754
+#, fuzzy
+msgid "`break' outside a loop is not portable"
+msgstr "`Hanze a ni OYA"
+
+#: eval.c:758
+#, fuzzy
+msgid "`break' outside a loop is not allowed"
+msgstr "`Hanze a ni OYA"
+
+#: eval.c:775
+#, fuzzy
+msgid "`continue' outside a loop is not portable"
+msgstr "`Hanze a ni OYA"
+
+#: eval.c:779
+#, fuzzy
+msgid "`continue' outside a loop is not allowed"
+msgstr "`Hanze a ni OYA"
+
+#: eval.c:813
+#, fuzzy
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`Bivuye a"
+
+#: eval.c:815
+#, fuzzy
+msgid "`next' cannot be called from an END rule"
+msgstr "`Bivuye"
+
+#: eval.c:824
+#, fuzzy
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`Bivuye a"
+
+#: eval.c:826
+#, fuzzy
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`Bivuye"
+
+#: eval.c:875
+#, fuzzy
+msgid "statement has no effect"
+msgstr "Inyandiko Oya INGARUKA"
+
+#: eval.c:952 eval.c:1893
+#, fuzzy, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "Gukoresha Umumaro Izina: Nka IMPINDURAGACIRO Cyangwa Imbonerahamwe"
+
+#: eval.c:959 eval.c:965
+#, fuzzy, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "Indango Kuri Itatangijwe"
+
+#: eval.c:974 eval.c:1902
+#, fuzzy, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "Indango Kuri Itatangijwe IMPINDURAGACIRO"
+
+#: eval.c:1120
+#, fuzzy
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr "Ingaruka in imvugo Byahinduwe i Uburebure Bya"
+
+#: eval.c:1200
+#, fuzzy
+msgid "assignment used in conditional context"
+msgstr "Igenera in Imvugiro"
+
+#: eval.c:1278
+#, fuzzy
+msgid "division by zero attempted"
+msgstr "ku Zeru"
+
+#: eval.c:1293
+#, fuzzy, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "ku Zeru in"
+
+#: eval.c:1308 profile.c:714
+#, fuzzy, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "Ubwoko in"
+
+#: eval.c:1471
+#, fuzzy
+msgid "division by zero attempted in `/='"
+msgstr "ku Zeru in"
+
+#: eval.c:1493
+#, fuzzy, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "ku Zeru in"
+
+#: eval.c:1758
+#, fuzzy, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "Umumaro Na: Birenzeho ingingo"
+
+#: eval.c:1802
+#, fuzzy, c-format
+msgid "function `%s' not defined"
+msgstr "Umumaro OYA"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr ""
+
+#: eval.c:2023
+#, fuzzy
+msgid "attempt to field reference from non-numeric value"
+msgstr "Kuri Umwanya Indango Bivuye Bikurikije umubare Agaciro"
+
+#: eval.c:2025
+#, fuzzy
+msgid "attempt to reference from null string"
+msgstr "Kuri Indango Bivuye NTAGIHARI Ikurikiranyanyuguti"
+
+#: eval.c:2031
+#, fuzzy, c-format
+msgid "attempt to access field %d"
+msgstr "Kuri Umwanya"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+#, fuzzy
+msgid "assignment is not allowed to result of builtin function"
+msgstr "Igenera ni OYA Kuri Igisubizo Bya Umumaro"
+
+#: eval.c:2123
+#, fuzzy
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`ni a Umugereka"
+
+#: eval.c:2153
+#, fuzzy
+msgid "`BINMODE' is a gawk extension"
+msgstr "`ni a Umugereka"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr ""
+
+#: eval.c:2353
+#, fuzzy
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "Bidakora Kuri Igenera Kuri"
+
+#: ext.c:60 ext.c:64
+#, fuzzy
+msgid "`extension' is a gawk extension"
+msgstr "`ni a Umugereka"
+
+#: ext.c:74
+#, fuzzy, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "Umugereka Gufungura"
+
+#: ext.c:82
+#, fuzzy, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "Umugereka Isomero Umumaro"
+
+#: ext.c:102
+#, fuzzy
+msgid "extension: missing function name"
+msgstr "Umugereka Ibuze Umumaro Izina:"
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "Umugereka Inyuguti in Umumaro Izina:"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "Umugereka Umumaro"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "Umugereka Umumaro"
+
+#: ext.c:122
+#, fuzzy, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr "Umugereka Gukoresha in Nka Umumaro Izina:"
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "Umugereka Umumaro Izina:"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "Umumaro Kuri Oya Birenzeho S"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "Umumaro Ibuze"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "Umumaro Kuri Gukoresha Nka Imbonerahamwe"
+
+#: ext.c:218
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "Umumaro Kuri Gukoresha Imbonerahamwe Nka a"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr ""
+
+#: field.c:326
+#, fuzzy
+msgid "NF set to negative value"
+msgstr "Gushyiraho Kuri Agaciro"
+
+#: field.c:819
+#, fuzzy
+msgid "split: second argument is not an array"
+msgstr "Gutandukanya ISEGONDA ni OYA Imbonerahamwe"
+
+#: field.c:853
+#, fuzzy
+msgid "split: null string for third arg is a gawk extension"
+msgstr "Gutandukanya NTAGIHARI Ikurikiranyanyuguti kugirango ni a Umugereka"
+
+#: field.c:905
+#, fuzzy
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`ni a Umugereka"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+#, fuzzy
+msgid "null string for `FS' is a gawk extension"
+msgstr "NTAGIHARI Ikurikiranyanyuguti kugirango ni a Umugereka"
+
+#: getopt.c:571 getopt.c:590
+#, fuzzy, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s:Ihitamo ni"
+
+#: getopt.c:623 getopt.c:627
+#, fuzzy, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s:Ihitamo Kwemerera"
+
+#: getopt.c:636 getopt.c:641
+#, fuzzy, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s:Ihitamo Kwemerera"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, fuzzy, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s:Ihitamo"
+
+#: getopt.c:747 getopt.c:750
+#, fuzzy, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s:Ihitamo"
+
+#: getopt.c:758 getopt.c:761
+#, fuzzy, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s:Ihitamo"
+
+#: getopt.c:816 getopt.c:819
+#, fuzzy, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s:Ihitamo"
+
+#: getopt.c:825 getopt.c:828
+#, fuzzy, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s:Sibyo Ihitamo"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, fuzzy, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s:Ihitamo"
+
+#: getopt.c:955 getopt.c:974
+#, fuzzy, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s:Ihitamo ni"
+
+#: getopt.c:998 getopt.c:1019
+#, fuzzy, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s:Ihitamo Kwemerera"
+
+#: io.c:307
+#, fuzzy, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "Gufungura IDOSIYE kugirango"
+
+#: io.c:398
+#, fuzzy, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "Gufunga Bya Byanze"
+
+#: io.c:536
+#, fuzzy, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "Sibyo Ubwoko in"
+
+#: io.c:542
+#, fuzzy, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "imvugo in Bikurikije umubare Agaciro"
+
+#: io.c:548
+#, fuzzy, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "imvugo kugirango NTAGIHARI Ikurikiranyanyuguti Agaciro"
+
+#: io.c:553
+#, fuzzy, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"Izina ry'idosiye: kugirango Gicurasi Igisubizo Bya Bijyanye n'inyurabwenge "
+"imvugo"
+
+#: io.c:591
+#, fuzzy, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "Bya Na kugirango IDOSIYE"
+
+#: io.c:643
+#, fuzzy, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "Gufungura kugirango Ibisohoka"
+
+#: io.c:652
+#, fuzzy, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "Gufungura kugirango Iyinjiza"
+
+#: io.c:665
+#, fuzzy, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "Gufungura kugirango Iyinjiza Ibisohoka"
+
+#: io.c:669
+#, fuzzy, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "Gufungura kugirango Iyinjiza Ibisohoka"
+
+#: io.c:745
+#, fuzzy, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "Bivuye"
+
+#: io.c:748
+#, fuzzy, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "Kuri"
+
+#: io.c:787
+#, fuzzy
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr "Sisitemu kugirango Gufungura Idosiye Kuri IDOSIYE"
+
+#: io.c:803
+#, fuzzy, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "Gufunga Bya Byanze"
+
+#: io.c:811
+#, fuzzy
+msgid "too many pipes or input files open"
+msgstr "Cyangwa Iyinjiza Idosiye Gufungura"
+
+#: io.c:834
+#, fuzzy
+msgid "close: second argument must be `to' or `from'"
+msgstr "Gufunga ISEGONDA Cyangwa"
+
+#: io.c:848
+#, fuzzy, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "Gufunga."
+
+#: io.c:852
+#, fuzzy
+msgid "close of redirection that was never opened"
+msgstr "Gufunga Bya Nta narimwe"
+
+#: io.c:948
+#, fuzzy, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr "Gufunga OYA Na: ISEGONDA"
+
+#: io.c:964
+#, fuzzy, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "Imimerere ku Gufunga Bya"
+
+#: io.c:967
+#, fuzzy, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "Imimerere ku IDOSIYE Gufunga Bya"
+
+#: io.c:987
+#, fuzzy, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "Oya Gufunga Bya"
+
+#: io.c:990
+#, fuzzy, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "Oya Gufunga Bya"
+
+#: io.c:993
+#, fuzzy, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "Oya Gufunga Bya"
+
+#: io.c:996
+#, fuzzy, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "Oya Gufunga Bya IDOSIYE"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, fuzzy, c-format
+msgid "error writing standard output (%s)"
+msgstr "Ikosa Bisanzwe Ibisohoka"
+
+#: io.c:1029 io.c:1085
+#, fuzzy, c-format
+msgid "error writing standard error (%s)"
+msgstr "Ikosa Bisanzwe Ikosa"
+
+#: io.c:1037
+#, fuzzy, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "Bya Byanze"
+
+#: io.c:1040
+#, fuzzy, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "Bya Kuri Byanze"
+
+#: io.c:1043
+#, fuzzy, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "IDOSIYE Bya Byanze"
+
+#: io.c:1205
+#, fuzzy
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "/Umukiriya OYA Cyiteguye"
+
+#: io.c:1207 io.c:1244
+#, fuzzy
+msgid "only root may use `/inet/raw'."
+msgstr "Imizi Gicurasi Gukoresha"
+
+#: io.c:1242
+#, fuzzy
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "/Seriveri OYA Cyiteguye"
+
+#: io.c:1332
+#, fuzzy, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "Oya Porotokole in Bidasanzwe Izina ry'idosiye:"
+
+#: io.c:1350
+#, fuzzy, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "Bidasanzwe IDOSIYE Izina: ni"
+
+#: io.c:1362
+#, fuzzy, c-format
+msgid "local port invalid in `%s'"
+msgstr "Umuyoboro Sibyo in"
+
+#: io.c:1374
+#, fuzzy
+msgid "must supply a remote hostname to `/inet'"
+msgstr "a Izina ry'inturo: Kuri"
+
+#: io.c:1389
+#, fuzzy
+msgid "must supply a remote port to `/inet'"
+msgstr "a Umuyoboro Kuri"
+
+#: io.c:1395
+#, fuzzy, c-format
+msgid "remote port invalid in `%s'"
+msgstr "Umuyoboro Sibyo in"
+
+#: io.c:1405
+#, fuzzy
+msgid "TCP/IP communications are not supported"
+msgstr "OYA"
+
+#: io.c:1414 io.c:1595
+#, fuzzy, c-format
+msgid "file `%s' is a directory"
+msgstr "IDOSIYE ni a bushyinguro"
+
+#: io.c:1484
+#, fuzzy, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "Gukoresha Bya"
+
+#: io.c:1516
+#, fuzzy
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "Gukoresha Bya"
+
+#: io.c:1581 io.c:1763
+#, fuzzy, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "OYA Gufungura Ubwoko"
+
+#: io.c:1814
+#, fuzzy, c-format
+msgid "close of master pty failed (%s)"
+msgstr "Gufunga Bya Mugenga Byanze"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, fuzzy, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "Gufunga Bya in Byanze"
+
+#: io.c:1819
+#, fuzzy, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "Kuri in Byanze"
+
+#: io.c:1821 io.c:1973
+#, fuzzy, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "Gufunga Bya in Byanze"
+
+#: io.c:1824
+#, fuzzy, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "Kuri in Byanze"
+
+#: io.c:1826 io.c:1845
+#, fuzzy, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "Gufunga Bya Byanze"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, fuzzy, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "Kuri in Byanze"
+
+#: io.c:1923 io.c:1976
+#, fuzzy, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "Kuri in Byanze"
+
+#: io.c:1940 io.c:2113
+#, fuzzy
+msgid "restoring stdout in parent process failed\n"
+msgstr "in"
+
+#: io.c:1945
+#, fuzzy
+msgid "restoring stdin in parent process failed\n"
+msgstr "in"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, fuzzy, c-format
+msgid "close of pipe failed (%s)"
+msgstr "Gufunga Bya Byanze"
+
+#: io.c:2024
+#, fuzzy
+msgid "`|&' not supported"
+msgstr "`|&'OYA"
+
+#: io.c:2090
+#, fuzzy, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "Gufungura"
+
+#: io.c:2131
+#, fuzzy, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "Kurema kugirango"
+
+#: io.c:2506
+#, fuzzy, c-format
+msgid "data file `%s' is empty"
+msgstr "Ibyatanzwe IDOSIYE ni ubusa"
+
+#: io.c:2547 io.c:2555
+#, fuzzy
+msgid "could not allocate more input memory"
+msgstr "OYA Birenzeho Iyinjiza Ububiko"
+
+#: io.c:2919 io.c:2984
+#, fuzzy, c-format
+msgid "error reading input file `%s': %s"
+msgstr "Ikosa Iyinjiza IDOSIYE"
+
+#: io.c:3109
+#, fuzzy
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "Agaciro Bya ni a Umugereka"
+
+#: main.c:338
+#, fuzzy
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "`-M Ihitamo in"
+
+#: main.c:340
+#, fuzzy
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-M Ihitamo Ikoresha: M"
+
+#: main.c:357
+#, fuzzy, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s:Ihitamo"
+
+#: main.c:394
+#, fuzzy
+msgid "empty argument to `--source' ignored"
+msgstr "ubusa Kuri"
+
+#: main.c:467
+#, fuzzy
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "IMPINDURAGACIRO Gushyiraho ku"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr ""
+
+#: main.c:483
+#, fuzzy
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "`--NYACUMI"
+
+#: main.c:487
+#, fuzzy, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "Imizi Gicurasi a Umutekano"
+
+#: main.c:528
+#, fuzzy, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "Gushyiraho Nyabibiri Ubwoko ku"
+
+#: main.c:531
+#, fuzzy, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "Gushyiraho Nyabibiri Ubwoko ku"
+
+#: main.c:533
+#, fuzzy, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "Gushyiraho Nyabibiri Ubwoko ku"
+
+#: main.c:572
+#, fuzzy
+msgid "no program text at all!"
+msgstr "Oya Porogaramu Umwandiko ku Byose"
+
+#: main.c:665
+#, fuzzy, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr "Cyangwa IMISUSIRE Amahitamo F IDOSIYE"
+
+#: main.c:667
+#, fuzzy, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Cyangwa IMISUSIRE Amahitamo IDOSIYE"
+
+#: main.c:672
+#, fuzzy
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "Amahitamo Amahitamo"
+
+#: main.c:673
+#, fuzzy
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "-F IDOSIYE"
+
+#: main.c:674
+#, fuzzy
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "-Umwanya Mutandukanya"
+
+#: main.c:675
+#, fuzzy
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "-v VAR Kugenera... VAR"
+
+#: main.c:676
+#, fuzzy
+msgid "\t-m[fr] val\n"
+msgstr "-M"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr ""
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr ""
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr ""
+
+#: main.c:680
+#, fuzzy
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "-Ibihinduka IDOSIYE Ibihinduka IDOSIYE"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "-Ibijyana IDOSIYE Ibijyana IDOSIYE"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr ""
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr ""
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr ""
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr ""
+
+#: main.c:686
+#, fuzzy
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "-NYACUMI NYACUMI"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr ""
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr ""
+
+#: main.c:693
+#, fuzzy
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "-Ibijyana IDOSIYE Ibijyana IDOSIYE"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr ""
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr ""
+
+#: main.c:696
+#, fuzzy
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "-Inkomoko Porogaramu Inkomoko Porogaramu"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr ""
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr ""
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr ""
+
+#: main.c:703
+#, fuzzy
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr "Icyegeranyo in Na in i Byacapwe Verisiyo"
+
+#: main.c:707
+#, fuzzy
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"ni a Ishusho Na Inonosora Ururimi Mburabuzi Bisanzwe Iyinjiza Na Bisanzwe "
+"Ibisohoka"
+
+#: main.c:711
+#, fuzzy
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr "Igiteranyo Gucapa Igiteranyo Gucapa"
+
+#: main.c:731
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"C Porogaramu ni Kigenga Na Cyangwa i Bya i Nka Verisiyo 2. Bya i ku Ihitamo "
+"Verisiyo"
+
+#: main.c:739
+#, fuzzy
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Porogaramu ni in i ATARIIGIHARWE i Cyangwa A kugirango Birenzeho Birambuye"
+
+#: main.c:745
+#, fuzzy
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"BYAKIRIWE a Gukoporora Bya i Na: iyi Porogaramu NIBA OYA Kwandika Kuri i"
+
+#: main.c:781
+#, fuzzy
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-OYA Gushyiraho Kuri Isunika in"
+
+#: main.c:1018
+#, fuzzy, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr "%s:`%s'Kuri OYA in VAR"
+
+#: main.c:1038
+#, fuzzy, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s'ni OYA a By'amategeko IMPINDURAGACIRO Izina:"
+
+#: main.c:1041
+#, fuzzy, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s'ni OYA a IMPINDURAGACIRO Izina: kugirango IDOSIYE"
+
+#: main.c:1074
+#, fuzzy
+msgid "floating point exception"
+msgstr "Bihindagurika Akadomo Irengayobora(-)"
+
+#: main.c:1081
+#, fuzzy
+msgid "fatal error: internal error"
+msgstr "Ikosa By'imbere Ikosa"
+
+#: main.c:1132
+#, fuzzy, c-format
+msgid "no pre-opened fd %d"
+msgstr "Oya Byahawe imiterere mbere"
+
+#: main.c:1139
+#, fuzzy, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "OYA Byahawe imiterere mbere Gufungura NTAGIHARI kugirango"
+
+#: main.c:1162 main.c:1171
+#, fuzzy, c-format
+msgid "could not find groups: %s"
+msgstr "OYA Gushaka Amatsinda"
+
+#: msg.c:54
+#, fuzzy, c-format
+msgid "cmd. line:"
+msgstr "Cmd+."
+
+#: msg.c:120
+#, fuzzy
+msgid "warning: "
+msgstr "Iburira!"
+
+# starmath/source\smres.src:RID_ERR_IDENT.text
+#: msg.c:142
+#, fuzzy
+msgid "error: "
+msgstr "IKOSA"
+
+#: msg.c:178
+msgid "fatal: "
+msgstr ""
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+#, fuzzy
+msgid "can't convert string to float"
+msgstr "GUHINDURA Ikurikiranyanyuguti Kuri Kureremba"
+
+#: node.c:414
+#, fuzzy
+msgid "backslash at end of string"
+msgstr "ku Impera Bya Ikurikiranyanyuguti"
+
+#: node.c:604
+#, fuzzy
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "OYA Kwemerera"
+
+#: node.c:610
+#, fuzzy
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "Oya in"
+
+#: node.c:644
+#, fuzzy, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "Nka Byuzuye"
+
+#: posix/gawkmisc.c:172
+#, fuzzy, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s%s`%s':OYA Gushyiraho Gufunga ku"
+
+#: profile.c:91
+#, fuzzy, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "OYA Gufungura kugirango"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "By'imbere Ikosa Na: NTAGIHARI"
+
+#: profile.c:531
+#, fuzzy
+msgid "# treated internally as `delete'"
+msgstr "#Nka"
+
+#: profile.c:1168
+#, fuzzy, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "#iyi ni a Umugereka Umumaro"
+
+#: profile.c:1199
+#, fuzzy, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "#Ibijyana Byaremwe"
+
+#: profile.c:1202
+#, fuzzy, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr "#Funga S"
+
+#: profile.c:1212
+#, fuzzy, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr "#S"
+
+#: profile.c:1218
+#, fuzzy, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr "#Funga S"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+
+#: profile.c:1453
+#, fuzzy, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "Ubwoko in"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Ibyatunganye"
+
+#: regcomp.c:163
+#, fuzzy
+msgid "No match"
+msgstr "BIHUYE"
+
+#: regcomp.c:166
+#, fuzzy
+msgid "Invalid regular expression"
+msgstr "Ibisanzwe imvugo"
+
+#: regcomp.c:169
+#, fuzzy
+msgid "Invalid collation character"
+msgstr "Inyuguti"
+
+#: regcomp.c:172
+#, fuzzy
+msgid "Invalid character class name"
+msgstr "Inyuguti ishuri Izina:"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr ""
+
+#: regcomp.c:178
+#, fuzzy
+msgid "Invalid back reference"
+msgstr "Inyuma Indango"
+
+#: regcomp.c:181
+#, fuzzy
+msgid "Unmatched [ or [^"
+msgstr "Cyangwa"
+
+#: regcomp.c:184
+#, fuzzy
+msgid "Unmatched ( or \\("
+msgstr "Cyangwa"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr ""
+
+#: regcomp.c:190
+#, fuzzy
+msgid "Invalid content of \\{\\}"
+msgstr "Ibikubiyemo Bya"
+
+#: regcomp.c:193
+#, fuzzy
+msgid "Invalid range end"
+msgstr "Urutonde Impera"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr ""
+
+#: regcomp.c:199
+#, fuzzy
+msgid "Invalid preceding regular expression"
+msgstr "Ibisanzwe imvugo"
+
+#: regcomp.c:202
+#, fuzzy
+msgid "Premature end of regular expression"
+msgstr "Impera Bya Ibisanzwe imvugo"
+
+#: regcomp.c:205
+#, fuzzy
+msgid "Regular expression too big"
+msgstr "imvugo"
+
+#: regcomp.c:208
+#, fuzzy
+msgid "Unmatched ) or \\)"
+msgstr "Cyangwa"
+
+#: regcomp.c:688
+#, fuzzy
+msgid "No previous regular expression"
+msgstr "Ibanjirije Ibisanzwe imvugo"
+
+#, fuzzy
+#~ msgid "function %s called\n"
+#~ msgstr "Umumaro"
+
+#, fuzzy
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "Umwanya in 0"
--- /dev/null
+# Swedish translation of gawk
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Martin Sjögren <md9ms@mdstud.chalmers.se>, 2001-2002.
+#
+# $Id: sv.po,v 1.23 2003/02/27 18:54:30 martin Exp $
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.1m\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2003-02-27 19:54+0100\n"
+"Last-Translator: Martin Sjögren <md9ms@mdstud.chalmers.se>\n"
+"Language-Team: Swedish <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: array.c:112
+#, fuzzy, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "försök att använda funktionen \"%s\" som vektor"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "försök att använda skalärparametern \"%s\" som en vektor"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "försök att använda skalären \"%s\" som vektor"
+
+#: array.c:156
+#, fuzzy, c-format
+msgid "from %s"
+msgstr "%s (från %s)"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "referens till ickeinitierat element \"%s[\"%s\"]\""
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "index i vektorn \"%s\" är en tom sträng"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: index \"%s\" finns inte i vektorn \"%s\""
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: tom (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: tom (noll)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: tabellstorlek = %d, vektorstorlek = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: är en parameter\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: vektorreferens till %s\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "%s-block måste ha en åtgärdsdel"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "varje regel måste ha ett mönster eller en åtgärdsdel"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "\"%s\" är en inbyggd funktion, den kan inte definieras om"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "regexp-konstanten \"/%s/\" ser ut som en C-kommentar men är inte det"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "regexp-konstanten \"/%s/\" ser ut som en C-kommentar men är inte det"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "kommandot kanske inte har någon effekt"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "\"%s\" använd i %s-åtgärden"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "\"nextfile\" är en gawk-utökning"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "\"return\" använd utanför funktion"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"ensamt \"print\" i BEGIN eller END-regel bör troligen vara 'print \"\"'"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "\"delete array\" är en gawk-utökning"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "\"delete(array)\" är en icke portabel tawk-utökning"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "flerstegs dubbelriktade rör fungerar inte"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "reguljärt uttryck i högerledet av en tilldelning"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "reguljärt uttryck på vänster sida om en \"~\"- eller \"!~\"-operator"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "reguljärt uttryck i högerledet av en jämförelse"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "icke omdirigerad \"getline\" odefinierad inuti END-åtgärd"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "anrop av \"length\" utan parenteser är inte portabelt"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "anrop av \"length\" utan parenteser är föråldrat enligt POSIX"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr ""
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "ogiltig indexuttryck"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "oväntat nyradstecken eller slut på strängen"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "tom programtext på kommandoraden"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "kan inte öppna källfilen \"%s\" för läsning (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "kan inte läsa källfilen \"%s\" (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "källfilen \"%s\" är tom"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "källfilen slutar inte med en ny rad"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "oavslutat reguljärt uttryck slutar med \"\\\" i slutet av filen"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "oavslutat reguljärt uttryck"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "oavslutat reguljärt uttryck i slutet av filen"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "Användning av \"\\ #...\" för radfortsättning är inte portabelt"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "sista tecknet på raden är inte ett omvänt snedstreck"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX tillåter inte operatorn \"**=\""
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "gamla awk stöder inte operatorn \"**=\""
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX tillåter inte operatorn \"**\""
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "gamla awk stöder inte operatorn \"**\""
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "operatorn \"^=\" stöds inte i gamla awk"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "operatorn \"^\" stöds inte i gamla awk"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "oavslutad sträng"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "ogiltigt tecken \"%c\" i uttryck"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "\"%s\" är en gawk-utökning"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "\"%s\" är en Bell Labs-utökning"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX tillåter inte \"%s\""
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "\"%s\" stöds inte i gamla awk"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "\"goto\" anses skadlig!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d är ett ogiltigt antal argument för %s"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: tredje argumentet är en gawk-utökning"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: bokstavlig sträng som sista argument till ersättning har ingen effekt"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "%s: tredje argumentet är inte ett ändringsbart objekt"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: andra argumentet är en gawk-utökning"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"användandet av dcgettext(_\"...\") är felaktigt: ta bort det inledande "
+"understrykningstecknet"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+"användandet av dcngettext(_\"...\") är felaktigt: ta bort det inledande "
+"understrykningstecknet"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funktionen \"%s\": parameter %d, \"%s\", är samma som parameter %d"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "funktionen \"%s\": parametern \"%s\" överskuggar en global variabel"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "kunde inte öpnna \"%s\" för skrivning (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "skickar profilen till standard fel"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: misslyckades att stänga (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() anropad två gånger!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "det fanns överskuggade variabler."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "funktionen \"%s\": kan inte använda funktionsnamn som parameternamn"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funktionsnamnet \"%s\" är definierat sedan tidigare"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "funktionen \"%s\" anropad men aldrig definierad"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "funktionen \"%s\" definierad men aldrig anropad"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "konstant reguljärt uttryck för parameter %d ger ett booleskt värde"
+
+#: awkgram.y:3105
+#, fuzzy, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"funktionen \"%s\" anropad med blanktecken mellan namnet och \"(\",\n"
+"%s"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s till \"%s\" misslyckades (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standard ut"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "okänd anledning"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: fick ett ickenumeriskt argument"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: argumentet %g är inte inom tillåten gräns"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kan inte spola: röret \"%s\" öppnat för läsning, inte skrivning"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kan inte spola: filen \"%s\" öppnad för läsning, inte skrivning"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: \"%s\" är inte en öppen fil, rör eller koprocess"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: första argumentet är inte en sträng"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: andra argumentet är inte en sträng"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: fick ett ickenumeriskt argument"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "\"delete array\" är en gawk-utökning"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: fick ett argument som inte är en sträng"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: fick ett ickenumeriskt argument"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: fick ett negativt argumentet %g"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "måste använda \"count$\" på alla eller inga format"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "\"$\" tillåts inte i awkformat"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "argumentantalet med \"$\" måste vara > 0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "argumentantalet %ld är större än antalet givna argument"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "\"$\" tillåts inte efter en punkt i formatet"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "inget \"$\" bifogat för positionsangiven fältbredd eller precision"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "\"l\" är meningslös i awk-format, ignorerad"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "\"l\" tillåts inte i POSIX awk-format"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "\"L\" är meningslös i awk-format, ignorerad"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "\"L\" tillåts inte i POSIX awk-format"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "\"h\" är meningslös i awk-format, ignorerad"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "\"h\" tillåts inte i POSIX awk-format"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "för få argument för formatsträngen"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "^ tog slut här"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: formatspecifieraren har ingen kommandobokstav"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "för många argument för formatsträngen"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: inga argument"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: fick ickenumeriskt argument"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: anropad med negativt argument %g"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: startindex %g är ogiltigt, använder 1"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: startindex %g som inte är ett heltal kommer trunkeras"
+
+#: builtin.c:1353
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: längden %g är <= 0"
+
+#: builtin.c:1355
+#, fuzzy, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: längden %g är <= 0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: längden %g som inte är ett heltal kommer trunkeras"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr "substr: längden %g är för stor för strängindexering, trunkeras till %g"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: källsträngen är tom"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: startindex %g är bortom strängens slut"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: längden %g vid startindex %g överskrider det första argumentets "
+"längd (%lu)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: fick ett första argument som inte är en sträng"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: fick en tom formatsträng"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: fick ett argument som inte är en sträng"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: fick ett argument som inte är en sträng"
+
+#: builtin.c:1722 eval.c:2039
+#, fuzzy, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "referens till icke initierad variabel \"%s\""
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: fick ett argument som inte är en sträng"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: fick ett argument som inte är en sträng"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: fick ett ickenumeriskt första argument"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: fick ett ickenumeriskt argument"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: fick ett ickenumeriskt argument"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: fick ett ickenumeriskt argument"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: tredje argumentet är inte en vektor"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: Nollan i tredje argumentet behandlad som en etta"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: fick ett ickenumeriskt första argument"
+
+#: builtin.c:2717
+#, fuzzy
+msgid "lshift: received non-numeric second argument"
+msgstr "strftime: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): för stora skiftvärden kommer ge konstiga resultat"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: fick ett ickenumeriskt första argument"
+
+#: builtin.c:2755
+#, fuzzy
+msgid "rshift: received non-numeric second argument"
+msgstr "strftime: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): för stora skiftvärden kommer ge konstiga resultat"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: fick ett ickenumeriskt första argument"
+
+#: builtin.c:2793
+#, fuzzy
+msgid "and: received non-numeric second argument"
+msgstr "atan2: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: fick ett ickenumeriskt första argument"
+
+#: builtin.c:2829
+#, fuzzy
+msgid "or: received non-numeric second argument"
+msgstr "atan2: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: fick ett ickenumeriskt första argument"
+
+#: builtin.c:2865
+#, fuzzy
+msgid "xor: received non-numeric second argument"
+msgstr "atan2: fick ett ickenumeriskt andra argument"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: fick ett ickenumeriskt argument"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): negativa värden kommer ge konstiga resultat"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): flyttalsvärden kommer trunkeras"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: \"%s\" är inte en giltig lokalkategori"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "okänd nodtyp %d"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "buffertöverflöd i genflags2str"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "försök att använda vektorn \"%s\" i skalärsammanhang"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"forslinga: vektorn \"%s\" ändrade storlek från %ld till %ld under "
+"slingexekvering"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "\"break\" utanför en slinga är inte portabelt"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "\"break\" utanför en slinga är inte tillåtet"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "\"continue\" utanför en slinga är inte portabelt"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "\"continue\" utanför en slinga är inte tillåtet"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "\"next\" kan inte anropas från en BEGIN-regel"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "\"next\" kan inte anropas från en END-regel"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "\"nextfile\" kan inte anropas från en BEGIN-regel"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "\"nextfile\" kan inte anropas från en END-regel"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "kommandot har ingen effekt"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "kan inte använda funktionsnamnet \"%s\" som variabel eller vektor"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "referens till icke initierat argument \"%s\""
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referens till icke initierad variabel \"%s\""
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation: sidoeffekter i ett uttryck har ändrat längden av ett annat!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "tilldelning använt i jämförelsesammanhang"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "försökte dividera med noll"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "försökte dividera med noll i \"%%\""
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "otillåten typ (%s) i tree_eval"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "försökte dividera med noll i \"/=\""
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "försökte dividera med noll i \"%%=\""
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "funktionen \"%s\" anropad med fler argument än vad som deklarerats"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "funktionen \"%s\" är inte definierad"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Funktionsanropsstack:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "försök att fältreferera från ickenumeriskt värde"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "försök att referera från tom sträng"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "försök att komma åt fält nummer %d"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "det är inte tillåtet att tilldela resultatet från en inbyggd funktion"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "\"IGNORECASE\" är en gawk-utökning"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "\"BINMODE\" är en gawk-utökning"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "felaktig \"%sFMT\"-specifikation \"%s\""
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "slår av \"--lint\" på grund av en tilldelning till \"LINT\""
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "\"extension\" är en gawk-utökning"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: kan inte öppna \"%s\" (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: bibliotek \"%s\": kan inte anropa funktionen \"%s\" (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:107
+#, fuzzy, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: bibliotek \"%s\": kan inte anropa funktionen \"%s\" (%s)\n"
+
+#: ext.c:113
+#, fuzzy, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: kan inte öppna \"%s\" (%s)\n"
+
+#: ext.c:117
+#, fuzzy, c-format
+msgid "extension: function `%s' already defined"
+msgstr "funktionen \"%s\" är inte definierad"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:124
+#, fuzzy, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "funktionsnamnet \"%s\" är definierat sedan tidigare"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "funktionen \"%s\" definierad men aldrig anropad"
+
+#: ext.c:204
+#, fuzzy, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "funktionen \"%s\" är inte definierad"
+
+#: ext.c:214
+#, fuzzy, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "försök att använda skalären \"%s\" som vektor"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Operationen stöds inte"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF satt till ett negativt värde"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: andra argumentet är inte en vektor"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: tom sträng som tredje argument är en gawk-utökning"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "\"FIELDWIDTHS\" är en gawk-utökning"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "tom sträng som \"FS\" är en gawk-utökning"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: flaggan \"%s\" är tvetydig\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: flaggan \"--%s\" tillåter inte argument\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: flaggan \"%c%s\" tillåter inte argument\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: flaggan \"%s\" kräver ett argument\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: okänd flagga \"--%s\"\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: okänd flagga \"%c%s\"\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: otillåten flagga -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: ogiltig flagga -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: flaggan kräver ett argument -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: flaggan \"-W %s\" är tvetydig\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: flaggan \"-W %s\" tillåter inte något argument\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "kan inte öppna filen \"%s\" för läsning (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "stängning av fd %d (\"%s\") misslyckades (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "ogiltig trädtyp %s i redirect()"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "uttrycket i \"%s\"-omdirigering har bara numeriskt värde"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "uttrycket för \"%s\"-omdirigering har en tom sträng som värde"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"filnamnet \"%s\" för \"%s\"-omdirigering kan vara resultatet av ett logiskt "
+"uttryck"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "onödig blandning av \">\" och \">>\" för filen \"%.*s\""
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "kan inte öppna röret \"%s\" för utmatning (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "kan inte öppna röret \"%s\" för inmatning (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "kan inte öppna tvåvägsuttaget \"%s\" för in-/utmatning (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "kan inte öppna tvåvägsröret \"%s\" för in-/utmatning (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "kan inte dirigera om från \"%s\" (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "kan inte dirigera om till \"%s\" (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"nådde systembegränsningen för öppna filer: börjar multiplexa fildeskriptorer"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "stängning av \"%s\" misslyckades (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "för många rör eller indatafiler öppna"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: andra argumentet måste vara \"to\" eller \"from\""
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: \"%.*s\" är inte en öppen fil, rör eller koprocess"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "stängning av omdirigering som aldrig öppnades"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: omdirigeringen \"%s\" öppnades inte med \"|&\", andra argumentet "
+"ignorerat"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "felstatus (%d) från rörstängning av \"%s\" (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "felstatus (%d) från filstängning av \"%s\" (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "ingen explicit stängning av uttaget \"%s\" tillhandahållen"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "ingen explicit stängning av koprocessen \"%s\" tillhandahållen"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "ingen explicit stängning av röret \"%s\" tillhandahållen"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "ingen explicit stängning av filen \"%s\" tillhandahållen"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "fel vid skrivning till standard ut (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "fel vid skrivning till standard fel (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "rörspolning av \"%s\" misslyckades (%s)"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "koprocesspolning av röret till \"%s\" misslyckades (%s)"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "filspolning av \"%s\" misslyckades (%s)"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "/inet/raw-klient är tyvärr inte klar än"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "bara root kan använda \"/inet/raw\"."
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "/inet/raw-server inte redo än, ledsen"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+"inget (känt) protokoll tillhandahållet i det speciella filnamnet \"%s\""
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "speciellt filnamn \"%s\" är ofullständigt"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "lokal port ogiltig i \"%s\""
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "måste tillhandahålla ett fjärrdatornamn till \"/inet\""
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "måste tillhandahålla en fjärrport till \"/inet\""
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "fjärrporten ogiltig i \"%s\""
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP-kommunikation stöds inte"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "filen \"%s\" är en katalog"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "använd \"PROCINFO[\"%s\"]\" istället för \"%s\""
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "använd \"PROCINFO[...]\" istället för \"dev/user\""
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "kunde inte öppna \"%s\", läge \"%s\""
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "stängning av huvudpty misslyckades (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "stängning av standard ut i barnet misslyckades (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "flyttandet av slavpty till standard ut i barnet misslyckades (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "stängning av standard in i barnet misslyckades (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "flyttandet av slavpty till standard in i barnet misslyckades (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "stängning av slavpty misslyckades (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "flyttande av rör till standard ut i barnet misslyckades (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "flyttande av rör till standard in i barnet misslyckades (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "återställande av standard ut i förälderprocessen misslyckades\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "återställande av standard in i förälderprocessen misslyckades\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "stängning av röret misslyckades (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "\"|&\" stöds inte"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "kan inte öppna röret \"%s\" (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "kan inte skapa barnprocess för \"%s\" (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "datafilen \"%s\" är tom"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "kunde inte allokera mer indataminne"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "fel vid läsning av indatafilen \"%s\": %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "flerteckensvärdet av \"RS\" är en gawk-utökning"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "\"-m[fr]\"-flaggan är irrelevant i gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m-flaggans användning: \"-m[fr] nnn\""
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: flaggan \"-W %s\" okänd, ignorerad\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "tomt argument till \"--source\" ignorerat"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "miljövariabeln \"POSIXLY_CORRECT\" satt: slår på \"--posix\""
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "\"--posix\" åsidosätter \"--traditional\""
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr "\"--posix\"/\"--traditional\" åsidosätter \"--non-decimal-data\""
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "att köra %s setuid root kan vara ett säkerhetsproblem"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "kan inte sätta binärläge på standard in (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "kan inte sätta binärläge på standard ut (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "kan inte sätta binärläge på standard fel (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "ingen programtext alls!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Användning: %s [POSIX- eller GNU-stilsflaggor] -f progfil [--] fil ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr "Användning: %s [POSIX- eller GNU-stilsflaggor] %cprogram%c fil ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "POSIX-flaggor:\t\tGNU långa flaggor:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f progfil\t\t--file=progfil\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr "\t-v var=värde\t\t--assign=var=värde\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] värde\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr "\t-W compat\t\t--compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr "\t-W copyleft\t\t--copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr "\t-W copyright\t\t--copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr "\t-W dump-variables[=fil]\t--dump-variables[=fil]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W profile[=fil]\t--profile[=fil]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-W gen-po\t\t--gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr "\t-W help\t\t\t--help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-W lint-old\t\t--lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr "\t-W nostalgia\t\t--nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-W parsedebug\t\t--parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr "\t-W profile[=fil]\t--profile[=fil]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-W re-interval\t\t--re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr "\t-W source=programtext\t--source=programtext\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr "\t-W traditional\t\t--traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr "\t-W usage\t\t--usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr "\t-W version\t\t--version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"För att rapportera buggar, se noden \"Bugs\" i \"gawk.info\",\n"
+"vilket är sektionen \"Reporting Problems and Bugs\" i den utskrivna\n"
+"versionen.\n"
+"Rapportera synpunkter på översättningen till <sv@li.org>.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk är ett mönsterskannande och -bearbetande språk.\n"
+"Normalt läser det från standard in och skriver till standard ut.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Exempel:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' fil\n"
+"\tgawk -F: '{print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Copyright © 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Detta program är fri programvara. Du kan distribuera det och/eller\n"
+"modifiera det under villkoren i GNU General Public License, publicerad\n"
+"av Free Software Foundation, antingen version 2 eller (om du så vill)\n"
+"någon senare version.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Detta program distribueras i hopp om att det ska vara användbart,\n"
+"men UTAN NÅGON SOM HELST GARANTI, även utan underförstådd garanti\n"
+"om SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL. Se GNU\n"
+"General Public License för ytterligare information.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Du bör ha fått en kopia av GNU General Public License tillsammans\n"
+"med detta program. Om inte, skriv till Free Software Foundation,\n"
+"Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft sätter inte FS till tab i POSIX-awk"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr "%s: Argumentet \"%s\" till \"-v\" är inte på formatet \"var=värde\"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "\"%s\" är inte ett giltigt variabelnamn"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "\"%s\" är inte ett variabelnamn, letar efter filen \"%s=%s\""
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "flyttalsundantag"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "ödesdigert fel: internt fel"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "ingen föröppnad fd %d"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "kunde inte föröppna /dev/null för fd %d"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "kunde inte hitta grupper: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "kommandorad:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "varning: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "fel: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "ödesdigert: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "kan inte konvertera en sträng till flyttal"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "omvänt snedstreck i slutet av strängen"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX tillåter inte \"\\x\"-kontrollsekvenser"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "inga hexadecimala siffror i \"\\x\"-kontrollsekvenser"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "kontrollsekvensen \"\\%c\" behandlad som bara \"%c\""
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s \"%s\": kunde inte sätta stäng-vid-exec (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "kunde inte öppna \"%s\" för skrivning: %s"
+
+#: profile.c:467
+#, fuzzy, c-format
+msgid "internal error: %s with null vname"
+msgstr "internt fel: Node_var med null vname"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# behandlad internt som \"delete\""
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr ""
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawkprofil, skapad %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN-block\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Regel/regler\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END-block\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Funktioner, listade alfabetiskt\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "oväntad typ %s i prec_level"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Lyckades"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Misslyckades"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Ogiltigt reguljärt uttryck"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Ogiltigt kollationeringstecken"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Ogiltigt teckenklassnamn"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Eftersläpande omvänt snedstreck"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Ogiltig bakåtrerefens"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Obalanserad [ eller [^"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Obalanserad ( eller \\("
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Obalanserad \\{"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Ogiltigt innehåll i \\{\\}"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Ogiltigt omfångsslut"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Minnet slut"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Ogiltigt föregående reguljärt uttryck"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "För tidigt slut på reguljärt uttryck"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Reguljärt uttryck för stort"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Obalanserad ) eller \\)"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Inget föregående reguljärt uttryck"
+
+#~ msgid "function %s called\n"
+#~ msgstr "funktionen %s anropad\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "fält %d i FIELDWIDTHS måste vara > 0"
+
+#~ msgid "or used as a variable or an array"
+#~ msgstr "eller använd som variabel eller vektor"
+
+#~ msgid "regex match failed, not enough memory to match string \"%.*s%s\""
+#~ msgstr ""
+#~ "regexmatchning misslyckades, inte tillräckligt mycket minne för att "
+#~ "matcha \"%.*s%s\""
+
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: längden %g är < 0"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: otillåten användning av variabeln \"%s\" som vektor"
+
+#, fuzzy
+#~ msgid "%s: gvar_ref to %s\n"
+#~ msgstr "%s: vektorreferens till %s\n"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: första argumentet är inte en vektor"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: andra argumentet är inte en vektor"
+
+#, fuzzy
+#~ msgid ""
+#~ "attempt to use array parameter `%s' that was passed from global scalar `%"
+#~ "s'"
+#~ msgstr "försök att använda skalärparametern \"%s\" som en vektor"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "internt fel: Node_var_vektor med null vname"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "För att rapportera fel, se noden \"Bugs\" i \"gawk.info\" som är\n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "ogiltig syntax i namnet \"%s\" för variabeltilldelning"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "eller använt i andra uttryckssammanhang"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "\"%s\" är en funktion, tilldelning är inte tillåtet"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "BEGIN-block måste ha en åtgärdsdel"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "\"nextfile\" använd i BEGIN- eller END-åtgärd"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "icke omdirigerad \"getline\" odefinierade inuti BEGIN- eller END-åtgärd"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "fptr %x är inte i tokentab\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "gsub: tredje argumentet är inte ett ändringsbart objekt"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Oavslutad \\-kontrollsekvens"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "oavslutat upprepningsantal"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "felaktigt utformat upprepningsantal"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "Obalanserad ["
+
+#~ msgid "Unbalanced ("
+#~ msgstr "Obalanserad ("
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Inga syntaxbitar för reguljära uttryck angivna"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "Obalanserad )"
+
+#~ msgid "out of memory"
+#~ msgstr "slut på minne"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "internt fel: filen \"%s\", rad %d\n"
--- /dev/null
+# Turkish translations for GNU awk messages
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Nilgün Belma Bugüner <nilgun@superonline.com>, 2001, ..., 2004.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.3l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2004-07-19 10:15+0300\n"
+"Last-Translator: Nilgün Belma Bugüner <nilgun@superonline.com>\n"
+"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.0\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "`%s' işlevi dizi olarak kullanılmaya çalışılıyor"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "sayısal paramaetre `%s' bir dizi olarak kullanılmaya çalışılıyor"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "sayısal `%s' dizi olarak kullanılmaya çalışılıyor"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "%s'den"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "ilklendirilmemiş öğeye ( %s[\"%s\"] ) başvuru yapılıyor"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "dizinin indisi `%s' bir null dizge"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: `%s' indeksi `%s' dizisinde değil"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: boş (null)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: boş (sıfır)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: tablo_uzunluğu = %d, dizi_indisi = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: parametredir\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: %s için dizi başvurusu\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "%s blokları bir eylem bölümü içermeli"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "her kural bir eylem bölümü veya bir kalıp içermeli"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "`%s' bir yerleşik işlevdir, yeniden atanamaz"
+
+#: awkgram.y:313
+#, fuzzy
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr "düzenli ifade sabiti `/%s/' bir C açıklaması gibi görünüyor ama değil"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr "düzenli ifade sabiti `/%s/' bir C açıklaması gibi görünüyor ama değil"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "deyim bir etkiye sahip olmayabilir"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "`%s' %s eyleminde kullanılmış"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "`nextfile' bir gawk uzantısıdır"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "`return' işlev bağlamının dışında kullanılmış"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr "BEGIN veya END kuralındaki `print' aslında `print \"\"' olmalıydı"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "`delete array' bir gawk uzantısıdır"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "`delete array' uyarlanabilir olmayan bir gawk uzantısıdır"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "switch içinde yinelenmiş case değerleri var: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "switch içinde yinelenmiş `default' saptandı"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "çok katlı iki yönlü veriyolları çalışmaz"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "düzenli ifade atamanın sağında"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "düzenli ifade `~' ya da `!~' işlemiminin solunda"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "düzenli ifade karşılaştırmanın sağında"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr "END eyleminin içinde yönlendirme yapmayan `getline' tanımsız"
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "parantezsiz `length' çağrısı taşınabilir değil"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "parantezsiz `length' çağrısı POSIX'e uygun değil"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "dizi olmayan değişken dizi olarak kullanılmış"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "indis ifadesi geçersiz"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "beklenmeyen satırsonu ya da dizge sonu"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "komut satırında boş program metni"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "kaynak dosyası `%s' okumak için açılamıyor (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "kaynak dosyası `%s' okunamıyor (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "kaynak dosyası `%s' boş"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "kaynak dosyasının sonunda satırsonu eksik"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr "sonlandırılmamış düzenli ifade dosya sonunda `\\' ile bitiyor"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "sonlandırılmamış düzenli ifade"
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "dosya sonunda sonlandırılmamış düzenli ifade"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "`\\ #...' satır uzatma kullanımı taşınabilir değil"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "tersbölü satırdaki son karakter değil"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "`**=' işlemimi POSIX uyumlu değil"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "`**=' işlemimini eski awk desteklemiyor"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "`**' işlemimi POSIX uyumlu değil"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "`**' işlemimini eski awk desteklemiyor"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "`^=' işlemimini eski awk desteklemiyor"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "`^' işlemimini eski awk desteklemiyor"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "sonlandırılmamış dizge"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "ifade içinde '%c' karakteri geçersiz"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "`%s' bir gawk uzantısıdır"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "`%s' bir Bell Laboratuarları uzantısıdır"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "`%s' POSIX uyumlu değil"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "`%s' eski awk tarafından desteklemiyor"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "`goto' zararlı sayılır!\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "%d argüman sayısı olarak %s için geçersiz"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: üçüncü argüman bir gawk uzantısı"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr "%s: yerine kullanılan son argüman olarak dizge sabiti etkisiz"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "üçüncü %s parametresi değiştirilebilir bir nesne değil"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: ikinci argüman bir gawk uzantısı"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dcgettext(_\"...\") kullanımı yanlış: altçizgiyi kaldırın"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dcngettext(_\"...\") kullanımı yanlış: altçizgiyi kaldırın"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "`%s' işlevi: %d. parametre, `%s', %d. parametrenin tekrarı"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "`%s' işlevi: parametre, `%s'global değişkeni gölgeliyor"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "`%s' yazmak için açılamadı (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "profil standart hataya gönderiliyor"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: kapatma başarısız (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() iki kere çağrıldı!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "gölgeli değişkenler vardı."
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "işlev `%s': işlev ismi parametre ismi olarak kullanılamaz"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "işlev ismi `%s' önceden atanmış"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "`%s' işlevi çağrıldı ama hiç atanmamış"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "`%s' işlevi atanmış ama hiç çağrılmadı"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "%d numaralı argüman bir düzenli ifade sabiti"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"`%s' işlevi `(' ile isim arasında boşlukla çağrılmış,\n"
+"ya da bir değişken veya bir dizi olarak kullanılmış"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s \"%s\"ya yazılamadı (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "standart çıktı"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "sebebi bilinmiyor"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: sayısal olmayan argüman alındı"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: %g kapsamdışı"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kanala yazılamadı: veriyolu `%s' okumak için açıldı, yazmak için "
+"değil"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: kanala yazılamadı: dosya `%s' okumak için açıldı, yazmak için değil"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr "fflush: `%s' bir açık dosya, veriyolu ya da bir yan işlem değil"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: ilk argüman dizge olmayan türde alındı"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: ikinci argüman dizge olmayan türde alındı"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: sayısal olmayan argüman alındı"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "`delete array' bir gawk uzantısıdır"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: dizge olmayan argüman alındı"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: sayısal olmayan argüman alındı"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: negatif argüman %g alındı"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr "tüm biçemlerde ya `count$' kullanmalısınız ya da hiçbir şey"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "`$' awk biçemlerde kullanılmaz"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "`$' ile birlikte verilen argüman sayısı > 0 olmalıdır"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "argüman sayısı %ld sağlanmış toplam argüman sayısından büyük"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "`$' biçem içinde noktadan sonra kullanılmaz"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr "konumsal alan genişliği ya da duyarlığı için `$' kullanılmamış"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' awk biçemlerde anlamsız; yoksayıldı"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "`l' POSIX awk biçemlerde kullanılmaz"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' awk biçemlerde anlamsız; yoksayıldı"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "`L' POSIX awk biçemlerde kullanılmaz"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' awk biçemlerde anlamsız; yoksayıldı"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "`h' POSIX awk biçemlerde kullanılmaz"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: %g değeri `%%%c' biçimi için kapsamdışı"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "biçem dizgesini oluşturacak yeterli argüman yok"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "bir bunun için ^ tükendi"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: biçem belirteci denetim karakteri içermiyor"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "biçem dizgesi için çok fazla argüman sağlanmış"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: argüman yok"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: sayısal olmayan argüman alındı"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: negatif argüman %g ile çağrıldı"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: başlangıç indeksi olarak %g geçersiz, 1 kullanılıyor"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr ""
+"substr: tamsayı olmayan başlangıç indeksi %g den ondalık kısım çıkarılacak"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: uzunluk %g >= 1 değil"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: uzunluk %g => 0 değil"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: tamsayı olmayan uzunluk %g den ondalık kısım çıkarılacak"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+"substr: dizge indislemesi için uzunluk olarak %g çok fazla, %g den sonrası "
+"gözardı ediliyor"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: kaynak dizge sıfır uzunlukta"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: başlangıç indisi %g dizgenin sonundan sonra"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: uzunluk %g, %g başlangıç indisinde ilk argümanın uzunluğunu (%lu) "
+"aşar"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: ilk argüman dizge olmayan türde alındı"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: boş biçem dizgesi alındı"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: ikinci argüman sayısal olmayan türde alındı"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: dizge olmayan argüman alındı"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: dizge olmayan argüman alındı"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "ilklendirilmemiş `$%d' alanına başvuru"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: dizge olmayan argüman alındı"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: dizge olmayan argüman alındı"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: ikinci argüman sayısal olmayan türde alındı"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: sayısal olmayan argüman alındı"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: sayısal olmayan argüman alındı"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: sayısal olmayan argüman alındı"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: üçüncü argüman bir dizi değil"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: 0 olan 3. argüman 1 kabul edildi"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: ikinci argüman sayısal değil"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): çok büyük kaydırma değeri tuhaf sonuçlar verecek"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: ikinci argüman sayısal değil"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): çok büyük kaydırma değeri tuhaf sonuçlar verecek"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: ikinci argüman sayısal değil"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: ikinci argüman sayısal değil"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: ilk argüman sayısal olmayan türde alındı"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: ikinci argüman sayısal değil"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: sayısal olmayan argüman alındı"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): negatif değerler tuhaf sonuçlar verecek"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): tamsayı kısım kalacak şekilde kalanı atılacak"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' geçerli bir yerel kategori değil"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "%d. düğümtürü bilinmiyor"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "genflags2str içinde tampon taştı"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "`%s' dizisi bir sayısal bağlamda kullanılmaya çalışılıyor"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for loop: `%s' dizisinin boyu döngünün yorumlanması sırasında %ld iken %ld "
+"oldu"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "döngü dışında `break' kullanımı taşınabilir değil"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "döngü dışında `break' kullanımı yasak"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "döngü dışında `continue' kullanımı taşınabilir değil"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "döngü dışında `continue' kullanımı yasak"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "`next' bir BEGIN kuralından çağrılamaz"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "`next' bir END kuralından çağrılamaz"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr "`nextfile' bir BEGIN kuralından çağrılamaz"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr "`nextfile' bir END kuralından çağrılamaz"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "deyim etkisiz"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "`%s' işlev ismi bir değişken ya da dizi olarak kullanılamaz"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "başlangıç değeri olmayan `%s' argümanına başvuru"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "öndeğer ataması yapılmamış `%s' değişkenine başvuru"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"bitiştirme: bir ifadenin yan etkileri diğerinin uzunluğunu değiştirmiş!"
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "koşul bağlamında atama yapılmış"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "sıfırla bölme hatası"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "`%%'de sıfırla bölme hatası"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "tree_eval içinde kuraldışı tür (%s)"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "`/='de sıfırla bölme hatası"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "`%%='de sıfırla bölme hatası"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "`%s' işlevi bildirilenden daha fazla argümanla çağrıldı"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "`%s' işlevi tanımsız"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# İşlev Çağrı Yığını:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr "\t# -- main --\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "sayısal olmayan değerden alan başvurusu"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "null dizgeden alan başvurusu"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "%d. alana erişilmeye çalışılıyor"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "değişken ismine yerleşik işlevin sonucu atanamaz"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "`IGNORECASE' bir gawk uzantısıdır"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "`BINMODE' bir gawk uzantısıdır"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "`%sFMT' özelliği `%s' hatalı"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "`LINT' atamasından dolayı `--lint' kapatılıyor"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "`extension' bir gawk uzantısıdır"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: `%s' açılamıyor (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr "extension: kitaplık `%s': `%s' işlevi çağrılamıyor (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: işlev ismi eksik"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr "extension: `%2$s' işlevindeki `%1$c' karakteri kuraldışı"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: `%s' işlevi yeniden tanımlanamaz"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: `%s' işlevi zaten tanımlı"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr "extension: bir gawk yerleşiği olan `%s' işlev ismi olamaz"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: işlev ismi `%s' evvelce tanımlanmış"
+
+#: ext.c:201
+#, fuzzy, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "`%s' işlevi en çok `%d' argüman alabilecek şekilde tanımlı"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "`%s' işlevi: %d. argüman eksik"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr ""
+"`%s' işlevi: %d. argüman: tek değerli değişken bir dizi olarak kullanılmaya "
+"çalışılıyor"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+"`%s' işlevi: %d. argüman: dizi tek değerli bir değişken olarak kullanılmaya "
+"çalışılıyor"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "İşlem Desteklenmiyor"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "NF negatif değere ayarlı"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: ikinci argüman bir dizi değil"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr "split: üçüncü argüman olan null dizge bir gawk uzantısı"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "`FIELDWIDTHS' bir gawk uzantısıdır"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "`FS' için null dizge bir gawk uzantısıdır"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: `%s' seçeneği belirsiz\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: `--%s' seçeneği argümansız kullanılır\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: seçenek `%c%s' argümansız kullanılır\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: `%s' seçeneği bir argümanla kullanılır\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: `--%s' seçeneği bilinmiyor\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: `%c%s' seçeneği bilinmiyor\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: kuraldışı seçenek -- %c\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: geçersiz seçenek -- %c\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: seçenek bir argümanla kullanılır -- %c\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: `-W %s' seçeneği belirsiz\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: `-W %s' seçeneği argümansız kullanılır\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "`%s' okumak için açılamıyor (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "dosya tanımlayıcı %d (`%s') başarısız (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "redirect() içindeki ağaç türü %s geçersiz"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "`%s' yönlendirmesi içindeki ifade sadece sayısal değer içeriyor"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "`%s' yönlendirmesi içindeki ifade null dizge değeri içeriyor"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"`%s' dosya ismi (`%s' yönlendirmesi için) mantıksal ifadenin sonucu olabilir"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "`%.*s' dosyası için `>' ve `>>' karışımı gereksiz"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "`%s' veriyolu çıktı için açılamadı (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "`%s' veriyolu girdi için açılamadı (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "iki yönlü `%s' soketi G/Ç için açılamıyor (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "iki yönlü `%s' veriyolu G/Ç için açılamıyor (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "`%s'den yönlendirilemiyor (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "`%s'e yönlendirilemiyor (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"açık dosyalar için sistem sınırı aşıldı: çoğul dosya tanımlayıcılara "
+"başlarken"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "`%s' kapatılamadı (%s)."
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "çok fazla veriyolu ya da dosya açık"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: ikinci argüman `to' ya da `from' olmalı"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr "close: `%.*s' bir açık dosya, veriyolu ya da alt-işlem değil"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "hiç açılmamış bir yönlendirmenin kapatılması"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: `%s' yönlendirmesi bir `|&' ile açılmamış, ikinci argüman yoksayıldı"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "başarısızlık durumu (%d): `%s' veriyolunun kapatılması (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "başarısızlık durumu (%d): `%s' dosyasının kapatılması (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "`%s' soketinin açıkça kapatılması istenmedi"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "`%s' alt-işleminin açıkça kapatılması istenmedi"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "`%s' veriyolunun açıkça kapatılması istenmedi"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "`%s' dosyasının açıkça kapatılması istenmedi"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "standart çıktıya yazarken hata (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "standart hataya yazarken hata (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "`%s'in veriyolu ile veri aktarımı başarısız (%s)."
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "`%s'e veriyolunun alt-işlemi ile veri aktarımı başarısız (%s)."
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "`%s'in dosya ile veri aktarımı başarısız (%s)."
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "/inet/raw istemci henüz hazır değil"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "`/inet/raw' sadece root tarafından kullanılabilir"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "/inet/raw sunucu henüz hazır değil"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "özel dosya ismi `%s' içinde (bilinen) bir protokol sağlanmamış"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "özel dosya ismi `%s' tamamlanmamış"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "`%s' deki yerel port geçersiz"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "`/inet' e bir karşı makina ismi sağlanmalı"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "`/inet' e bir karşı port sağlanmalı"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "`%s' de karşı port geçersiz"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "TCP/IP haberleşmesi desteklenmiyor"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "`%s' dosya değil dizin"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "`PROCINFO[\"%s\"]' kullanın (`%s' yerine)"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "`/dev/user' yerine `PROCINFO[...]' kullanın"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "`%s', `%s' kipinde açılamadı"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "ana pty kapatılamadı (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "ast süreçte stdÇ kapatılamadı (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr "ast süreçte yardımcı pty standart çıktıya taşınamadı (dup: %s)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "ast süreçte stdG kapatılamadı (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr "ast süreçte yardımcı pty standart girdiye taşınamadı (dup: %s)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "yardımcı pty kapatılamadı (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr "ast süreçte veriyolu standart çıktıya taşınamadı (dup: %s)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr "ast süreçte veriyolu standart girdiye taşınamadı (dup: %s)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "üst süreçte stdÇ eski durumuna getirilemedi\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "üst süreçte stdG eski durumuna getirilemedi\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "veriyolu kapatılamadı (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "`|&' desteklenmiyor"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "`%s' veriyolu açılamıyor (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "`%s' için ast süreç oluşturulamıyor (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "veri dosyası `%s' boş"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "daha fazla girdi belleği ayrılamadı"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "`%s' girdi dosyası okunurken hata: %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "`RS' çoklu karakter değeri bir gawk uzantısıdır"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "`-m[fr]' seçeneği gawk'da böyle kullanılmaz"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "-m seçeneğinin kullanımı: `-m[fr] nnn'"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: `-W %s' seçeneği tanımlı değil, yok sayıldı\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "`--source' seçeneği için boş argüman yoksayıldı"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr "ortam değişkeni `POSIXLY_CORRECT' var: `--posix' kullanılıyor"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "`--posix' seçeneği `--traditional' seçeneğini etkisiz kılar"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr ""
+"`--posix'/`--traditional' seçenekleri `--non-decimal-data' seçeneğini "
+"etkisiz kılar"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "%s root yetkileriyle çalıştırıldığında güvenlik sorunları olabilir"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "standart girdi ikilik kipe ayarlanamaz (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "standart çıktı ikilik kipe ayarlanamaz (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "standart hata ikilik kipe ayarlanamaz (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "program metni hiç yok!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Kullanımı: %s [POSIX veya GNU tarzı seçenekler] -f progdosyası [--] "
+"dosya ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Kullanımı: %s [POSIX veya GNU tarzı seçenekler] %cprogram%c dosya ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "POSIX seçenekleri: GNU uzun seçenekleri:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr " -f progDosyası --file=progDosyası\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr " -F ayraç --field-separator=ayraç\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr " -v var=değer --assign=var=değer\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr " -m[fr] değer\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr " -W compat --compat\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr " -W copyleft --copyleft\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr " -W copyright --copyright\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr " -W dump-variables[=dosya] --dump-variables[=dosya]\n"
+
+#: main.c:681
+#, fuzzy
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr " -W profile[=dosya] --profile[=dosya]\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr " -W gen-po --gen-po\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr " -W help --help\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr " -W lint[=ölümcül] --lint[=ölümcül]\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr " -W lint-old --lint-old\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr " -W non-decimal-data --non-decimal-data\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr " -W nostalgia --nostalgia\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr " -W parsedebug --parsedebug\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr " -W profile[=dosya] --profile[=dosya]\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr " -W posix --posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr " -W re-interval --re-interval\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr " -W source=program-metni --source=program-metni\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr " -W traditional --traditional\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr " -W usage --usage\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr " -W version --version\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Hataları raporlarken, `gawk.info' içindeki `Reporting Problems and Bugs'\n"
+"kısmının `Bugs' başlıklı bölümünden gerekli bilgileri alabilirsiniz.\n"
+"\n"
+"Çeviri hatalarını <gnu-tr-u12a@lists.sourceforge.net> adresine bildiriniz.\n"
+"\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk bir dizge kalıplarını tarama ve işleme dilidir.\n"
+"Öntanımlı olarak standart girdiyi okur ve standart çıktıya yazar.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Örnekler:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' dosya\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Telif hakkı (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"Bu program bir serbest yazılımdır. Bu yazılımı Free Software Foundation\n"
+"tarafından yayınlanmış olan GNU Genel Kamu Lisansının 2. ya da daha sonraki\n"
+"bir sürümünün koşulları altında kopyalayabilir, dağıtabilir ve/veya\n"
+"üzerinde değişiklik yapabilirsiniz.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Bu program kullanışlı olabileceği umularak dağıtılmaktadır. Ancak,\n"
+"hiçbir GARANTİSİ YOKTUR; hatta SATILABİLİRLİĞİ veya HERHANGİ BİR\n"
+"AMACA UYGUNLUĞU için bile garanti verilmez. Daha ayrıntılı bilgi\n"
+"edinmek için GNU Genel Kamu Lisansına bakınız.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"GNU Genel Kamu Lisansının bir kopyasını bu programla birlikte almış\n"
+"olacaksınız; yoksa Free Software Foundation, Inc., 51 Franklin Street\n"
+"Fifth Floor, Boston, MA 02110-1301, USA. adresinden isteyebilirsiniz.\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "POSIX awk -Ft ile dosya sistemini belirlemez"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: `-v' ile verilen `%s' argümanı `var=değer' biçiminde değil\n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "`%s' kurala uygun bir değişken ismi değil"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%2$s=%3$s' için dosyaya bakınca, `%1$s' bir değişken ismi değil"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "Gerçel sayı istisnası"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "ölümcül iç hata"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "ön açılışlı bir %d dosya tanımlayıcısı yok"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "%d dosya tanımlayıcısı için /dev/null ön açılışı yapılamadı"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "gruplar bulunamadı: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "komut satırı:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "uyarı: "
+
+#: msg.c:142
+msgid "error: "
+msgstr "hata: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "ölümcül: "
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "dizge gerçel sayıya dönüştürülemiyor"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "dizge sonunda tersbölü"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX `\\x' öncelemelerine izin vermez"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "`\\x' önceleme dizgesinde onaltılık rakamlar yok"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "`\\%c' önceleme dizgesi `%c' olarak kullanıldı"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': close-on-exec belirlenemedi: (fcntl: %s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "`%s' yazmak için açılamadı: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "iç hata: null vname'li %s"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# dahili olarak `delete' varsayıldı"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# bu özdevimli olarak yüklenmiş bir ek işlevdir"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# gawk profili, oluşturuldu: %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# BEGIN blokları\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Kurallar\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# END blokları\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# İşlevler, alfabetik sırayla\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "prec_level'da anlaşılamayan tür %s"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Başarılı"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Eşleşmez"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Düzenli ifade geçersiz"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Karşılaştırma karakteri geçersiz"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Karakter sınıf ismi geçersiz"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "İzleyen tersbölü"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Geriye başvuru geçersiz"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "[ ya da [^ eşleşmiyor"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "( ya da \\( eşleşmiyor"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "\\{ eşleşmiyor"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "\\{\\} içeriği geçersiz"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Kapsam sonu geçersiz"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Bellek tükendi"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "düzenli ifade önceliği geçersiz"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Düzenli ifade sonu eksik kalmış"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Düzenli ifade çok büyük"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr ") ya da \\) eşleşmiyor"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Daha önce düzenli ifade yok"
+
+#~ msgid "function %s called\n"
+#~ msgstr "%s işlevi çağrıldı\n"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "FIELDWIDTHS içindeki %d. alan > 0 olmalı"
+
+#~ msgid "or used as a variable or an array"
+#~ msgstr "ya da bir değişken ya da dizi olarak kullanılmış"
+
+#~ msgid "substr: length %g is < 0"
+#~ msgstr "substr: uzunluk %g < 0"
+
+#~ msgid "regex match failed, not enough memory to match string \"%.*s%s\""
+#~ msgstr ""
+#~ "düzenli ifade eşleşmesi sağlanamadı, \"%.*s%s\" dizgesini eşleştirmek "
+#~ "için yeterli bellek yok"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: `%s' değişkeninin dizi olarak kullanımı kuraldışı"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: ilk argüman bir dizi değil"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: ikinci argüman bir dizi değil"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "iç hata: null vname'li node_var_array"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "değişken ismi `%s' de sözdizimi hatası"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "ya da diğer ifadenin içeriğinde kullanılmış"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "`%s' bir işlevdir, bir değişken ismi olarak kullanılamaz"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "BEGIN blokları bir eylem bölümü içermeli"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr "`nextfile' BEGIN ya da END eyleminde kullanılmış"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "BEGIN ya da END eyleminin içinde yönlendirme yapmayan `getline' tanımsız"
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "işlev imleyicisi %x işlev isim listesinde bulunamadı\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "üçüncü gsub parametresi değiştirilebilir bir nesne değil"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "Dengesiz ["
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "Tamamlanmamış \\ escape"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "Tamamlanmamış tekrar sayısı"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "Tekrar sayısı hatalı"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "Dengesiz ("
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Düzenli ifade sözdizimi bitleri belirtilmemiş"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "Karşılıksız )"
+
+#~ msgid "out of memory"
+#~ msgstr "bellek yetersiz"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "iç hata: dosya `%s', satır %d\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Yazılım hatalarını bildirmek için `gawk.info' içindeki `Bugs' "
+#~ "bölümündeki\n"
--- /dev/null
+# Vietnamese translation for gawk.
+# Copyright © 2005 Free Software Foundation, Inc.
+# Clytie Siddall <clytie@riverland.net.au>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 3.1.4l\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2005-07-06 17:20+0300\n"
+"PO-Revision-Date: 2005-06-28 14:46+0930\n"
+"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
+"Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: array.c:112
+#, c-format
+msgid "attempt to use function `%s' as an array"
+msgstr "cố dùng chức năng «%s» là một mảng"
+
+#: array.c:115
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "cố dùng tham số vô hướng «%s» là một mảng"
+
+#: array.c:118
+#, c-format
+msgid "attempt to use scalar `%s' as array"
+msgstr "cố dùng điều cô hướng «%s» là mảng"
+
+#: array.c:156
+#, c-format
+msgid "from %s"
+msgstr "từ %s"
+
+#: array.c:511
+#, c-format
+msgid "reference to uninitialized element `%s[\"%s\"]'"
+msgstr "tham chiếu đến phần tử chưa khởi động «%s[\"%s\"]»"
+
+#: array.c:517
+#, c-format
+msgid "subscript of array `%s' is null string"
+msgstr "chữ in dưới mảng «%s» là chuỗi rỗng"
+
+#: array.c:621
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "delete: (xóa bỏ) số chỉ mục «%s» không phải trong mảng «%s»"
+
+#: array.c:791
+#, c-format
+msgid "%s: empty (null)\n"
+msgstr "%s: rỗng (vô giá trị)\n"
+
+#: array.c:796
+#, c-format
+msgid "%s: empty (zero)\n"
+msgstr "%s: rỗng (số không)\n"
+
+#: array.c:800
+#, c-format
+msgid "%s: table_size = %d, array_size = %d\n"
+msgstr "%s: cỡ_bảng = %d, cỡ_mảng = %d\n"
+
+#: array.c:829
+#, c-format
+msgid "%s: is parameter\n"
+msgstr "%s: là tham số\n"
+
+#: array.c:834
+#, c-format
+msgid "%s: array_ref to %s\n"
+msgstr "%s: «array_ref» (mảng tham chiếu) đến «%s»\n"
+
+#: awkgram.y:208
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr "Mọi khối «%s» phải có một phần là hành động"
+
+#: awkgram.y:211
+msgid "each rule must have a pattern or an action part"
+msgstr "Mọi quy tắc phải có một mẫu hoặc một phần là hành động"
+
+#: awkgram.y:267
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr "«%s» là một chức năng có sẵn nên không thể định nghĩa lái nó."
+
+#: awkgram.y:313
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+"hằng biểu thức chính quy «//» hình như một chú thích C, nhưng mà không phải"
+
+#: awkgram.y:316
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+"hằng biểu thức chính quy «/%s/» hình như một chú thích C, nhưng mà không phải"
+
+#: awkgram.y:343 awkgram.y:623
+msgid "statement may have no effect"
+msgstr "có lẽ câu sẽ không có tác dụng"
+
+#: awkgram.y:440 awkgram.y:460
+#, c-format
+msgid "`%s' used in %s action"
+msgstr "«%s» được dùng trong hành động «%s»"
+
+#: awkgram.y:453 awkgram.y:456
+msgid "`nextfile' is a gawk extension"
+msgstr "«nextfile» (tập tin kế tiếp) là một phần mở rộng gawk"
+
+#: awkgram.y:470
+msgid "`return' used outside function context"
+msgstr "đã dùng «return» (trở về) ở ngoại ngữ cảnh chức năng"
+
+#: awkgram.y:512
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+"«print» (in) giản dị trong quy tắc «BEGIN» (bắt đầu) hay «END» (kết thức) "
+"thì rất có thể nên là «print\"\"»"
+
+#: awkgram.y:525 awkgram.y:532
+msgid "`delete array' is a gawk extension"
+msgstr "«delete array» (xóa bỏ mảng) là một phần mở rộng gawk"
+
+#: awkgram.y:540 awkgram.y:547
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr "«delete array» (xóa bỏ mảng) là một phần mở rộng tawk không thể mang"
+
+#: awkgram.y:591
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr "giá trị trường hợp trùng trong nội dung câu chuyển đổi nhánh: %s"
+
+#: awkgram.y:601
+msgid "Duplicate `default' detected in switch body"
+msgstr "Đã phát hiện «mặc định» trùng trong nội dung câu chuyển đổi nhánh"
+
+#: awkgram.y:690
+msgid "multistage two-way pipelines don't work"
+msgstr "đường ống dẫn hai chiếu đa giai đoạn không hoạt động được"
+
+#: awkgram.y:781
+msgid "regular expression on right of assignment"
+msgstr "biểu thức chính quy bên phải điều gán"
+
+#: awkgram.y:804
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr "biểu thức chính quy bên trái toán tử «~» hay «!~»"
+
+#: awkgram.y:812
+msgid "regular expression on right of comparison"
+msgstr "biểu thức chính quy bên phải so sánh"
+
+#: awkgram.y:879
+msgid "non-redirected `getline' undefined inside END action"
+msgstr ""
+"trong hành động «END» (kết thức) có «getline» (lấy dòng) không được chuyển "
+"hướng và chưa được định nghĩa."
+
+#: awkgram.y:906
+msgid "call of `length' without parentheses is not portable"
+msgstr "không thể mang lời gọi «length» (độ dài) không có ngoặc"
+
+#: awkgram.y:909
+msgid "call of `length' without parentheses is deprecated by POSIX"
+msgstr "POSIX phản đối lời gọi «length» (độ dài) không có ngoặc"
+
+#: awkgram.y:962
+msgid "use of non-array as array"
+msgstr "đã dùng điều là mảng mà không phải là mảng"
+
+#: awkgram.y:964
+msgid "invalid subscript expression"
+msgstr "biểu thức in thấp không hợp lệ"
+
+#: awkgram.y:1171
+msgid "unexpected newline or end of string"
+msgstr "dòng mới hay kết thức chuỗi bất ngờ"
+
+#: awkgram.y:1267
+msgid "empty program text on command line"
+msgstr "chữ chương trình rỗng trên dòng lệnh"
+
+#: awkgram.y:1320
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr "không mở được tập tin nguồn «%s» để đọc (%s)"
+
+#: awkgram.y:1397
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr "không đọc được tập tin nguồn «%s» (%s)"
+
+#: awkgram.y:1405
+#, c-format
+msgid "source file `%s' is empty"
+msgstr "tập tin nguồn «%s» là rỗng"
+
+#: awkgram.y:1596 awkgram.y:1718 awkgram.y:1736 awkgram.y:2107 awkgram.y:2194
+msgid "source file does not end in newline"
+msgstr "tập tin nguồn không kết thức với dòng mới"
+
+#: awkgram.y:1658
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+"biểu thức chính quy chưa chấm dứt thì kết thức với «\\» tại kết thức tập tin"
+
+#: awkgram.y:1682
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"%s: %d: điều sửa đổi biểu thức chính quy tawk «/.../%c» không hoạt động "
+"trong trình gawk"
+
+#: awkgram.y:1686
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+"điều sửa đổi biểu thức chính quy tawk «/.../%c» không hoạt động trong trình "
+"gawk"
+
+#: awkgram.y:1693
+msgid "unterminated regexp"
+msgstr "biểu thức chính quy chưa chấm dứt "
+
+#: awkgram.y:1696
+msgid "unterminated regexp at end of file"
+msgstr "biểu thức chính quy chưa chấm dứt tại kết thức tập tin"
+
+#: awkgram.y:1762
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr "không thể mang khi sử dụng «\\#...» để tiếp tục dòng"
+
+#: awkgram.y:1774
+msgid "backslash not last character on line"
+msgstr "xuyệc ngược không phải là ký tự cuối cùng trên dòng"
+
+#: awkgram.y:1819
+msgid "POSIX does not allow operator `**='"
+msgstr "POSIX không cho phép toán tử «**=»"
+
+#: awkgram.y:1821
+msgid "old awk does not support operator `**='"
+msgstr "awk cũ không hỗ trợ toán tử «**=»"
+
+#: awkgram.y:1830
+msgid "POSIX does not allow operator `**'"
+msgstr "POSIX không cho phép toán tử «**»"
+
+#: awkgram.y:1832
+msgid "old awk does not support operator `**'"
+msgstr "awk cũ không hỗ trợ toán tử «**»"
+
+#: awkgram.y:1863
+msgid "operator `^=' is not supported in old awk"
+msgstr "awk cũ không hỗ trợ toán tử «^=»"
+
+#: awkgram.y:1871
+msgid "operator `^' is not supported in old awk"
+msgstr "awk cũ không hỗ trợ toán tử «^»"
+
+#: awkgram.y:1955 awkgram.y:1970
+msgid "unterminated string"
+msgstr "chuỗi không được chấm dứt"
+
+#: awkgram.y:2155
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr "có một ký tự không hợp lệ «%c» trong biểu thức"
+
+#: awkgram.y:2203
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr "«%s» là một phần mở rộng gawk"
+
+#: awkgram.y:2206
+#, c-format
+msgid "`%s' is a Bell Labs extension"
+msgstr "«%s» là một phần mở rộng Bell Labs (Phòng thí nghiệm Bell)"
+
+#: awkgram.y:2209
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr "POSIX không cho phép «%s»"
+
+#: awkgram.y:2213
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr "awk cũ không hỗ trợ «%s»"
+
+#: awkgram.y:2239
+msgid "`goto' considered harmful!\n"
+msgstr "đã thấy là «goto» gây tai hại\n"
+
+#: awkgram.y:2301
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr "«%d» không hợp lệ là số đối số cho «%s»"
+
+#: awkgram.y:2320 awkgram.y:2323
+msgid "match: third argument is a gawk extension"
+msgstr "match: (khớp) đối số thứ ba là phần mở rộng gawk"
+
+#: awkgram.y:2336
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+"%s: khi đối số cuối cùng của thay thế, hằng mã nguồn chuỗi không có tác dụng"
+
+#: awkgram.y:2339
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr "tham số thứ ba «%s» không phải là một đối tượng có thể thay đổi"
+
+#: awkgram.y:2366 awkgram.y:2369
+msgid "close: second argument is a gawk extension"
+msgstr "close: (đóng) đối số thứ hai là phần mở rộng gawk"
+
+#: awkgram.y:2379
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dùng «dcgettext(_\"...\")» không đúng: hãy loại bỏ gạch dưới đi trước"
+
+#: awkgram.y:2394
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr "dùng «dcgettext(_\"...\")» không đúng: hãy loại bỏ gạch dưới đi trước"
+
+#: awkgram.y:2465
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "chức năng «%s»: tham số «#%d», «%s», nhân đôi tham số «#%d»"
+
+#: awkgram.y:2498
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr "chức năng «%s»: tham số «%s» che biến toàn cục"
+
+#: awkgram.y:2610
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr "không mở được «%s» để ghi (%s)"
+
+#: awkgram.y:2611 profile.c:93
+msgid "sending profile to standard error"
+msgstr "đang gởi tiểu sở sơ lược cho thiết bị lỗi chuẩn"
+
+#: awkgram.y:2643
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr "%s: đóng thất bại (%s)"
+
+#: awkgram.y:2764
+msgid "shadow_funcs() called twice!"
+msgstr "shadow_funcs() (chức năng bóng) được gọi hai lần!"
+
+#: awkgram.y:2791
+msgid "there were shadowed variables."
+msgstr "đã có một số biến bị che"
+
+#: awkgram.y:2864
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr "chức năng «%s»: không dùng được tên chức năng là tên tham số"
+
+#: awkgram.y:2874
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "tên chức năng «%s» được định nghĩa trước"
+
+#: awkgram.y:3025 awkgram.y:3031
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr "chức năng «%s» được gọi nhưng mà chưa định nghĩa"
+
+#: awkgram.y:3034
+#, c-format
+msgid "function `%s' defined but never called"
+msgstr "chức năng «%s» được định nghĩa nhưng mà chưa gọi"
+
+#: awkgram.y:3061
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr "hằng biểu thức chính quy cho tham số «#%d» làm giá trị luận lý"
+
+#: awkgram.y:3105
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+"chức năng «%s» được gọi khi có dấu cách giữa tên và «(»\n"
+"hoặc được dùng là một biến hay là một mảng"
+
+#: builtin.c:145
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr "%s đến «%s» thất bại (%s)"
+
+#: builtin.c:146
+msgid "standard output"
+msgstr "thiết bị xuất chuẩn"
+
+#: builtin.c:147
+msgid "reason unknown"
+msgstr "không biết sao"
+
+#: builtin.c:160
+msgid "exp: received non-numeric argument"
+msgstr "exp: đã nhận đối số không phải thuộc số"
+
+#: builtin.c:166
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr "exp: đối số «%g» ở ngoại phạm vị"
+
+#: builtin.c:224
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+"fflush: không thể xóa sạch: ống dẫn «%s» được mở để đọc, không phải để ghi"
+
+#: builtin.c:227
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+"fflush: không thể xóa sạch: tập tin «%s» được mở để đọc, không phải để ghi"
+
+#: builtin.c:239
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr ""
+"fflush: «%s» không phải là một tập tin đã mở, một ống dẫn hay một đồng tiến "
+"trình"
+
+#: builtin.c:332
+msgid "index: received non-string first argument"
+msgstr "index: (số chỉ mục) đã nhận đối số đầu không phải là chuỗi"
+
+#: builtin.c:334
+msgid "index: received non-string second argument"
+msgstr "index: (số chỉ mục) đã nhận đối số thứ hai không phải là chuỗi"
+
+#: builtin.c:449
+msgid "int: received non-numeric argument"
+msgstr "int: (số nguyên) đã nhận đối số không phải thuộc số"
+
+#: builtin.c:472
+#, fuzzy
+msgid "`length(array)' is a gawk extension"
+msgstr "«delete array» (xóa bỏ mảng) là một phần mở rộng gawk"
+
+#: builtin.c:481
+msgid "length: received non-string argument"
+msgstr "length: (độ dài) đã nhận đối số không phải chuỗi"
+
+#: builtin.c:506
+msgid "log: received non-numeric argument"
+msgstr "log: (bản ghi) đã nhận đối số không phải thuộc số"
+
+#: builtin.c:509
+#, c-format
+msgid "log: received negative argument %g"
+msgstr "log: (bản ghi) đã nhận đối số âm «%g»"
+
+#: builtin.c:673 builtin.c:676
+msgid "must use `count$' on all formats or none"
+msgstr ""
+"phải sử dụng «count$» hoặc với mọi định dạng hoặc không với định dạng nào"
+
+#: builtin.c:778
+msgid "`$' is not permitted in awk formats"
+msgstr "không cho phép «$» trong định dạng awk"
+
+#: builtin.c:784
+msgid "arg count with `$' must be > 0"
+msgstr "khi dùng «$» thì số đếm đối số phải là >0"
+
+#: builtin.c:786
+#, c-format
+msgid "arg count %ld greater than total number of supplied arguments"
+msgstr "số đếm đối số «%ld» lớn hơn tổng số đối số được cung cấp"
+
+#: builtin.c:788
+msgid "`$' not permitted after period in format"
+msgstr "không cho phép «$» sau dấu chấm trong định dạng"
+
+#: builtin.c:801
+msgid "no `$' supplied for positional field width or precision"
+msgstr ""
+"chưa cung cấp «$» cho độ rộng trường thuộc vị trí hoặc cho độ chính xác"
+
+#: builtin.c:867
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "chữ «l» không có nghĩa trong định dạng awk nên bị bỏ qua"
+
+#: builtin.c:871
+msgid "`l' is not permitted in POSIX awk formats"
+msgstr "không cho phép chữ «l» trong định dạng awk POSIX"
+
+#: builtin.c:882
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "chữ «L» không có nghĩa trong định dạng awk nên bị bỏ qua"
+
+#: builtin.c:886
+msgid "`L' is not permitted in POSIX awk formats"
+msgstr "không cho phép chữ «L» trong định dạng awk POSIX"
+
+#: builtin.c:897
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "chữ «h» không có nghĩa trong định dạng awk nên bị bỏ qua"
+
+#: builtin.c:901
+msgid "`h' is not permitted in POSIX awk formats"
+msgstr "không cho phép chữ «h» trong định dạng awk POSIX"
+
+#: builtin.c:1132
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: giá trị «%g» ở ngoại phạm vị cho định dạng «%%%c»"
+
+#: builtin.c:1198
+msgid "not enough arguments to satisfy format string"
+msgstr "chưa có đủ đối số để đáp ứng chuỗi định dạng"
+
+#: builtin.c:1200
+msgid "^ ran out for this one"
+msgstr "hết «^» cho điều này"
+
+#: builtin.c:1205
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: điều ghi rõ định dạng không có chữ điều khiển"
+
+#: builtin.c:1208
+msgid "too many arguments supplied for format string"
+msgstr "đã cung cấp quá nhiều đối số cho chuỗi định dạng"
+
+#: builtin.c:1274 builtin.c:1277
+msgid "printf: no arguments"
+msgstr "printf: không có đối số nào"
+
+#: builtin.c:1301
+msgid "sqrt: received non-numeric argument"
+msgstr "sqrt: (căn bậc hai) đã nhận đối số không phải thuộc số"
+
+#: builtin.c:1305
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr "sqrt: (căn bậc hai) đã gọi với đối số âm «%g»"
+
+#: builtin.c:1329
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr "substr: (chuỗi con) số chỉ mục đầu «%g» không hợp lệ nên dùng «1»"
+
+#: builtin.c:1334
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr "substr: (chuỗi con) sẽ cắt xén số chỉ mục không phải số nguyên «%g»"
+
+#: builtin.c:1353
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr "substr: (chuỗi con) độ dài «%g» không phải ≥1"
+
+#: builtin.c:1355
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr "substr: (chuỗi con) độ dài «%g» không phải ≥0"
+
+#: builtin.c:1362
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr "substr: (chuỗi con) sẽ cắt xén độ dài không phải số nguyên «%g»"
+
+#: builtin.c:1367
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+"substr: (chuỗi con) độ dài «%g» quá lớn cho chỉ mục chuỗi nên cắt xén xuống "
+"«%g»"
+
+#: builtin.c:1379
+msgid "substr: source string is zero length"
+msgstr "substr: (chuỗi con) chuỗi nguồn có độ dài số không"
+
+#: builtin.c:1395
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr "substr: (chuỗi con) chỉ mục đầu «%g» sau kết thức chuỗi"
+
+#: builtin.c:1403
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+"substr: (chuỗi con) độ dài «%g» tại chỉ mục đầu «%g» thì vượt quá độ dài của "
+"đối số đầu («%lu»)"
+
+#: builtin.c:1478
+msgid "strftime: received non-string first argument"
+msgstr "strftime: đã nhận đối số đầu không phải chuỗi"
+
+#: builtin.c:1484
+msgid "strftime: received empty format string"
+msgstr "strftime: đã nhận chuỗi định dạng rỗng"
+
+#: builtin.c:1493
+msgid "strftime: received non-numeric second argument"
+msgstr "strftime: đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:1556
+msgid "mktime: received non-string argument"
+msgstr "mktime: đã nhận đối số không phải chuỗi"
+
+#: builtin.c:1601
+msgid "system: received non-string argument"
+msgstr "system: (hệ thống) đã nhận đối số không phải chuỗi"
+
+#: builtin.c:1722 eval.c:2039
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr "tham chiếu đến trường chưa khởi động «$%d»"
+
+#: builtin.c:1827
+msgid "tolower: received non-string argument"
+msgstr "tolower: (đến thấp hơn) đã nhận đối số không phải chuỗi"
+
+#: builtin.c:1857
+msgid "toupper: received non-string argument"
+msgstr "toupper: (đến cao hơn) đã nhận đối số không phải chuỗi"
+
+#: builtin.c:1890
+msgid "atan2: received non-numeric first argument"
+msgstr "atan2: đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:1892
+msgid "atan2: received non-numeric second argument"
+msgstr "atan2: đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:1911
+msgid "sin: received non-numeric argument"
+msgstr "sin: đã nhận đối số không phải thuộc số"
+
+#: builtin.c:1927
+msgid "cos: received non-numeric argument"
+msgstr "cos: đã nhận đối số không phải thuộc số"
+
+#: builtin.c:1977
+msgid "srand: received non-numeric argument"
+msgstr "srand: đã nhận đối số không phải thuộc số"
+
+#: builtin.c:2012
+msgid "match: third argument is not an array"
+msgstr "match: (khớp) đối số thứ ba không phải là một mảng"
+
+#: builtin.c:2555
+msgid "gensub: third argument of 0 treated as 1"
+msgstr "gensub: (tạo điều con) đối số thứ ba là «0» thì được xử lý là «1»"
+
+#: builtin.c:2715
+msgid "lshift: received non-numeric first argument"
+msgstr "lshift: (dịch trái) đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:2717
+msgid "lshift: received non-numeric second argument"
+msgstr "lshift: (dịch trái) đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:2723
+#, c-format
+msgid "lshift(%lf, %lf): negative values will give strange results"
+msgstr "lshift(%lf, %lf): giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2725
+#, c-format
+msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:2727
+#, c-format
+msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgstr "lshift(%lf, %lf): giá trị dịch quá lớn thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2753
+msgid "rshift: received non-numeric first argument"
+msgstr "rshift: đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:2755
+msgid "rshift: received non-numeric second argument"
+msgstr "rshift: (dịch phải) đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:2761
+#, c-format
+msgid "rshift(%lf, %lf): negative values will give strange results"
+msgstr "rshift(%lf, %lf): giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2763
+#, c-format
+msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:2765
+#, c-format
+msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgstr "rshift(%lf, %lf): giá trị dịch quá lớn thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2791
+msgid "and: received non-numeric first argument"
+msgstr "and: (và) đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:2793
+msgid "and: received non-numeric second argument"
+msgstr "and: (và) đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:2799
+#, c-format
+msgid "and(%lf, %lf): negative values will give strange results"
+msgstr "and(%lf, %lf): (và) giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2801
+#, c-format
+msgid "and(%lf, %lf): fractional values will be truncated"
+msgstr "and(%lf, %lf): (và) giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:2827
+msgid "or: received non-numeric first argument"
+msgstr "or: (hoặc) đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:2829
+msgid "or: received non-numeric second argument"
+msgstr "or: (hoặc) đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:2835
+#, c-format
+msgid "or(%lf, %lf): negative values will give strange results"
+msgstr "or(%lf, %lf): (hoặc) giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2837
+#, c-format
+msgid "or(%lf, %lf): fractional values will be truncated"
+msgstr "or(%lf, %lf): (hoặc) giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:2863
+msgid "xor: received non-numeric first argument"
+msgstr "xor: (không hoặc) đã nhận đối số đầu không phải thuộc số"
+
+#: builtin.c:2865
+msgid "xor: received non-numeric second argument"
+msgstr "xor: (không hoặc) đã nhận đối số thứ hai không phải thuộc số"
+
+#: builtin.c:2871
+#, c-format
+msgid "xor(%lf, %lf): negative values will give strange results"
+msgstr "xor(%lf, %lf): (không hoặc) giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2873
+#, c-format
+msgid "xor(%lf, %lf): fractional values will be truncated"
+msgstr "xor(%lf, %lf): (không hoặc) giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:2897
+msgid "compl: received non-numeric argument"
+msgstr "compl: (biên dịch) đã nhận đối số không phải thuộc số"
+
+#: builtin.c:2903
+#, c-format
+msgid "compl(%lf): negative value will give strange results"
+msgstr "compl(%lf): (biên dịch) giá trị âm thì sẽ gây ra kết quả lạ"
+
+#: builtin.c:2905
+#, c-format
+msgid "compl(%lf): fractional value will be truncated"
+msgstr "compl(%lf): (biên dịch) giá trị thuộc phân số thì sẽ bị cắt xén"
+
+#: builtin.c:3078
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: «%s» không phải là một phân loại miền địa phương hợp lệ"
+
+#: eval.c:303
+#, c-format
+msgid "unknown nodetype %d"
+msgstr "không biết kiểu nút «%d»"
+
+#: eval.c:353
+msgid "buffer overflow in genflags2str"
+msgstr "vùng đệm vượt quá trong «genflags2str» (tạo ra cờ đến chuỗi)"
+
+#: eval.c:385 eval.c:391 profile.c:838
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "cố dùng mảng «%s» trong một ngữ cảnh vô hướng"
+
+#: eval.c:733
+#, c-format
+msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgstr ""
+"for loop: (cho vòng lặp) mảng «%s» đã thay đổi kích thước từ «%ld» đến «%ld» "
+"trong khi thực hiện vòng lặp"
+
+#: eval.c:754
+msgid "`break' outside a loop is not portable"
+msgstr "không thể mang «break» (ngắt) ở ngoại một vòng lặp"
+
+#: eval.c:758
+msgid "`break' outside a loop is not allowed"
+msgstr "không cho phép «break» (ngắt) ở ngoại một vòng lặp"
+
+#: eval.c:775
+msgid "`continue' outside a loop is not portable"
+msgstr "không thể mang «continue» (tiếp tục) ở ngoại một vòng lặp"
+
+#: eval.c:779
+msgid "`continue' outside a loop is not allowed"
+msgstr "không cho phép «continue» (tiếp tục) ở ngoại một vòng lặp"
+
+#: eval.c:813
+msgid "`next' cannot be called from a BEGIN rule"
+msgstr "không gọi được «next» (kế tiếp) từ một quy tắc «BEGIN» (bắt đầu)"
+
+#: eval.c:815
+msgid "`next' cannot be called from an END rule"
+msgstr "không gọi được «next» (kế tiếp) từ một quy tắc «END» kết thức)"
+
+#: eval.c:824
+msgid "`nextfile' cannot be called from a BEGIN rule"
+msgstr ""
+"không gọi được «nextfile» (tập tin kế tiếp) từ một quy tắc «BEGIN» (bắt đầu)"
+
+#: eval.c:826
+msgid "`nextfile' cannot be called from an END rule"
+msgstr ""
+"không gọi được «nextfile» (tập tin kế tiếp) từ một quy tắc «END» kết thức)"
+
+#: eval.c:875
+msgid "statement has no effect"
+msgstr "câu không có tác dụng"
+
+#: eval.c:952 eval.c:1893
+#, c-format
+msgid "can't use function name `%s' as variable or array"
+msgstr "không thể dùng tên chức năng «%s» với là biến hay mảng"
+
+#: eval.c:959 eval.c:965
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr "tham chiếu đến đối số chưa khởi động «%s»"
+
+#: eval.c:974 eval.c:1902
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "tham chiếu đến biến chưa khởi động «%s»"
+
+#: eval.c:1120
+msgid ""
+"concatenation: side effects in one expression have changed the length of "
+"another!"
+msgstr ""
+"concatenation: (nối chuỗi) hiệu ứng khác trong một biểu thức nào đó đã thay "
+"đổi độ dài của một biểu thức khác."
+
+#: eval.c:1200
+msgid "assignment used in conditional context"
+msgstr "đã dùng điều gán trong ngữ cảnh chỉ điều kiện"
+
+#: eval.c:1278
+msgid "division by zero attempted"
+msgstr "cố chia cho số không"
+
+#: eval.c:1293
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr "cố chia cho số không trong «%%»"
+
+#: eval.c:1308 profile.c:714
+#, c-format
+msgid "illegal type (%s) in tree_eval"
+msgstr "không cho phép kiểu (%s) trong «tree_eval» (ước lượng cây)"
+
+#: eval.c:1471
+msgid "division by zero attempted in `/='"
+msgstr "cố chia cho số không trong «/=»"
+
+#: eval.c:1493
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr "cố chia cho số không trong «%%=»"
+
+#: eval.c:1758
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr "đã gọi chức năng «%s» với nhiều đối số hơn được tuyên bố"
+
+#: eval.c:1802
+#, c-format
+msgid "function `%s' not defined"
+msgstr "chưa định nghĩa chức năng «%s»"
+
+#: eval.c:1865
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+"\n"
+"\t# Đống gọi chức năng:\n"
+"\n"
+
+#: eval.c:1868
+#, c-format
+msgid "\t# -- main --\n"
+msgstr ""
+"\t# -- main --\n"
+"(chính)\n"
+
+#: eval.c:2023
+msgid "attempt to field reference from non-numeric value"
+msgstr "cố tham chiếu trường từ giá trị không thuộc số"
+
+#: eval.c:2025
+msgid "attempt to reference from null string"
+msgstr "cố tham chiếu từ chuỗi vô giá trị"
+
+#: eval.c:2031
+#, c-format
+msgid "attempt to access field %d"
+msgstr "cố truy cập trường «%d»"
+
+#: eval.c:2052 eval.c:2059 profile.c:935
+msgid "assignment is not allowed to result of builtin function"
+msgstr "không cho phép gán cho kết quả của chức năng «builtin» (có sẵn)"
+
+#: eval.c:2123
+msgid "`IGNORECASE' is a gawk extension"
+msgstr "«IGNORECASE» (bỏ qua chữ hoa/thường) là một phần mở rộng gawk"
+
+#: eval.c:2153
+msgid "`BINMODE' is a gawk extension"
+msgstr "«BINMODE» (chế độ nhị phân) là một phần mở rộng gawk"
+
+#: eval.c:2275
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr "điều ghi rõ «%s» «%sFMT» sai"
+
+#: eval.c:2353
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr "đang tắt «--lint» vì gán cho «LINT»"
+
+#: ext.c:60 ext.c:64
+msgid "`extension' is a gawk extension"
+msgstr "«extension» là một phần mở rộng gawk"
+
+#: ext.c:74
+#, c-format
+msgid "extension: cannot open `%s' (%s)\n"
+msgstr "extension: (phần mở rộng) không mở được «%s» (%s)\n"
+
+#: ext.c:82
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"extension: (phần mở rộng) thư viên «%s»: không gọi được chức năng «%s» (%s)\n"
+
+#: ext.c:102
+msgid "extension: missing function name"
+msgstr "extension: (phần mở rộng) thiếu tên chức năng"
+
+#: ext.c:107
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr ""
+"extension: (phần mở rộng) không cho phép ký tự «%c» trong tên chức năng «%s»"
+
+#: ext.c:113
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr "extension: (phần mở rộng) không thể định nghĩa lại chức nắng «%s»"
+
+#: ext.c:117
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr "extension: (phần mở rộng) đã định nghĩa chức năng «%s» rồi"
+
+#: ext.c:122
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+"extension: (phần mở rộng) không thể dùng «%s» có sẵn gawk là tên chức năng"
+
+#: ext.c:124
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr "extension: (phần mở rộng) tên chức năng «%s» được định nghĩa trước"
+
+#: ext.c:201
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr "chức năng «%s» được định nghĩa để chấp nhận nhiều nhất «%d» đối số"
+
+#: ext.c:204
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr "chức năng «%s» thiếu đối số «#%d»"
+
+#: ext.c:214
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr "chức năng «%s»: đối số «#%d»: cố dùng điều vô hướng là một mảng"
+
+#: ext.c:218
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr "chức năng «%s»: đối số «#%d»: cố dùng mảng là một điều vô hướng"
+
+#: ext.c:243
+msgid "Operation Not Supported"
+msgstr "Không hỗ trợ thao tác ấy"
+
+#: field.c:326
+msgid "NF set to negative value"
+msgstr "đã lập «NF» là giá trị âm"
+
+#: field.c:819
+msgid "split: second argument is not an array"
+msgstr "split: (chia tách) đối số thứ hai không phải là một mảng"
+
+#: field.c:853
+msgid "split: null string for third arg is a gawk extension"
+msgstr ""
+"split: (chia tách) chuỗi vô giá trị cho đối số thứ ba là một phần mở rộng "
+"gawk"
+
+#: field.c:905
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr "«FIELDWIDTHS» (độ rộng trường) là một phần mở rộng gawk"
+
+#: field.c:935 field.c:946
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr "Giá trị «FIELDWIDTHS» (độ rộng trường) không hợp lệ, gần «%s»"
+
+#: field.c:1027
+msgid "null string for `FS' is a gawk extension"
+msgstr "chuỗi vô giá trị cho «FS» là một phần mở rộng gawk"
+
+#: getopt.c:571 getopt.c:590
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr "%s: tùy chọn «%s» là mơ hồ\n"
+
+#: getopt.c:623 getopt.c:627
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr "%s: tùy chọn «--%s» không cho phép đối số\n"
+
+#: getopt.c:636 getopt.c:641
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr "%s: tùy chọn «%c%s» không cho phép đối số\n"
+
+#: getopt.c:687 getopt.c:709 getopt.c:1040 getopt.c:1062
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr "%s: tùy chọn «%s» cần đến đối số\n"
+
+#: getopt.c:747 getopt.c:750
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr "%s: không chấp nhận tùy chọn «--%s»\n"
+
+#: getopt.c:758 getopt.c:761
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr "%s: không chấp nhận tùy chọn «%c%s»\n"
+
+#: getopt.c:816 getopt.c:819
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: không cho phép tùy chọn «-- %c»\n"
+
+#: getopt.c:825 getopt.c:828
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr "%s: tùy chọn không hợp lệ «-- %c»\n"
+
+#: getopt.c:883 getopt.c:902 getopt.c:1115 getopt.c:1136 main.c:448
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: tùy chọn cần đến đối số «-- %c»\n"
+
+#: getopt.c:955 getopt.c:974
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr "%s: tùy chọn «-W %s» là mơ hồ\n"
+
+#: getopt.c:998 getopt.c:1019
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr "%s: tùy chọn «-W %s» không cho phép đối số\n"
+
+#: io.c:307
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr "không mở được tập tin «%s» để ghi (%s)"
+
+#: io.c:398
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr "đóng «fd %d» («%s») thất bại (%s)"
+
+#: io.c:536
+#, c-format
+msgid "invalid tree type %s in redirect()"
+msgstr "kiểu cây không hợp lệ «%s» trong «redirect()»"
+
+#: io.c:542
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr "biểu thức trong điều chuyển hướng «%s» chỉ có giá trị thuộc số"
+
+#: io.c:548
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr "biểu thức cho điều chuyển hướng «%s» có giá trị chuỗi vô giá trị"
+
+#: io.c:553
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+"tên tập tin «%s» cho điều chuyển hướng «%s» có lẽ là kết quả của biểu thức "
+"luận lý"
+
+#: io.c:591
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr "không cần hợp «>» vào «>>» cho tập tin «%.*s»"
+
+#: io.c:643
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr "không mở được ống dẫn «%s» để xuất (%s)"
+
+#: io.c:652
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr "không mở được ống dẫn «%s» để gõ (%s)"
+
+#: io.c:665
+#, c-format
+msgid "can't open two way socket `%s' for input/output (%s)"
+msgstr "không mở được ổ cắm hai chiều «%s» để gõ/xuất (%s)"
+
+#: io.c:669
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr "không mở được ống dẫn hai chiều «%s» để gõ/xuất (%s)"
+
+#: io.c:745
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr "không thể chuyển hướng từ «%s» (%s)"
+
+#: io.c:748
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr "không thể chuyển hướng đến «%s» (%s)"
+
+#: io.c:787
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+"đã gặp giới hạn hệ thống cho tập tin đang mở nên bắt đầu phối hợp nhiều dòng "
+"điều diễn tả tâp tin"
+
+#: io.c:803
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr "đóng «%s» thất bại (%s)"
+
+#: io.c:811
+msgid "too many pipes or input files open"
+msgstr "quá nhiều ống dẫn hay tập tin gõ đang mở"
+
+#: io.c:834
+msgid "close: second argument must be `to' or `from'"
+msgstr "close: (đóng) đối số thứ hai phải là «to» (đến) hay «from» (từ)"
+
+#: io.c:848
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+"close: (đóng) «%.*s» không phải là một tập tin đang mở, một ống dẫn hay tiến "
+"trình với nhau"
+
+#: io.c:852
+msgid "close of redirection that was never opened"
+msgstr "đã đóng điều chuyển hướng chưa mở"
+
+#: io.c:948
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+"close: (đóng) điều chuyển hướng «%s» không do «|&» mở nên đối số thứ hai bị "
+"bỏ qua"
+
+#: io.c:964
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr "trạng thái thất bại (%d) khi đóng ống dẫn «%s» (%s)"
+
+#: io.c:967
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr "trạng thái thất bại (%d) khi đóng tập tin «%s» (%s)"
+
+#: io.c:987
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr "chưa cung cấp điều đóng ổ cắm «%s» dứt khoát"
+
+#: io.c:990
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr "chưa cung cấp điều đóng tiến trình với nhau «%s» dứt khoát"
+
+#: io.c:993
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr "chưa cung cấp điều đóng ống dẫn «%s» dứt khoát"
+
+#: io.c:996
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr "chưa cung cấp điều đóng tập tin «%s» dứt khoát"
+
+#: io.c:1025 io.c:1080 main.c:718 main.c:756
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr "gặp lỗi khi ghi thiết bị xụất chuẩn (%s)"
+
+#: io.c:1029 io.c:1085
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr "gặp lỗi khi ghi thiết bị lỗi chuẩn (%s)"
+
+#: io.c:1037
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr "xóa sạch ống dẫn «%s» thất bại (%s)"
+
+#: io.c:1040
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr "xóa sạch ống dẫn đồng tiến trình đến «%s» thất bại (%s)"
+
+#: io.c:1043
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr "xóa sạch tập tin «%s» thất bại (%s)"
+
+#: io.c:1205
+msgid "/inet/raw client not ready yet, sorry"
+msgstr "tiếc là trình khách «/inet/raw» chưa sẵn sàng"
+
+#: io.c:1207 io.c:1244
+msgid "only root may use `/inet/raw'."
+msgstr "chỉ người chủ (root) có thể sử dụng «/inet/raw» thôi"
+
+#: io.c:1242
+msgid "/inet/raw server not ready yet, sorry"
+msgstr "tiếc là trình phục vụ «/inet/raw» chưa sẵn sàng"
+
+#: io.c:1332
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr "trong tên tập tin đặc biệt «%s» không cung cấp giao thức (đã biết) nào"
+
+#: io.c:1350
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr "tên tập tin đặc biệt «%s» chưa xong"
+
+#: io.c:1362
+#, c-format
+msgid "local port invalid in `%s'"
+msgstr "trong «%s» cổng địa phương không hợp lệ"
+
+#: io.c:1374
+msgid "must supply a remote hostname to `/inet'"
+msgstr "phải cung cấp một tên máy từ xa cho «/inet»"
+
+#: io.c:1389
+msgid "must supply a remote port to `/inet'"
+msgstr "phải cung cấp một cổng từ xa cho «/inet»"
+
+#: io.c:1395
+#, c-format
+msgid "remote port invalid in `%s'"
+msgstr "trong «%s» cổng từ xa không hợp lệ"
+
+#: io.c:1405
+msgid "TCP/IP communications are not supported"
+msgstr "không hỗ trợ truyền thông TCP/IP"
+
+#: io.c:1414 io.c:1595
+#, c-format
+msgid "file `%s' is a directory"
+msgstr "tập tin «%s» là một thư mục"
+
+#: io.c:1484
+#, c-format
+msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+msgstr "hãy dùng «PROCINFO[\"%s\"]» (thông tin tiến trình) thay vào «%s»"
+
+#: io.c:1516
+msgid "use `PROCINFO[...]' instead of `/dev/user'"
+msgstr "hãy dùng «PROCINFO[...]» (thông tin tiến trình) thay vào «/dev/user»"
+
+#: io.c:1581 io.c:1763
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr "không mở được «%s», chế độ «%s»"
+
+#: io.c:1814
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr "đóng pty cái thất bại (%s)"
+
+#: io.c:1816 io.c:1968 io.c:2119
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr "đóng thiết bị xuất chuẩn trong tiến trình con thất bại (%s)"
+
+#: io.c:1819
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+"di chuyển pty phụ đến thiết bị xuất chuẩn thất bại trong tiến trình con "
+"(dup: %s) (nhân đôi)"
+
+#: io.c:1821 io.c:1973
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr "đóng thiết bị gõ chuẩn trong tiến trình con thất bại (%s)"
+
+#: io.c:1824
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+"di chuyển điều phụ đến thiết bị gõ chuẩn thất bại trong tiến trình con (dup: "
+"%s) (nhân đôi)"
+
+#: io.c:1826 io.c:1845
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr "đóng điều phụ thất bại (%s)"
+
+#: io.c:1919 io.c:1971 io.c:2100 io.c:2122
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+"di chuyển ống dẫn đến thiết bị xuất chuẩn thất bại trong tiến trình con "
+"(dup: %s) (nhân đôi)"
+
+#: io.c:1923 io.c:1976
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+"di chuyển ống dẫn đến thiết bị gõ chuẩn thất bại trong tiến trình con (dup: %"
+"s) (nhân đôi)"
+
+#: io.c:1940 io.c:2113
+msgid "restoring stdout in parent process failed\n"
+msgstr "phục hồi thiết bị xuất chuẩn trong tiến trình mẹ thất bại\n"
+
+#: io.c:1945
+msgid "restoring stdin in parent process failed\n"
+msgstr "phục hồi thiết bị gõ chuẩn trong tiến trình mẹ thất bại\n"
+
+#: io.c:1979 io.c:2124 io.c:2135
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr "đóng ống dẫn thất bại (%s)"
+
+#: io.c:2024
+msgid "`|&' not supported"
+msgstr "không hỗ trợ «|&»"
+
+#: io.c:2090
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr "không mở được «%s» (%s)"
+
+#: io.c:2131
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr "không tạo được tiến trình con cho «%s» (fork: %s)"
+
+#: io.c:2506
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "tập tin dữ liệu «%s» là rỗng"
+
+#: io.c:2547 io.c:2555
+msgid "could not allocate more input memory"
+msgstr "không thể cấp phát bộ nhớ gõ nhiều hơn"
+
+#: io.c:2919 io.c:2984
+#, c-format
+msgid "error reading input file `%s': %s"
+msgstr "gặp lỗi khi đọc tập tin gõ «%s»: %s"
+
+#: io.c:3109
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "giá trị đa ký tự của «RS» là một phần mở rộng gawk"
+
+#: main.c:338
+msgid "`-m[fr]' option irrelevant in gawk"
+msgstr "«-m[fr]» tùy chọn không thích đang trong gawk"
+
+#: main.c:340
+msgid "-m option usage: `-m[fr] nnn'"
+msgstr "cách sử dụng tùy chọn «-m»: «-m[fr] nnn»"
+
+#: main.c:357
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: tùy chọn «-W %s» không được nhận diện nên bị bỏ qua\n"
+
+#: main.c:394
+msgid "empty argument to `--source' ignored"
+msgstr "đối số rỗng tới «--source» (nguồn) bị bỏ qua"
+
+#: main.c:467
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+"đã lập biến môi trường «POSIXLY_CORRECT» (đúng cách POSIX) thì đang bật tùy "
+"chọn «--posix»"
+
+#: main.c:472
+msgid "`--posix' overrides `--traditional'"
+msgstr "tùy chọn «--posix» đè «--traditional» (truyền thống)"
+
+#: main.c:483
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr ""
+"«--posix»/«--traditional» (truyền thống) đè «--non-decimal-data» (dữ liệu "
+"không phải thập phân)"
+
+#: main.c:487
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr "chạy «%s» với tư cách «setuid root» thì có lẽ sẽ rủi rỏ bảo mật"
+
+#: main.c:528
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr "không lập được chế độ nhị phân trên thiết bị gõ chuẩn (%s)"
+
+#: main.c:531
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr "không lập được chế độ nhị phân trên thiết bị xuất chuẩn (%s)"
+
+#: main.c:533
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr "không lập được chế độ nhị phân trên thiết bị lỗi chuẩn (%s)"
+
+#: main.c:572
+msgid "no program text at all!"
+msgstr "không có chữ chương trình nào cả!"
+
+#: main.c:665
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+"Cách sử dụng: %s [tùy chọn kiểu POSIX hay GNU] -f tập_tin_chương_trình [--] "
+"tập_tin ...\n"
+
+#: main.c:667
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+"Cách sử dụng: %s [tùy chọn kiểu POSIX hay GNU] [--] %cchương_trình%c "
+"tập_tin ...\n"
+
+#: main.c:672
+msgid "POSIX options:\t\tGNU long options:\n"
+msgstr "tùy chọn POSIX:\t\ttùy chọn dài GNU:\n"
+
+#: main.c:673
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr "\t-f tập_tin_chương_trình\t\t--tập_tin=tập_tin_chương_trình\n"
+
+#: main.c:674
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr "\t-F fs\t\t\t--field-separator=fs\t\tđiều phân cách trườngs\n"
+
+#: main.c:675
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr ""
+"\t-v var=val\t\t--assign=var=val\n"
+"(var là viết tắt cho variable: biến\n"
+"val là viết tắt cho value: giá trị\n"
+"assign: gán)\n"
+
+#: main.c:676
+msgid "\t-m[fr] val\n"
+msgstr "\t-m[fr] val\n"
+
+#: main.c:677
+msgid "\t-W compat\t\t--compat\n"
+msgstr ""
+"\t-W compat\t\t--compat\n"
+"(compat là viết tắt cho compatible: tương thích)\n"
+
+#: main.c:678
+msgid "\t-W copyleft\t\t--copyleft\n"
+msgstr ""
+"\t-W copyleft\t\t--copyleft\n"
+"(sao chép trái)\n"
+
+#: main.c:679
+msgid "\t-W copyright\t\t--copyright\n"
+msgstr ""
+"\t-W copyright\t\t--copyright\n"
+"(sao chép phải hoặc bản quyền)\n"
+
+#: main.c:680
+msgid "\t-W dump-variables[=file]\t--dump-variables[=file]\n"
+msgstr ""
+"\t-W dump-variables[=tập_tin]\t--dump-variables[=tập_tin]\n"
+"(đổ các biến)\n"
+
+#: main.c:681
+msgid "\t-W exec=file\t\t--exec=file\n"
+msgstr "\t-W exec=file\t\t--exec=file\n"
+
+#: main.c:682
+msgid "\t-W gen-po\t\t--gen-po\n"
+msgstr ""
+"\t-W gen-po\t\t--gen-po\n"
+"(gen là viết tắt cho generate: tạo ra)\n"
+
+#: main.c:683
+msgid "\t-W help\t\t\t--help\n"
+msgstr ""
+"\t-W help\t\t\t--help\n"
+"(trợ giúp)\n"
+
+#: main.c:684
+msgid "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr ""
+"\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+"(l? int là viết tắt cho integer: số nguyên\n"
+"fatal: nghiêm trọng)\n"
+
+#: main.c:685
+msgid "\t-W lint-old\t\t--lint-old\n"
+msgstr ""
+"\t-W lint-old\t\t--lint-old\n"
+"(old: cũ)\n"
+
+#: main.c:686
+msgid "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr ""
+"\t-W non-decimal-data\t--non-decimal-data\n"
+"(dữ liệu không phải thập phân)\n"
+
+#: main.c:688
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr ""
+"\t-W nostalgia\t\t--nostalgia\n"
+"(nỗi luyến tiếc quá khứ)\n"
+
+#: main.c:691
+msgid "\t-W parsedebug\t\t--parsedebug\n"
+msgstr ""
+"\t-W parsedebug\t\t--parsedebug\n"
+"(parse: phân tách\n"
+"debug: gỡ lỗi)\n"
+
+#: main.c:693
+msgid "\t-W profile[=file]\t--profile[=file]\n"
+msgstr ""
+"\t-W profile[=tập_tin]\t--profile[=tập_tin]\n"
+"(profile: tiểu sử sơ lược)\n"
+
+#: main.c:694
+msgid "\t-W posix\t\t--posix\n"
+msgstr "\t-W posix\t\t--posix\n"
+
+#: main.c:695
+msgid "\t-W re-interval\t\t--re-interval\n"
+msgstr ""
+"\t-W re-interval\t\t--re-interval\n"
+"(re-[động từ]: [làm] lại\n"
+"interval: thời gian giữa hai lúc)\n"
+
+#: main.c:696
+msgid "\t-W source=program-text\t--source=program-text\n"
+msgstr ""
+"\t-W source=program-text\t--source=program-text\n"
+"(source: nguồn\n"
+"program-text: các văn bản trong chương trình)\n"
+
+#: main.c:697
+msgid "\t-W traditional\t\t--traditional\n"
+msgstr ""
+"\t-W traditional\t\t--traditional\n"
+"(truyền thống)\n"
+
+#: main.c:698
+msgid "\t-W usage\t\t--usage\n"
+msgstr ""
+"\t-W usage\t\t--usage\n"
+"(cách sử dụng)\n"
+
+#: main.c:699
+msgid "\t-W version\t\t--version\n"
+msgstr ""
+"\t-W version\t\t--version\n"
+"(phiên bản)\n"
+
+#: main.c:703
+msgid ""
+"\n"
+"To report bugs, see node `Bugs' in `gawk.info', which is\n"
+"section `Reporting Problems and Bugs' in the printed version.\n"
+"\n"
+msgstr ""
+"\n"
+"Để thông báo lỗi, hãy xem phần «Bugs» (Lỗi) trong tập tin «gawk.info»\n"
+"trong phần «Reporting Problems and Bugs» (thông báo vấn đề và lỗi)\n"
+"trong bản in.\n"
+
+#: main.c:707
+msgid ""
+"gawk is a pattern scanning and processing language.\n"
+"By default it reads standard input and writes standard output.\n"
+"\n"
+msgstr ""
+"gawk là một ngôn ngữ quét mẫu và xử lý.\n"
+"Mặc định là nó đọc từ thiết bị gõ chuẩn và ghi vào thiết bị xuất chuẩn.\n"
+"\n"
+
+#: main.c:711
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+"Thí dụ:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+
+#: main.c:731
+#, c-format
+msgid ""
+"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+"Bản quyền © 1989, 1991-%d Tổ chức Phần mềm Tự do.\n"
+"\n"
+"Chương trình này là phần mềm tự do; bạn có thể phân phối lại nó\n"
+"và/hay sửa đổi nó với điều kiện của Quyền Công Chung GNU (GPL)\n"
+"như do Tổ chức Phần mềm Tự do xuất bản, hoặc phiên bản 2\n"
+"của Quyền ấy, hoặc (tùy chọn) bất cứ phiên bản sau nào.\n"
+"\n"
+
+#: main.c:739
+msgid ""
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+msgstr ""
+"Chúng tôi phân phối chương trình này vì mong muốn nó hữu ích,\n"
+"nhưng mà KHÔNG BẢO ĐẢM GÌ CẢ, không ngay cả ngụ ý bảo đảm\n"
+"KHẢ NĂNG BÁN hoặc KHẢ NĂNG LÀM VIỆC DỨT KHOÁT.\n"
+"Hãy xem Quyền Công Chung GNU (GNU General Public Licence)\n"
+"để tìm chi tiết.\n"
+"\n"
+
+#: main.c:745
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
+"USA.\n"
+msgstr ""
+"Bện nên đã nhận một bản sao của Quyền Công Chung GNU\n"
+"cũng với chương trình này; nếu không thì hãy viết cho\n"
+"Tổ chức Phần mềm Tự do:\n"
+"Free Software Foundation, Inc.,\n"
+"51 Franklin Street, Fifth Floor,\n"
+"Boston, MA 02110-1301, USA. (Mỹ)\n"
+
+#: main.c:781
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr "-Ft không lập FS là tab trong awk POSIX"
+
+#: main.c:1018
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+"%s: đối số «%s» với «-v» không phải có dạng «biến=giá_trị» \n"
+"\n"
+
+#: main.c:1038
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr "«%s» không phải là một tên biến cho phép"
+
+#: main.c:1041
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "«%s» không phải là một tên biến nên đang tìm tập tin «%s=%s»"
+
+#: main.c:1074
+msgid "floating point exception"
+msgstr "ngoại lệ điểm phù động"
+
+#: main.c:1081
+msgid "fatal error: internal error"
+msgstr "lỗi nghiêm trọng: lỗi nội bộ"
+
+#: main.c:1132
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr "không có «fd %d» đã mở trước"
+
+#: main.c:1139
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr "không mở được «/dev/null» trước cho «fd %d»"
+
+#: main.c:1162 main.c:1171
+#, c-format
+msgid "could not find groups: %s"
+msgstr "không tìm được nhóm: %s"
+
+#: msg.c:54
+#, c-format
+msgid "cmd. line:"
+msgstr "dòng lệnh:"
+
+#: msg.c:120
+msgid "warning: "
+msgstr "cảnh báo:"
+
+#: msg.c:142
+msgid "error: "
+msgstr "lỗi: "
+
+#: msg.c:178
+msgid "fatal: "
+msgstr "nghiêm trọng:"
+
+#: node.c:59 node.c:66 node.c:75 node.c:90 node.c:119
+msgid "can't convert string to float"
+msgstr "không thể chuyển đổi chuỗi sang điều lơ lửng"
+
+#: node.c:414
+msgid "backslash at end of string"
+msgstr "xuyệc ngoặc tại kết thức chuỗi"
+
+#: node.c:604
+msgid "POSIX does not allow `\\x' escapes"
+msgstr "POSIX không cho phép điều thoát «\\x»"
+
+#: node.c:610
+msgid "no hex digits in `\\x' escape sequence"
+msgstr "không có số thập lúc phân trong dây thoát «\\x»"
+
+#: node.c:644
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr "dây thoát «\\%c» được xử lý là «%c» giản dị"
+
+#: posix/gawkmisc.c:172
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl: %s)"
+msgstr ""
+"%s %s «%s»: không lập được «close-on-exec» (đóng một khi thực hiện) (fcntl: %"
+"s)"
+
+#: profile.c:91
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr "không mở được «%s» để ghi: %s"
+
+#: profile.c:467
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr "lỗi nội bộ: «%s» với vname (tên biến) vô giá trị"
+
+#: profile.c:531
+msgid "# treated internally as `delete'"
+msgstr "# được xử lý nội bộ là «xóa bỏ»"
+
+#: profile.c:1168
+#, c-format
+msgid "# this is a dynamically loaded extension function"
+msgstr "# đây là một chức năng mở rộng được tải một cách động"
+
+#: profile.c:1199
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr "\t# tiểu sở sơ lược gawk, được tạo %s\n"
+
+#: profile.c:1202
+#, c-format
+msgid ""
+"\t# BEGIN block(s)\n"
+"\n"
+msgstr ""
+"\t# khối BEGIN (bắt đầu)\n"
+"\n"
+
+#: profile.c:1212
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+"\t# Quy tắc\n"
+"\n"
+
+#: profile.c:1218
+#, c-format
+msgid ""
+"\t# END block(s)\n"
+"\n"
+msgstr ""
+"\t# khối END (kết thức)\n"
+"\n"
+
+#: profile.c:1238
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+"\n"
+"\t# Các chức năng theo thứ tự abc\n"
+
+#: profile.c:1453
+#, c-format
+msgid "unexpected type %s in prec_level"
+msgstr "gặp kiểu bất ngờ «%s» trong «prec_level» (cấp trước?)"
+
+#: regcomp.c:160
+msgid "Success"
+msgstr "Thành công"
+
+#: regcomp.c:163
+msgid "No match"
+msgstr "Không khớp với gì"
+
+#: regcomp.c:166
+msgid "Invalid regular expression"
+msgstr "Biểu thức chính quy không hợp lệ"
+
+#: regcomp.c:169
+msgid "Invalid collation character"
+msgstr "Ký tự đối chiếu không hợp lệ"
+
+#: regcomp.c:172
+msgid "Invalid character class name"
+msgstr "Tên hạng ký tự không hợp lệ"
+
+#: regcomp.c:175
+msgid "Trailing backslash"
+msgstr "Có xuyệc ngược theo sau"
+
+#: regcomp.c:178
+msgid "Invalid back reference"
+msgstr "Tham chiếu trở lại không hợp lệ"
+
+#: regcomp.c:181
+msgid "Unmatched [ or [^"
+msgstr "Chưa khớp «[» hay «[^»"
+
+#: regcomp.c:184
+msgid "Unmatched ( or \\("
+msgstr "Chưa khớp «(» hay «\\(»"
+
+#: regcomp.c:187
+msgid "Unmatched \\{"
+msgstr "Chưa khớp «\\{»"
+
+#: regcomp.c:190
+msgid "Invalid content of \\{\\}"
+msgstr "Nội dụng «\\{\\}» không hợp lệ"
+
+#: regcomp.c:193
+msgid "Invalid range end"
+msgstr "Kết thức miền không hợp lệ"
+
+#: regcomp.c:196
+msgid "Memory exhausted"
+msgstr "Hết bộ nhớ rồi"
+
+#: regcomp.c:199
+msgid "Invalid preceding regular expression"
+msgstr "Biểu thức chính quy đi trước không hợp lệ"
+
+#: regcomp.c:202
+msgid "Premature end of regular expression"
+msgstr "Kết thức quá sớm của biểu thức chính quy"
+
+#: regcomp.c:205
+msgid "Regular expression too big"
+msgstr "Biểu thức chính quy quá lớn"
+
+#: regcomp.c:208
+msgid "Unmatched ) or \\)"
+msgstr "Chưa khớp «)» hay «\\)»"
+
+#: regcomp.c:688
+msgid "No previous regular expression"
+msgstr "Không có biểu thức chính quy đi trước"
+
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: (xóa bỏ) không cho phép cách dùng biến «%s» là mảng"
+
+#~ msgid "asort: first argument is not an array"
+#~ msgstr "asort: (sắp xếp) đối số đầu không phải là một mảng"
+
+#~ msgid "asort: second argument is not an array"
+#~ msgstr "asort: (sắp xếp) đối số thứ hai không phải là một mảng"
+
+#~ msgid ""
+#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Để thông báo lỗi, hãy xem phần «Bugs» (lỗi) trong tập tin «gawk.info», \n"
+
+#~ msgid "invalid syntax in name `%s' for variable assignment"
+#~ msgstr "cú pháp không hợp lệ trong tên «%s» trong điều gán biến"
+
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "lỗi nội bộ: «Node_var_array» với vname (tên biến) vô giá trị"
+
+#~ msgid "or used in other expression context"
+#~ msgstr "hoặc được dùng trong ngữ cảnh biểu thức khác"
+
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "«%s» là một chức năng thì không cho phép gán"
+
+#~ msgid "BEGIN blocks must have an action part"
+#~ msgstr "Mọi khối BEGIN (bắt đầu) phải có một phần là hành động"
+
+#~ msgid "`nextfile' used in BEGIN or END action"
+#~ msgstr ""
+#~ "đã dùng «nextfile» (tập tin kế tiếp) trong hành động «BEGIN» (bắt đầu) "
+#~ "hay «END» (kết thức)"
+
+#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
+#~ msgstr ""
+#~ "trong hành động «BEGIN» (đầu) hay «END» (kết thức), có «getline» (lấy "
+#~ "dòng) không được chuyển hướng và chưa được định nghĩa."
+
+#~ msgid "fptr %x not in tokentab\n"
+#~ msgstr "«fptr %x» không phải trong «tokentab»\n"
+
+#~ msgid "gsub third parameter is not a changeable object"
+#~ msgstr "tham số thứ ba gsub không phải là một đối tượng có thể thay đổi"
+
+#~ msgid "Unfinished \\ escape"
+#~ msgstr "«\\ escape» chưa xong"
+
+#~ msgid "unfinished repeat count"
+#~ msgstr "việc đếm lần nữa chưa xong"
+
+#~ msgid "malformed repeat count"
+#~ msgstr "việc đếm lần nữa dạng sai"
+
+#~ msgid "Unbalanced ["
+#~ msgstr "Chưa cân bằng «[»"
+
+#~ msgid "Unbalanced ("
+#~ msgstr "Chưa cân bằng «(»"
+
+#~ msgid "No regexp syntax bits specified"
+#~ msgstr "Chưa ghi rõ bit cú pháp biểu thức chính quy"
+
+#~ msgid "Unbalanced )"
+#~ msgstr "Chưa cân bằng «)»"
+
+#~ msgid "out of memory"
+#~ msgstr "hết bộ nhớ"
+
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "trường %d trong «FIELDWIDTHS», phải > 0"
+
+#~ msgid "function %s called\n"
+#~ msgstr "đã gọi chức năng «%s»\n"
+
+#~ msgid "internal error: file `%s', line %d\n"
+#~ msgstr "lỗi nội bộ: tập tin «%s», dòng %d\n"
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Sun May 25 16:23:43 2003 Corinna Vinschen <vinschen@redhat.com>
+
+ * gawkmisc.c (cygwin_premain0): New function.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Tue Dec 17 11:05:11 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (optimal_bufsize): Stat the file first, so that
+ stb is always valid for higher level code.
+
+Thu Nov 28 10:20:05 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (optimal_bufsize): Enhance to use AWKBUFSIZE
+ environment variable for debugging.
+
+Tue Jun 11 22:18:42 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * gawkmisc.c (DEFBLKSIZE): Add check for st_blksize > 0,
+ fixes weird bug on some versions of HP-UX.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Tue Sep 25 15:19:53 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_close_on_exec): If fd <= 2, return.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawkmisc.c (os_restore_mode): New function.
+
+Sun Dec 3 16:53:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_setbinmode): New function.
+
+Tue Nov 14 16:13:08 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c: Remove all includes. Done by ../gawkmisc.c.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_is_setuid): new function.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Close-on-exec changes:
+ gawkmisc.c: (os_close_on_exec, os_isdir): new functions.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * ChangeLog created.
--- /dev/null
+/* gawkmisc.c --- miscellaneous gawk routines that are OS specific.
+
+ Copyright (C) 1986, 1988, 1989, 1991 - 1998, 2001 - 2004 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+char quote = '\'';
+char *defpath = DEFPATH;
+char envsep = ':';
+
+#ifndef INVALID_HANDLE
+/* FIXME: is this value for INVALID_HANDLE correct? */
+#define INVALID_HANDLE -1
+#endif
+
+/* gawk_name --- pull out the "gawk" part from how the OS called us */
+
+char *
+gawk_name(filespec)
+const char *filespec;
+{
+ char *p;
+
+ /* "path/name" -> "name" */
+ p = strrchr(filespec, '/');
+ return (p == NULL ? (char *) filespec : p + 1);
+}
+
+/* os_arg_fixup --- fixup the command line */
+
+void
+os_arg_fixup(argcp, argvp)
+int *argcp;
+char ***argvp;
+{
+ /* no-op */
+ return;
+}
+
+/* os_devopen --- open special per-OS devices */
+
+int
+os_devopen(name, flag)
+const char *name;
+int flag;
+{
+ /* no-op */
+ return INVALID_HANDLE;
+}
+
+/* optimal_bufsize --- determine optimal buffer size */
+
+/*
+ * Enhance this for debugging purposes, as follows:
+ *
+ * Always stat the file, stat buffer is used by higher-level code.
+ *
+ * if (AWKBUFSIZE == "exact")
+ * return the file size
+ * else if (AWKBUFSIZE == a number)
+ * always return that number
+ * else
+ * if the size is < default_blocksize
+ * return the size
+ * else
+ * return default_blocksize
+ * end if
+ * endif
+ *
+ * Hair comes in an effort to only deal with AWKBUFSIZE
+ * once, the first time this routine is called, instead of
+ * every time. Performance, dontyaknow.
+ */
+
+size_t
+optimal_bufsize(fd, stb)
+int fd;
+struct stat *stb;
+{
+ char *val;
+ static size_t env_val = 0;
+ static short first = TRUE;
+ static short exact = FALSE;
+
+ /* force all members to zero in case OS doesn't use all of them. */
+ memset(stb, '\0', sizeof(struct stat));
+
+ /* always stat, in case stb is used by higher level code. */
+ if (fstat(fd, stb) == -1)
+ fatal("can't stat fd %d (%s)", fd, strerror(errno));
+
+ if (first) {
+ first = FALSE;
+
+ if ((val = getenv("AWKBUFSIZE")) != NULL) {
+ if (strcmp(val, "exact") == 0)
+ exact = TRUE;
+ else if (ISDIGIT(*val)) {
+ for (; *val && ISDIGIT(*val); val++)
+ env_val = (env_val * 10) + *val - '0';
+
+ return env_val;
+ }
+ }
+ } else if (! exact && env_val > 0)
+ return env_val;
+ /* else
+ fall through */
+
+ /*
+ * System V.n, n < 4, doesn't have the file system block size in the
+ * stat structure. So we have to make some sort of reasonable
+ * guess. We use stdio's BUFSIZ, since that is what it was
+ * meant for in the first place.
+ */
+#ifdef HAVE_ST_BLKSIZE
+#define DEFBLKSIZE (stb->st_blksize > 0 ? stb->st_blksize : BUFSIZ)
+#else
+#define DEFBLKSIZE BUFSIZ
+#endif
+
+ if (S_ISREG(stb->st_mode) /* regular file */
+ && 0 < stb->st_size /* non-zero size */
+ && (stb->st_size < DEFBLKSIZE /* small file */
+ || exact)) /* or debugging */
+ return stb->st_size; /* use file size */
+
+ return DEFBLKSIZE;
+}
+
+/* ispath --- return true if path has directory components */
+
+int
+ispath(file)
+const char *file;
+{
+ return (strchr(file, '/') != NULL);
+}
+
+/* isdirpunct --- return true if char is a directory separator */
+
+int
+isdirpunct(c)
+int c;
+{
+ return (c == '/');
+}
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+const char *name, *what, *dir;
+{
+ if (fd <= 2) /* sanity */
+ return;
+
+ if (fcntl(fd, F_SETFD, 1) < 0)
+ warning(_("%s %s `%s': could not set close-on-exec: (fcntl: %s)"),
+ what, dir, name, strerror(errno));
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+#if ! defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+int
+os_isdir(fd)
+int fd;
+{
+ struct stat sbuf;
+
+ return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
+}
+
+/* os_is_setuid --- true if running setuid root */
+
+int
+os_is_setuid()
+{
+ long uid, euid;
+
+ uid = getuid();
+ euid = geteuid();
+
+ return (euid == 0 && euid != uid);
+}
+
+/* os_setbinmode --- set binary mode on file */
+
+int
+os_setbinmode(fd, mode)
+int fd, mode;
+{
+ return 0;
+}
+
+/* os_restore_mode --- restore the original mode of the console device */
+
+void
+os_restore_mode (fd)
+int fd;
+{
+ /* no-op */
+ return;
+}
+
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+
+extern int _fmode;
+void
+cygwin_premain0 (int argc, char **argv, struct per_process *myself)
+{
+ static struct __cygwin_perfile pf[] =
+ {
+ {"", O_RDONLY | O_TEXT},
+ /*{"", O_WRONLY | O_BINARY},*/
+ {NULL, 0}
+ };
+ cygwin_internal (CW_PERFILE, pf);
+}
+#endif
--- /dev/null
+/*
+ * profile.c - gawk parse tree pretty-printer with counts
+ */
+
+/*
+ * Copyright (C) 1999-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+/* where to place redirections for getline, print, printf */
+enum redir_placement {
+ BEFORE = 0,
+ AFTER = 1
+};
+
+#undef tree_eval
+static void tree_eval P((NODE *tree));
+static void parenthesize P((NODETYPE parent_type, NODE *tree));
+static void eval_condition P((NODE *tree));
+static void pp_op_assign P((NODE *tree));
+static void pp_func_call P((NODE *tree));
+static void pp_match_op P((NODE *tree));
+static void pp_lhs P((NODE *ptr));
+static void pp_print_stmt P((const char *command, NODE *tree));
+static void pp_delete P((NODE *tree));
+static void pp_in_array P((NODE *array, NODE *subscript));
+static void pp_getline P((NODE *tree));
+static void pp_builtin P((NODE *tree));
+static void pp_list P((NODE *tree));
+static void pp_string P((const char *str, size_t len, int delim));
+static int is_scalar P((NODETYPE type));
+static int prec_level P((NODETYPE type));
+#ifdef PROFILING
+static RETSIGTYPE dump_and_exit P((int signum)) ATTRIBUTE_NORETURN;
+static RETSIGTYPE just_dump P((int signum));
+#endif
+
+/* pretty printing related functions and variables */
+
+static char **fparms; /* function parameter names */
+static FILE *prof_fp; /* where to send the profile */
+
+static long indent_level = 0;
+
+static int in_BEGIN_or_END = FALSE;
+
+static int in_expr = FALSE;
+
+#define SPACEOVER 0
+
+/* init_profiling --- do needed initializations, see also main.c */
+
+void
+init_profiling(int *flag ATTRIBUTE_UNUSED, const char *def_file ATTRIBUTE_UNUSED)
+{
+#ifdef PROFILING
+ if (*flag == FALSE) {
+ *flag = TRUE;
+ set_prof_file(def_file);
+ }
+#endif
+}
+
+/* set_prof_file --- set the output file for profiling */
+
+void
+set_prof_file(const char *file)
+{
+ assert(file != NULL);
+
+ prof_fp = fopen(file, "w");
+ if (prof_fp == NULL) {
+ warning(_("could not open `%s' for writing: %s"),
+ file, strerror(errno));
+ warning(_("sending profile to standard error"));
+ prof_fp = stderr;
+ }
+}
+
+/* init_profiling_signals --- set up signal handling for pgawk */
+
+void
+init_profiling_signals()
+{
+#ifdef PROFILING
+#ifdef __DJGPP__
+ signal(SIGINT, dump_and_exit);
+ signal(SIGQUIT, just_dump);
+#else /* !__DJGPP__ */
+#ifdef SIGHUP
+ signal(SIGHUP, dump_and_exit);
+#endif
+#ifdef SIGUSR1
+ signal(SIGUSR1, just_dump);
+#endif
+#endif /* !__DJGPP__ */
+#endif /* PROFILING */
+}
+
+/* indent --- print out enough tabs */
+
+static void
+indent(long count)
+{
+ int i;
+
+ if (count == 0)
+ putc('\t', prof_fp);
+ else
+ fprintf(prof_fp, "%6ld ", count);
+
+ assert(indent_level >= 0);
+ for (i = 0; i < indent_level; i++)
+ putc('\t', prof_fp);
+}
+
+/* indent_in --- increase the level, with error checking */
+
+static void
+indent_in(void)
+{
+ assert(indent_level >= 0);
+ indent_level++;
+}
+
+/* indent_out --- decrease the level, with error checking */
+
+static void
+indent_out(void)
+{
+ indent_level--;
+ assert(indent_level >= 0);
+}
+
+/*
+ * pprint:
+ * Tree is a bunch of rules to run. Returns zero if it hit an exit()
+ * statement
+ */
+static void
+pprint(register NODE *volatile tree)
+{
+ register NODE *volatile t = NULL; /* temporary */
+ int volatile traverse = TRUE; /* True => loop thru tree (Node_rule_list) */
+
+ /* avoid false source indications */
+ source = NULL;
+ sourceline = 0;
+
+ if (tree == NULL)
+ return;
+ sourceline = tree->source_line;
+ source = tree->source_file;
+ switch (tree->type) {
+ case Node_rule_node:
+ traverse = FALSE; /* False => one for-loop iteration only */
+ /* FALL THROUGH */
+ case Node_rule_list:
+ for (t = tree; t != NULL; t = t->rnode) {
+ if (traverse)
+ tree = t->lnode;
+ sourceline = tree->source_line;
+ source = tree->source_file;
+
+ if (! in_BEGIN_or_END)
+ indent(tree->exec_count);
+
+ if (tree->lnode) {
+ eval_condition(tree->lnode);
+ if (tree->rnode)
+ fprintf(prof_fp, "\t");
+ }
+
+ if (tree->rnode) {
+ if (! in_BEGIN_or_END) {
+ fprintf(prof_fp, "{");
+ if (tree->lnode != NULL
+ && tree->lnode->exec_count)
+ fprintf(prof_fp, " # %ld",
+ tree->lnode->exec_count);
+ fprintf(prof_fp, "\n");
+ }
+ indent_in();
+ pprint(tree->rnode);
+ indent_out();
+ if (! in_BEGIN_or_END) {
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ }
+ }
+
+ if (! traverse) /* case Node_rule_node */
+ break; /* don't loop */
+
+ if (t->rnode && ! in_BEGIN_or_END)
+ fprintf(prof_fp, "\n");
+ }
+ break;
+
+ case Node_statement_list:
+ for (t = tree; t != NULL; t = t->rnode) {
+ pprint(t->lnode);
+ }
+ break;
+
+ case Node_K_if:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "if (");
+ in_expr++;
+ eval_condition(tree->lnode);
+ in_expr--;
+ fprintf(prof_fp, ") {");
+#ifdef PROFILING
+ if (tree->rnode->exec_count)
+ fprintf(prof_fp, " # %ld", tree->rnode->exec_count);
+#endif
+ fprintf(prof_fp, "\n");
+ indent_in();
+ pprint(tree->rnode->lnode);
+ indent_out();
+ if (tree->rnode->rnode != NULL) {
+ if (tree->exec_count - tree->rnode->exec_count > 0)
+ indent(tree->exec_count - tree->rnode->exec_count);
+ else
+ indent(0);
+ fprintf(prof_fp, "} else {\n");
+ indent_in();
+ pprint(tree->rnode->rnode);
+ indent_out();
+ }
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ break;
+
+ case Node_K_switch:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "switch (");
+ in_expr++;
+ pprint(tree->lnode);
+ in_expr--;
+ fprintf(prof_fp, ") {\n");
+ pprint(tree->rnode);
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ break;
+
+ case Node_switch_body:
+ case Node_case_list:
+ pprint(tree->lnode);
+ pprint(tree->rnode);
+ break;
+
+ case Node_K_case:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "case ");
+ in_expr++;
+ pprint(tree->lnode);
+ in_expr--;
+ fprintf(prof_fp, ":\n");
+ indent_in();
+ pprint(tree->rnode);
+ indent_out();
+ break;
+
+ case Node_K_default:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "default:\n");
+ indent_in();
+ pprint(tree->rnode);
+ indent_out();
+ break;
+
+ case Node_K_while:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "while (");
+ in_expr++;
+ eval_condition(tree->lnode);
+ in_expr--;
+ fprintf(prof_fp, ") {\n");
+ indent_in();
+ pprint(tree->rnode);
+ indent_out();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ break;
+
+ case Node_K_do:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "do {\n");
+ indent_in();
+ pprint(tree->rnode);
+ indent_out();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "} while (");
+ in_expr++;
+ eval_condition(tree->lnode);
+ in_expr--;
+ fprintf(prof_fp, ")\n");
+ break;
+
+ case Node_K_for:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "for (");
+ in_expr++;
+ pprint(tree->forloop->init);
+ fprintf(prof_fp, "; ");
+ eval_condition(tree->forloop->cond);
+ fprintf(prof_fp, "; ");
+ pprint(tree->forloop->incr);
+ fprintf(prof_fp, ") {\n");
+ in_expr--;
+ indent_in();
+ pprint(tree->lnode);
+ indent_out();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ break;
+
+ case Node_K_arrayfor:
+#define hakvar forloop->init
+#define arrvar forloop->incr
+ indent(tree->exec_count);
+ fprintf(prof_fp, "for (");
+ in_expr++;
+ pp_lhs(tree->hakvar);
+ in_expr--;
+ fprintf(prof_fp, " in ");
+ t = tree->arrvar;
+ if (t->type == Node_param_list)
+ fprintf(prof_fp, "%s", fparms[t->param_cnt]);
+ else
+ fprintf(prof_fp, "%s", t->vname);
+ fprintf(prof_fp, ") {\n");
+ indent_in();
+ pprint(tree->lnode);
+ indent_out();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}\n");
+ break;
+#undef hakvar
+#undef arrvar
+
+ case Node_K_break:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "break\n");
+ break;
+
+ case Node_K_continue:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "continue\n");
+ break;
+
+ case Node_K_print:
+ case Node_K_print_rec:
+ pp_print_stmt("print", tree);
+ break;
+
+ case Node_K_printf:
+ pp_print_stmt("printf", tree);
+ break;
+
+ case Node_K_delete:
+ pp_delete(tree);
+ break;
+
+ case Node_K_next:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "next\n");
+ break;
+
+ case Node_K_nextfile:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "nextfile\n");
+ break;
+
+ case Node_K_exit:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "exit");
+ if (tree->lnode != NULL) {
+ fprintf(prof_fp, " ");
+ tree_eval(tree->lnode);
+ }
+ fprintf(prof_fp, "\n");
+ break;
+
+ case Node_K_return:
+ indent(tree->exec_count);
+ fprintf(prof_fp, "return");
+ if (tree->lnode != NULL) {
+ fprintf(prof_fp, " ");
+ tree_eval(tree->lnode);
+ }
+ fprintf(prof_fp, "\n");
+ break;
+
+ default:
+ /*
+ * Appears to be an expression statement.
+ * Throw away the value.
+ */
+ if (in_expr)
+ tree_eval(tree);
+ else {
+ indent(tree->exec_count);
+ tree_eval(tree);
+ fprintf(prof_fp, "\n");
+ }
+ break;
+ }
+}
+
+/* varname --- print a variable name, handling vars done with -v */
+
+/*
+ * When `-v x=x' is given, the varname field ends up including the
+ * entire text. This gets printed in the profiled output if we're
+ * not careful. Oops.
+ *
+ * XXX: This is a band-aid; we really should fix the -v code.
+ */
+
+static void
+varname(const char *name)
+{
+ for (; *name != '\0' && *name != '='; name++)
+ putc(*name, prof_fp);
+ return;
+}
+
+/* tree_eval --- evaluate a subtree */
+
+static void
+tree_eval(register NODE *tree)
+{
+ if (tree == NULL)
+ return;
+
+ switch (tree->type) {
+ case Node_param_list:
+ fprintf(prof_fp, "%s", fparms[tree->param_cnt]);
+ return;
+
+ case Node_var_new:
+ case Node_var:
+ case Node_var_array:
+ if (tree->vname != NULL)
+ varname(tree->vname);
+ else
+ fatal(_("internal error: %s with null vname"),
+ nodetype2str(tree->type));
+ return;
+
+ case Node_val:
+ if ((tree->flags & NUMBER) != 0)
+ fprintf(prof_fp, "%g", tree->numbr);
+ else {
+ if ((tree->flags & INTLSTR) != 0)
+ fprintf(prof_fp, "_");
+ pp_string(tree->stptr, tree->stlen, '"');
+ }
+ return;
+
+ case Node_and:
+ eval_condition(tree->lnode);
+ fprintf(prof_fp, " && ");
+ eval_condition(tree->rnode);
+ return;
+
+ case Node_or:
+ eval_condition(tree->lnode);
+ fprintf(prof_fp, " || ");
+ eval_condition(tree->rnode);
+ return;
+
+ case Node_not:
+ fprintf(prof_fp, "! ");
+ parenthesize(tree->type, tree->lnode);
+ return;
+
+ /* Builtins */
+ case Node_builtin:
+ pp_builtin(tree);
+ return;
+
+ case Node_in_array:
+ in_expr++;
+ pp_in_array(tree->lnode, tree->rnode);
+ in_expr--;
+ return;
+
+ case Node_func_call:
+ pp_func_call(tree);
+ return;
+
+ case Node_K_getline:
+ pp_getline(tree);
+ return;
+
+ case Node_K_delete_loop:
+ {
+ char *aname;
+ NODE *t;
+
+ t = tree->lnode;
+ if (t->type == Node_param_list)
+ aname = fparms[t->param_cnt];
+ else
+ aname = t->vname;
+
+ fprintf(prof_fp, "for (");
+ pp_lhs(tree->rnode->lnode);
+ fprintf(prof_fp, " in %s) { %s %s'\n", aname,
+ _("# treated internally as `delete'"), aname);
+ indent_in();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "delete %s[", aname);
+ pp_lhs(tree->rnode->lnode);
+ fprintf(prof_fp, "]\n");
+ indent_out();
+ indent(SPACEOVER);
+ fprintf(prof_fp, "}");
+ }
+ return;
+
+ /* unary operations */
+ case Node_NR:
+ fprintf(prof_fp, "NR");
+ return;
+
+ case Node_FNR:
+ fprintf(prof_fp, "FNR");
+ return;
+
+ case Node_NF:
+ fprintf(prof_fp, "NF");
+ return;
+
+ case Node_FIELDWIDTHS:
+ fprintf(prof_fp, "FIELDWIDTHS");
+ return;
+
+ case Node_FS:
+ fprintf(prof_fp, "FS");
+ return;
+
+ case Node_RS:
+ fprintf(prof_fp, "RS");
+ return;
+
+ case Node_IGNORECASE:
+ fprintf(prof_fp, "IGNORECASE");
+ return;
+
+ case Node_OFS:
+ fprintf(prof_fp, "OFS");
+ return;
+
+ case Node_ORS:
+ fprintf(prof_fp, "ORS");
+ return;
+
+ case Node_OFMT:
+ fprintf(prof_fp, "OFMT");
+ return;
+
+ case Node_CONVFMT:
+ fprintf(prof_fp, "CONVFMT");
+ return;
+
+ case Node_BINMODE:
+ fprintf(prof_fp, "BINMODE");
+ return;
+
+ case Node_SUBSEP:
+ fprintf(prof_fp, "SUBSEP");
+ return;
+
+ case Node_TEXTDOMAIN:
+ fprintf(prof_fp, "TEXTDOMAIN");
+ return;
+
+ case Node_field_spec:
+ case Node_subscript:
+ pp_lhs(tree);
+ return;
+
+ case Node_unary_minus:
+ fprintf(prof_fp, " -");
+ if (is_scalar(tree->subnode->type))
+ tree_eval(tree->subnode);
+ else {
+ fprintf(prof_fp, "(");
+ tree_eval(tree->subnode);
+ fprintf(prof_fp, ")");
+ }
+ return;
+
+ case Node_cond_exp:
+ eval_condition(tree->lnode);
+ fprintf(prof_fp, " ? ");
+ tree_eval(tree->rnode->lnode);
+ fprintf(prof_fp, " : ");
+ tree_eval(tree->rnode->rnode);
+ return;
+
+ case Node_match:
+ case Node_nomatch:
+ case Node_regex:
+ case Node_dynregex:
+ pp_match_op(tree);
+ return;
+
+ /* assignments */
+ case Node_assign:
+ tree_eval(tree->lnode);
+ fprintf(prof_fp, " = ");
+ tree_eval(tree->rnode);
+ return;
+
+ case Node_assign_concat:
+ tree_eval(tree->lnode);
+ fprintf(prof_fp, " = ");
+ tree_eval(tree->lnode);
+ fprintf(prof_fp, " ");
+ tree_eval(tree->rnode);
+ return;
+
+ case Node_concat:
+ fprintf(prof_fp, "(");
+ tree_eval(tree->lnode);
+ fprintf(prof_fp, " ");
+ tree_eval(tree->rnode);
+ fprintf(prof_fp, ")");
+ return;
+
+ /* other assignment types are easier because they are numeric */
+ case Node_preincrement:
+ case Node_predecrement:
+ case Node_postincrement:
+ case Node_postdecrement:
+ case Node_assign_exp:
+ case Node_assign_times:
+ case Node_assign_quotient:
+ case Node_assign_mod:
+ case Node_assign_plus:
+ case Node_assign_minus:
+ pp_op_assign(tree);
+ return;
+
+ default:
+ break; /* handled below */
+ }
+
+ /* handle binary ops */
+ in_expr++;
+ parenthesize(tree->type, tree->lnode);
+
+ switch (tree->type) {
+ case Node_geq:
+ fprintf(prof_fp, " >= ");
+ break;
+ case Node_leq:
+ fprintf(prof_fp, " <= ");
+ break;
+ case Node_greater:
+ fprintf(prof_fp, " > ");
+ break;
+ case Node_less:
+ fprintf(prof_fp, " < ");
+ break;
+ case Node_notequal:
+ fprintf(prof_fp, " != ");
+ break;
+ case Node_equal:
+ fprintf(prof_fp, " == ");
+ break;
+ case Node_exp:
+ fprintf(prof_fp, " ^ ");
+ break;
+ case Node_times:
+ fprintf(prof_fp, " * ");
+ break;
+ case Node_quotient:
+ fprintf(prof_fp, " / ");
+ break;
+ case Node_mod:
+ fprintf(prof_fp, " %% ");
+ break;
+ case Node_plus:
+ fprintf(prof_fp, " + ");
+ break;
+ case Node_minus:
+ fprintf(prof_fp, " - ");
+ break;
+ default:
+ fatal(_("illegal type (%s) in tree_eval"), nodetype2str(tree->type));
+ }
+ parenthesize(tree->type, tree->rnode);
+ in_expr--;
+
+ return;
+}
+
+/* eval_condition --- is TREE true or false */
+
+static void
+eval_condition(register NODE *tree)
+{
+ if (tree == NULL) /* Null trees are the easiest kinds */
+ return;
+
+ if (tree->type == Node_line_range) {
+ /* /.../, /.../ */
+ eval_condition(tree->condpair->lnode);
+ fprintf(prof_fp,", ");
+ eval_condition(tree->condpair->rnode);
+ return;
+ }
+
+ /*
+ * Could just be J.random expression. in which case, null and 0 are
+ * false, anything else is true
+ */
+
+ tree_eval(tree);
+ return;
+}
+
+/* pp_op_assign --- do +=, -=, etc. */
+
+static void
+pp_op_assign(register NODE *tree)
+{
+ const char *op = NULL;
+ enum Order {
+ NA = 0,
+ PRE = 1,
+ POST = 2
+ } order = NA;
+
+ switch(tree->type) {
+ case Node_preincrement:
+ op = "++";
+ order = PRE;
+ break;
+
+ case Node_predecrement:
+ op = "--";
+ order = PRE;
+ break;
+
+ case Node_postincrement:
+ op = "++";
+ order = POST;
+ break;
+
+ case Node_postdecrement:
+ op = "--";
+ order = POST;
+ break;
+
+ default:
+ break; /* handled below */
+ }
+
+ if (order == PRE) {
+ fprintf(prof_fp, "%s", op);
+ pp_lhs(tree->lnode);
+ return;
+ } else if (order == POST) {
+ pp_lhs(tree->lnode);
+ fprintf(prof_fp, "%s", op);
+ return;
+ }
+
+ /* a binary op */
+ pp_lhs(tree->lnode);
+
+ switch(tree->type) {
+ case Node_assign_exp:
+ fprintf(prof_fp, " ^= ");
+ break;
+
+ case Node_assign_times:
+ fprintf(prof_fp, " *= ");
+ break;
+
+ case Node_assign_quotient:
+ fprintf(prof_fp, " /= ");
+ break;
+
+ case Node_assign_mod:
+ fprintf(prof_fp, " %%= ");
+ break;
+
+ case Node_assign_plus:
+ fprintf(prof_fp, " += ");
+ break;
+
+ case Node_assign_minus:
+ fprintf(prof_fp, " -= ");
+ break;
+
+ default:
+ cant_happen();
+ }
+
+ tree_eval(tree->rnode);
+}
+
+/* pp_lhs --- print the lhs */
+
+static void
+pp_lhs(register NODE *ptr)
+{
+ register NODE *n;
+
+ switch (ptr->type) {
+ case Node_var_array:
+ fatal(_("attempt to use array `%s' in a scalar context"),
+ ptr->vname);
+
+ case Node_var_new:
+ case Node_var:
+ fprintf(prof_fp, "%s", ptr->vname);
+ break;
+
+ case Node_FIELDWIDTHS:
+ fprintf(prof_fp, "FIELDWIDTHS");
+ break;
+
+ case Node_RS:
+ fprintf(prof_fp, "RS");
+ break;
+
+ case Node_FS:
+ fprintf(prof_fp, "FS");
+ break;
+
+ case Node_FNR:
+ fprintf(prof_fp, "FNR");
+ break;
+
+ case Node_NR:
+ fprintf(prof_fp, "NR");
+ break;
+
+ case Node_NF:
+ fprintf(prof_fp, "NF");
+ break;
+
+ case Node_IGNORECASE:
+ fprintf(prof_fp, "IGNORECASE");
+ break;
+
+ case Node_BINMODE:
+ fprintf(prof_fp, "BINMODE");
+ break;
+
+ case Node_LINT:
+ fprintf(prof_fp, "LINT");
+ break;
+
+ case Node_OFMT:
+ fprintf(prof_fp, "OFMT");
+ break;
+
+ case Node_CONVFMT:
+ fprintf(prof_fp, "CONVFMT");
+ break;
+
+ case Node_ORS:
+ fprintf(prof_fp, "ORS");
+ break;
+
+ case Node_OFS:
+ fprintf(prof_fp, "OFS");
+ break;
+
+ case Node_SUBSEP:
+ fprintf(prof_fp, "SUBSEP");
+ break;
+
+ case Node_TEXTDOMAIN:
+ fprintf(prof_fp, "TEXTDOMAIN");
+ break;
+
+ case Node_param_list:
+ fprintf(prof_fp, "%s", fparms[ptr->param_cnt]);
+ break;
+
+ case Node_field_spec:
+ fprintf(prof_fp, "$");
+ if (is_scalar(ptr->lnode->type))
+ tree_eval(ptr->lnode);
+ else {
+ fprintf(prof_fp, "(");
+ tree_eval(ptr->lnode);
+ fprintf(prof_fp, ")");
+ }
+ break;
+
+ case Node_subscript:
+ n = ptr->lnode;
+ if (n->type == Node_param_list) {
+ fprintf(prof_fp, "%s[", fparms[n->param_cnt]);
+ } else
+ fprintf(prof_fp, "%s[", n->vname);
+ if (ptr->rnode->type == Node_expression_list)
+ pp_list(ptr->rnode);
+ else
+ tree_eval(ptr->rnode);
+ fprintf(prof_fp, "]");
+ break;
+
+ case Node_builtin:
+ fatal(_("assignment is not allowed to result of builtin function"));
+
+ default:
+ cant_happen();
+ }
+}
+
+/* match_op --- do ~ and !~ */
+
+static void
+pp_match_op(register NODE *tree)
+{
+ register NODE *re;
+ const char *op;
+ const char *restr;
+ size_t relen;
+ NODE *text = NULL;
+
+ if (tree->type == Node_dynregex) {
+ tree_eval(tree->re_exp);
+ return;
+ }
+
+ if (tree->type == Node_regex) {
+ re = tree->re_exp;
+ restr = re->stptr;
+ relen = re->stlen;
+ pp_string(restr, relen, '/');
+ return;
+ }
+
+ /* at this point, have either ~ or !~ */
+
+ text = tree->lnode;
+ re = tree->rnode;
+
+ if (tree->type == Node_nomatch)
+ op = "!~";
+ else if (tree->type == Node_match)
+ op = "~";
+ else
+ op = "";
+
+ tree_eval(text);
+ fprintf(prof_fp, " %s ", op);
+ tree_eval(re);
+}
+
+/* pp_redir --- print a redirection */
+
+static void
+pp_redir(register NODE *tree, enum redir_placement dir)
+{
+ const char *op = "[BOGUS]"; /* should never be seen */
+
+ if (tree == NULL)
+ return;
+
+ switch (tree->type) {
+ case Node_redirect_output:
+ op = ">";
+ break;
+ case Node_redirect_append:
+ op = ">>";
+ break;
+ case Node_redirect_pipe:
+ op = "|";
+ break;
+ case Node_redirect_pipein:
+ op = "|";
+ break;
+ case Node_redirect_input:
+ op = "<";
+ break;
+ case Node_redirect_twoway:
+ op = "|&";
+ break;
+ default:
+ cant_happen();
+ }
+
+ if (dir == BEFORE) {
+ if (! is_scalar(tree->subnode->type)) {
+ fprintf(prof_fp, "(");
+ tree_eval(tree->subnode);
+ fprintf(prof_fp, ")");
+ } else
+ tree_eval(tree->subnode);
+ fprintf(prof_fp, " %s ", op);
+ } else {
+ fprintf(prof_fp, " %s ", op);
+ if (! is_scalar(tree->subnode->type)) {
+ fprintf(prof_fp, "(");
+ tree_eval(tree->subnode);
+ fprintf(prof_fp, ")");
+ } else
+ tree_eval(tree->subnode);
+ }
+}
+
+/* pp_list --- dump a list of arguments, without parens */
+
+static void
+pp_list(register NODE *tree)
+{
+ for (; tree != NULL; tree = tree->rnode) {
+ if (tree->type != Node_expression_list) {
+ fprintf(stderr, "pp_list: got %s\n",
+ nodetype2str(tree->type));
+ fflush(stderr);
+ }
+ assert(tree->type == Node_expression_list);
+ tree_eval(tree->lnode);
+ if (tree->rnode != NULL)
+ fprintf(prof_fp, ", ");
+ }
+}
+
+/* pp_print_stmt --- print a "print" or "printf" statement */
+
+static void
+pp_print_stmt(const char *command, register NODE *tree)
+{
+ NODE *redir = tree->rnode;
+
+ indent(tree->exec_count);
+ fprintf(prof_fp, "%s", command);
+ if (redir != NULL) {
+ if (tree->lnode != NULL) {
+ /* parenthesize if have a redirection and a list */
+ fprintf(prof_fp, "(");
+ pp_list(tree->lnode);
+ fprintf(prof_fp, ")");
+ } else
+ fprintf(prof_fp, " $0");
+ pp_redir(redir, AFTER);
+ } else {
+ fprintf(prof_fp, " ");
+ if (tree->lnode != NULL)
+ pp_list(tree->lnode);
+ else
+ fprintf(prof_fp, "$0");
+ }
+ fprintf(prof_fp, "\n");
+}
+
+/* pp_delete --- print a "delete" statement */
+
+static void
+pp_delete(register NODE *tree)
+{
+ NODE *array, *subscript;
+
+ array = tree->lnode;
+ subscript = tree->rnode;
+ indent(array->exec_count);
+ if (array->type == Node_param_list)
+ fprintf(prof_fp, "delete %s", fparms[array->param_cnt]);
+ else
+ fprintf(prof_fp, "delete %s", array->vname);
+ if (subscript != NULL) {
+ fprintf(prof_fp, "[");
+ pp_list(subscript);
+ fprintf(prof_fp, "]");
+ }
+ fprintf(prof_fp, "\n");
+}
+
+/* pp_in_array --- pretty print "foo in array" test */
+
+static void
+pp_in_array(NODE *array, NODE *subscript)
+{
+ if (subscript->type == Node_expression_list) {
+ fprintf(prof_fp, "(");
+ pp_list(subscript);
+ fprintf(prof_fp, ")");
+ } else
+ pprint(subscript);
+
+ if (array->type == Node_param_list)
+ fprintf(prof_fp, " in %s", fparms[array->param_cnt]);
+ else
+ fprintf(prof_fp, " in %s", array->vname);
+}
+
+/* pp_getline --- print a getline statement */
+
+static void
+pp_getline(register NODE *tree)
+{
+ NODE *redir = tree->rnode;
+ int before, after;
+
+ /*
+ * command | getline
+ * or
+ * command |& getline
+ * or
+ * getline < file
+ */
+ if (redir != NULL) {
+ before = (redir->type == Node_redirect_pipein
+ || redir->type == Node_redirect_twoway);
+ after = ! before;
+ } else
+ before = after = FALSE;
+
+ if (before)
+ pp_redir(redir, BEFORE);
+
+ fprintf(prof_fp, "getline");
+ if (tree->lnode != NULL) { /* optional var */
+ fprintf(prof_fp, " ");
+ pp_lhs(tree->lnode);
+ }
+
+ if (after)
+ pp_redir(redir, AFTER);
+}
+
+/* pp_builtin --- print a builtin function */
+
+static void
+pp_builtin(register NODE *tree)
+{
+ const char *func = getfname(tree->builtin);
+
+ if (func != NULL) {
+ fprintf(prof_fp, "%s(", func);
+ pp_list(tree->subnode);
+ fprintf(prof_fp, ")");
+ } else
+ fprintf(prof_fp, _("# this is a dynamically loaded extension function"));
+}
+
+/* pp_func_call --- print a function call */
+
+static void
+pp_func_call(NODE *tree)
+{
+ NODE *name, *arglist;
+
+ name = tree->rnode;
+ arglist = tree->lnode;
+ fprintf(prof_fp, "%s(", name->stptr);
+ pp_list(arglist);
+ fprintf(prof_fp, ")");
+}
+
+/* dump_prog --- dump the program */
+
+/*
+ * XXX: I am not sure it is right to have the strings in the dump
+ * be translated, but I'll leave it alone for now.
+ */
+
+void
+dump_prog(NODE *begin, NODE *prog, NODE *end)
+{
+ time_t now;
+
+ (void) time(& now);
+ /* \n on purpose, with \n in ctime() output */
+ fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now));
+
+ if (begin != NULL) {
+ fprintf(prof_fp, _("\t# BEGIN block(s)\n\n"));
+ fprintf(prof_fp, "\tBEGIN {\n");
+ in_BEGIN_or_END = TRUE;
+ pprint(begin);
+ in_BEGIN_or_END = FALSE;
+ fprintf(prof_fp, "\t}\n");
+ if (prog != NULL || end != NULL)
+ fprintf(prof_fp, "\n");
+ }
+ if (prog != NULL) {
+ fprintf(prof_fp, _("\t# Rule(s)\n\n"));
+ pprint(prog);
+ if (end != NULL)
+ fprintf(prof_fp, "\n");
+ }
+ if (end != NULL) {
+ fprintf(prof_fp, _("\t# END block(s)\n\n"));
+ fprintf(prof_fp, "\tEND {\n");
+ in_BEGIN_or_END = TRUE;
+ pprint(end);
+ in_BEGIN_or_END = FALSE;
+ fprintf(prof_fp, "\t}\n");
+ }
+}
+
+/* pp_func --- pretty print a function */
+
+void
+pp_func(const char *name, size_t namelen, NODE *f)
+{
+ int j;
+ char **pnames;
+ static int first = TRUE;
+
+ if (first) {
+ first = FALSE;
+ fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
+ }
+
+ fprintf(prof_fp, "\n");
+ indent(f->exec_count);
+ fprintf(prof_fp, "function %.*s(", (int) namelen, name);
+ pnames = f->parmlist;
+ fparms = pnames;
+ for (j = 0; j < f->lnode->param_cnt; j++) {
+ fprintf(prof_fp, "%s", pnames[j]);
+ if (j < f->lnode->param_cnt - 1)
+ fprintf(prof_fp, ", ");
+ }
+ fprintf(prof_fp, ")\n\t{\n");
+ indent_in();
+ pprint(f->rnode); /* body */
+ indent_out();
+ fprintf(prof_fp, "\t}\n");
+}
+
+/* pp_string --- pretty print a string or regex constant */
+
+static void
+pp_string(const char *str, size_t len, int delim)
+{
+ pp_string_fp(prof_fp, str, len, delim, FALSE);
+}
+
+/* pp_string_fp --- printy print a string to the fp */
+
+/*
+ * This routine concentrates string pretty printing in one place,
+ * so that it can be called from multiple places within gawk.
+ */
+
+void
+pp_string_fp(FILE *fp, const char *in_str, size_t len, int delim, int breaklines)
+{
+ static char escapes[] = "\b\f\n\r\t\v\\";
+ static char printables[] = "bfnrtv\\";
+ char *cp;
+ int i;
+ int count;
+#define BREAKPOINT 70 /* arbitrary */
+ const unsigned char *str = (const unsigned char *) in_str;
+
+ fprintf(fp, "%c", delim);
+ for (count = 0; len > 0; len--, str++) {
+ if (++count >= BREAKPOINT && breaklines) {
+ fprintf(fp, "%c\n%c", delim, delim);
+ count = 0;
+ }
+ if (*str == delim) {
+ fprintf(fp, "\\%c", delim);
+ count++;
+ } else if (*str == BELL) {
+ fprintf(fp, "\\a");
+ count++;
+ } else if ((cp = strchr(escapes, *str)) != NULL) {
+ i = cp - escapes;
+ putc('\\', fp);
+ count++;
+ putc(printables[i], fp);
+ if (breaklines && *str == '\n' && delim == '"') {
+ fprintf(fp, "\"\n\"");
+ count = 0;
+ }
+ /* NB: Deliberate use of lower-case versions. */
+ } else if (isascii(*str) && isprint(*str)) {
+ putc(*str, fp);
+ } else {
+ char buf[10];
+
+ /* print 'em as they came if for whiny users */
+ if (whiny_users)
+ sprintf(buf, "%c", *str & 0xff);
+ else
+ sprintf(buf, "\\%03o", *str & 0xff);
+ count += strlen(buf) - 1;
+ fprintf(fp, "%s", buf);
+ }
+ }
+ fprintf(fp, "%c", delim);
+}
+
+/* is_scalar --- true or false if we'll get a scalar value */
+
+static int
+is_scalar(NODETYPE type)
+{
+ switch (type) {
+ case Node_var_new:
+ case Node_var:
+ case Node_var_array:
+ case Node_val:
+ case Node_BINMODE:
+ case Node_CONVFMT:
+ case Node_FIELDWIDTHS:
+ case Node_FNR:
+ case Node_FS:
+ case Node_IGNORECASE:
+ case Node_LINT:
+ case Node_NF:
+ case Node_NR:
+ case Node_OFMT:
+ case Node_OFS:
+ case Node_ORS:
+ case Node_RS:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ case Node_subscript:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* prec_level --- return the precedence of an operator, for paren tests */
+
+static int
+prec_level(NODETYPE type)
+{
+ switch (type) {
+ case Node_var_new:
+ case Node_var:
+ case Node_var_array:
+ case Node_param_list:
+ case Node_subscript:
+ case Node_func_call:
+ case Node_K_delete_loop:
+ case Node_val:
+ case Node_builtin:
+ case Node_BINMODE:
+ case Node_CONVFMT:
+ case Node_FIELDWIDTHS:
+ case Node_FNR:
+ case Node_FS:
+ case Node_IGNORECASE:
+ case Node_LINT:
+ case Node_NF:
+ case Node_NR:
+ case Node_OFMT:
+ case Node_OFS:
+ case Node_ORS:
+ case Node_RS:
+ case Node_SUBSEP:
+ case Node_TEXTDOMAIN:
+ return 15;
+
+ case Node_field_spec:
+ return 14;
+
+ case Node_exp:
+ return 13;
+
+ case Node_preincrement:
+ case Node_predecrement:
+ case Node_postincrement:
+ case Node_postdecrement:
+ return 12;
+
+ case Node_unary_minus:
+ case Node_not:
+ return 11;
+
+ case Node_times:
+ case Node_quotient:
+ case Node_mod:
+ return 10;
+
+ case Node_plus:
+ case Node_minus:
+ return 9;
+
+ case Node_concat:
+ return 8;
+
+ case Node_equal:
+ case Node_notequal:
+ case Node_greater:
+ case Node_leq:
+ case Node_geq:
+ case Node_match:
+ case Node_nomatch:
+ return 7;
+
+ case Node_K_getline:
+ return 6;
+
+ case Node_less:
+ return 5;
+
+ case Node_in_array:
+ return 5;
+
+ case Node_and:
+ return 4;
+
+ case Node_or:
+ return 3;
+
+ case Node_cond_exp:
+ return 2;
+
+ case Node_assign:
+ case Node_assign_times:
+ case Node_assign_quotient:
+ case Node_assign_mod:
+ case Node_assign_plus:
+ case Node_assign_minus:
+ case Node_assign_exp:
+ case Node_assign_concat:
+ return 1;
+
+ default:
+ fatal(_("unexpected type %s in prec_level"), nodetype2str(type));
+ return 0; /* keep the compiler happy */
+ }
+}
+
+/* parenthesize --- print a subtree in parentheses if need be */
+
+static void
+parenthesize(NODETYPE parent_type, NODE *tree)
+{
+ NODETYPE child_type;
+
+ if (tree == NULL)
+ return;
+
+ child_type = tree->type;
+
+ in_expr++;
+ /* first the special cases, then the general ones */
+ if (parent_type == Node_not && child_type == Node_in_array) {
+ fprintf(prof_fp, "! (");
+ pp_in_array(tree->lnode, tree->rnode);
+ fprintf(prof_fp, ")");
+ /* other special cases here, as needed */
+ } else if (prec_level(child_type) < prec_level(parent_type)) {
+ fprintf(prof_fp, "(");
+ tree_eval(tree);
+ fprintf(prof_fp, ")");
+ } else
+ tree_eval(tree);
+ in_expr--;
+}
+
+#ifdef PROFILING
+/* just_dump --- dump the profile and function stack and keep going */
+
+static RETSIGTYPE
+just_dump(int signum)
+{
+ extern NODE *begin_block, *expression_value, *end_block;
+
+ dump_prog(begin_block, expression_value, end_block);
+ dump_funcs();
+ dump_fcall_stack(prof_fp);
+ fflush(prof_fp);
+ signal(signum, just_dump); /* for OLD Unix systems ... */
+}
+
+/* dump_and_exit --- dump the profile, the function stack, and exit */
+
+static RETSIGTYPE
+dump_and_exit(int signum)
+{
+ just_dump(signum);
+ exit(1);
+}
+#endif
--- /dev/null
+/*
+ * profile_p.c - compile profile.c with profiling turned on.
+ */
+
+/*
+ * Copyright (C) 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define PROFILING 1
+#include "profile.c"
--- /dev/null
+/*
+ * protos.h -- function prototypes for when the headers don't have them.
+ */
+
+/*
+ * Copyright (C) 1991 - 2002 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef __STDC__
+#define aptr_t void * /* arbitrary pointer type */
+#else
+#define aptr_t char *
+#endif
+extern aptr_t malloc P((MALLOC_ARG_T));
+extern aptr_t realloc P((aptr_t, MALLOC_ARG_T));
+extern aptr_t calloc P((MALLOC_ARG_T, MALLOC_ARG_T));
+
+extern void free P((aptr_t));
+extern char *getenv P((const char *));
+
+#if ! defined(HAVE_STRING_H) && ! defined(HAVE_STRINGS_H)
+extern char *strcpy P((char *, const char *));
+extern char *strcat P((char *, const char *));
+extern char *strncpy P((char *, const char *, size_t));
+extern int strcmp P((const char *, const char *));
+extern int strncmp P((const char *, const char *, size_t));
+extern char *strchr P((const char *, int));
+extern char *strrchr P((const char *, int));
+extern char *strstr P((const char *s1, const char *s2));
+extern size_t strlen P((const char *));
+extern long strtol P((const char *, char **, int));
+
+extern aptr_t memset P((aptr_t, int, size_t));
+extern aptr_t memcpy P((aptr_t, const aptr_t, size_t));
+extern aptr_t memmove P((aptr_t, const aptr_t, size_t));
+extern aptr_t memchr P((const aptr_t, int, size_t));
+extern int memcmp P((const aptr_t, const aptr_t, size_t));
+#endif /* ! defined(HAVE_STRING_H) && ! defined(HAVE_STRINGS_H) */
+
+#ifndef VMS
+extern char *strerror P((int));
+#else
+extern char *strerror P((int,...));
+#endif
+
+#if ! defined(_MSC_VER) && ! defined(__GNU_LIBRARY__)
+extern size_t strftime P((char *, size_t, const char *, const struct tm *));
+#endif
+#ifdef __STDC__
+extern time_t time P((time_t *));
+#else
+extern long time();
+#endif
+
+extern FILE *fdopen P((int, const char *));
+extern int fprintf P((FILE *, const char *, ...));
+#if ! defined(MSDOS) && ! defined(__GNU_LIBRARY__)
+#ifdef __STDC__
+extern size_t fwrite P((const aptr_t, size_t, size_t, FILE *));
+#else
+extern int fwrite();
+#endif
+extern int fputs P((const char *, FILE *));
+extern int unlink P((const char *));
+#endif
+extern int fflush P((FILE *));
+extern int fclose P((FILE *));
+extern FILE *popen P((const char *, const char *));
+extern int pclose P((FILE *));
+extern void abort P(());
+extern int isatty P((int));
+extern void exit P((int));
+extern int system P((const char *));
+extern int sscanf P((const char *, const char *, ...));
+#ifndef toupper
+extern int toupper P((int));
+#endif
+#ifndef tolower
+extern int tolower P((int));
+#endif
+
+extern double pow P((double x, double y));
+extern double atof P((const char *));
+extern double strtod P((const char *, char **));
+extern int fstat P((int, struct stat *));
+extern int stat P((const char *, struct stat *));
+extern off_t lseek P((int, off_t, int));
+extern int close P((int));
+extern int creat P((const char *, mode_t));
+extern int open P((const char *, int, ...));
+extern int pipe P((int *));
+extern int dup P((int));
+extern int dup2 P((int,int));
+extern int fork P(());
+extern int execl P((const char *, const char *, ...));
+#ifndef __STDC__
+extern int read P((int, void *, unsigned int));
+#endif
+#ifndef HAVE_SYS_WAIT_H
+extern int wait P((int *));
+#endif
+extern void _exit P((int));
+
+#ifndef __STDC__
+extern long time P((long *));
+#endif
+
+extern SPRINTF_RET sprintf P((char *, const char *, ...));
+
+#undef aptr_t
--- /dev/null
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef HAVE_CONFIG_H /* gawk addition */
+#include <config.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "random.h" /* gawk addition */
+
+#ifdef HAVE_SYS_TIME_H /* gawk addition */
+#include <sys/time.h>
+#endif
+
+#if 0
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/random.c,v 1.24 2004/01/20 03:02:18 das Exp $");
+
+#include "namespace.h"
+#include <sys/time.h> /* for srandomdev() */
+#include <fcntl.h> /* for srandomdev() */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> /* for srandomdev() */
+#include "un-namespace.h"
+#endif
+
+/*
+ * random.c:
+ *
+ * An improved random number generation package. In addition to the standard
+ * rand()/srand() like interface, this package also has a special state info
+ * interface. The initstate() routine is called with a seed, an array of
+ * bytes, and a count of how many bytes are being passed in; this array is
+ * then initialized to contain information for random number generation with
+ * that much state information. Good sizes for the amount of state
+ * information are 32, 64, 128, and 256 bytes. The state can be switched by
+ * calling the setstate() routine with the same array as was initiallized
+ * with initstate(). By default, the package runs with 128 bytes of state
+ * information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used.
+ *
+ * Internally, the state information is treated as an array of uint32_t's; the
+ * zeroeth element of the array is the type of R.N.G. being used (small
+ * integer); the remainder of the array is the state information for the
+ * R.N.G. Thus, 32 bytes of state information will give 7 ints worth of
+ * state information, which will allow a degree seven polynomial. (Note:
+ * the zeroeth word of state information also has some other information
+ * stored in it -- see setstate() for details).
+ *
+ * The random number generation technique is a linear feedback shift register
+ * approach, employing trinomials (since there are fewer terms to sum up that
+ * way). In this approach, the least significant bit of all the numbers in
+ * the state table will act as a linear feedback shift register, and will
+ * have period 2^deg - 1 (where deg is the degree of the polynomial being
+ * used, assuming that the polynomial is irreducible and primitive). The
+ * higher order bits will have longer periods, since their values are also
+ * influenced by pseudo-random carries out of the lower bits. The total
+ * period of the generator is approximately deg*(2**deg - 1); thus doubling
+ * the amount of state information has a vast influence on the period of the
+ * generator. Note: the deg*(2**deg - 1) is an approximation only good for
+ * large deg, when the period of the shift is the dominant factor.
+ * With deg equal to seven, the period is actually much longer than the
+ * 7*(2**7 - 1) predicted by this formula.
+ *
+ * Modified 28 December 1994 by Jacob S. Rosenberg.
+ * The following changes have been made:
+ * All references to the type u_int have been changed to unsigned long.
+ * All references to type int have been changed to type long. Other
+ * cleanups have been made as well. A warning for both initstate and
+ * setstate has been inserted to the effect that on Sparc platforms
+ * the 'arg_state' variable must be forced to begin on word boundaries.
+ * This can be easily done by casting a long integer array to char *.
+ * The overall logic has been left STRICTLY alone. This software was
+ * tested on both a VAX and Sun SpacsStation with exactly the same
+ * results. The new version and the original give IDENTICAL results.
+ * The new version is somewhat faster than the original. As the
+ * documentation says: "By default, the package runs with 128 bytes of
+ * state information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of
+ * 128 bytes, this new version runs about 19 percent faster and for a 16
+ * byte buffer it is about 5 percent faster.
+ */
+
+/*
+ * For each of the currently supported random number generators, we have a
+ * break value on the amount of state information (you need at least this
+ * many bytes of state info to support this random number generator), a degree
+ * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ * the separation between the two lower order coefficients of the trinomial.
+ */
+#define TYPE_0 0 /* linear congruential */
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+#define TYPE_1 1 /* x**7 + x**3 + 1 */
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+#define TYPE_2 2 /* x**15 + x + 1 */
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+#define TYPE_3 3 /* x**31 + x**3 + 1 */
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+#define TYPE_4 4 /* x**63 + x + 1 */
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+/*
+ * Array versions of the above information to make code run faster --
+ * relies on fact that TYPE_i == i.
+ */
+#define MAX_TYPES 5 /* max number of types above */
+
+#ifdef USE_WEAK_SEEDING
+#define NSHUFF 0
+#else /* !USE_WEAK_SEEDING */
+#define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */
+#endif /* !USE_WEAK_SEEDING */
+
+static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+/*
+ * Initially, everything is set up as if from:
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * Note that this initialization takes advantage of the fact that srandom()
+ * advances the front and rear pointers 10*rand_deg times, and hence the
+ * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ * element of the state information, which contains info about the current
+ * position of the rear pointer is just
+ *
+ * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
+ */
+
+static uint32_t randtbl[DEG_3 + 1] = {
+ TYPE_3,
+#ifdef USE_WEAK_SEEDING
+/* Historic implementation compatibility */
+/* The random sequences do not vary much with the seed */
+ 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
+ 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
+ 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
+ 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+ 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
+ 0x27fb47b9,
+#else /* !USE_WEAK_SEEDING */
+ 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
+ 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
+ 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
+ 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
+ 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
+ 0xf3bec5da
+#endif /* !USE_WEAK_SEEDING */
+};
+
+/*
+ * fptr and rptr are two pointers into the state info, a front and a rear
+ * pointer. These two pointers are always rand_sep places aparts, as they
+ * cycle cyclically through the state information. (Yes, this does mean we
+ * could get away with just one pointer, but the code for random() is more
+ * efficient this way). The pointers are left positioned as they would be
+ * from the call
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * (The position of the rear pointer, rptr, is really 0 (as explained above
+ * in the initialization of randtbl) because the state table pointer is set
+ * to point to randtbl[1] (as explained below).
+ */
+static uint32_t *fptr = &randtbl[SEP_3 + 1];
+static uint32_t *rptr = &randtbl[1];
+
+/*
+ * The following things are the pointer to the state information table, the
+ * type of the current generator, the degree of the current polynomial being
+ * used, and the separation between the two pointers. Note that for efficiency
+ * of random(), we remember the first location of the state information, not
+ * the zeroeth. Hence it is valid to access state[-1], which is used to
+ * store the type of the R.N.G. Also, we remember the last location, since
+ * this is more efficient than indexing every time to find the address of
+ * the last element to see if the front and rear pointers have wrapped.
+ */
+static uint32_t *state = &randtbl[1];
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+static uint32_t *end_ptr = &randtbl[DEG_3 + 1];
+
+static inline uint32_t good_rand(int32_t);
+
+static inline uint32_t good_rand (x)
+ int32_t x;
+{
+#ifdef USE_WEAK_SEEDING
+/*
+ * Historic implementation compatibility.
+ * The random sequences do not vary much with the seed,
+ * even with overflowing.
+ */
+ return (1103515245 * x + 12345);
+#else /* !USE_WEAK_SEEDING */
+/*
+ * Compute x = (7^5 * x) mod (2^31 - 1)
+ * wihout overflowing 31 bits:
+ * (2^31 - 1) = 127773 * (7^5) + 2836
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+ */
+ int32_t hi, lo;
+
+ /* Can't be initialized with 0, so use another value. */
+ if (x == 0)
+ x = 123459876;
+ hi = x / 127773;
+ lo = x % 127773;
+ x = 16807 * lo - 2836 * hi;
+ if (x < 0)
+ x += 0x7fffffff;
+ return (x);
+#endif /* !USE_WEAK_SEEDING */
+}
+
+/*
+ * srandom:
+ *
+ * Initialize the random number generator based on the given seed. If the
+ * type is the trivial no-state-information type, just remember the seed.
+ * Otherwise, initializes state[] based on the given "seed" via a linear
+ * congruential generator. Then, the pointers are set to known locations
+ * that are exactly rand_sep places apart. Lastly, it cycles the state
+ * information a given number of times to get rid of any initial dependencies
+ * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ * for default usage relies on values produced by this routine.
+ */
+void
+srandom(x)
+ unsigned long x;
+{
+ int i, lim;
+
+ state[0] = (uint32_t)x;
+ if (rand_type == TYPE_0)
+ lim = NSHUFF;
+ else {
+ for (i = 1; i < rand_deg; i++)
+ state[i] = good_rand(state[i - 1]);
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ lim = 10 * rand_deg;
+ }
+ for (i = 0; i < lim; i++)
+ (void)random();
+}
+
+#if 0 /* gawk doesn't use this */
+/*
+ * srandomdev:
+ *
+ * Many programs choose the seed value in a totally predictable manner.
+ * This often causes problems. We seed the generator using the much more
+ * secure random(4) interface. Note that this particular seeding
+ * procedure can generate states which are impossible to reproduce by
+ * calling srandom() with any value, since the succeeding terms in the
+ * state buffer are no longer derived from the LC algorithm applied to
+ * a fixed seed.
+ */
+void
+srandomdev()
+{
+ int fd, done;
+ size_t len;
+
+ if (rand_type == TYPE_0)
+ len = sizeof state[0];
+ else
+ len = rand_deg * sizeof state[0];
+
+ done = 0;
+ fd = open("/dev/random", O_RDONLY, 0);
+ if (fd >= 0) {
+ if (read(fd, (void *) state, len) == (ssize_t) len)
+ done = 1;
+ close(fd);
+ }
+
+ if (!done) {
+ struct timeval tv;
+ unsigned long junk;
+
+ gettimeofday(&tv, NULL);
+ srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+ return;
+ }
+
+ if (rand_type != TYPE_0) {
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ }
+}
+#endif
+
+/*
+ * initstate:
+ *
+ * Initialize the state information in the given array of n bytes for future
+ * random number generation. Based on the number of bytes we are given, and
+ * the break values for the different R.N.G.'s, we choose the best (largest)
+ * one we can and set things up for it. srandom() is then called to
+ * initialize the state information.
+ *
+ * Note that on return from srandom(), we set state[-1] to be the type
+ * multiplexed with the current value of the rear pointer; this is so
+ * successive calls to initstate() won't lose this information and will be
+ * able to restart with setstate().
+ *
+ * Note: the first thing we do is save the current state, if any, just like
+ * setstate() so that it doesn't matter when initstate is called.
+ *
+ * Returns a pointer to the old state.
+ *
+ * Note: The Sparc platform requires that arg_state begin on an int
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+initstate(seed, arg_state, n)
+ unsigned long seed; /* seed for R.N.G. */
+ char *arg_state; /* pointer to state array */
+ long n; /* # bytes of state info */
+{
+ char *ostate = (char *)(&state[-1]);
+ uint32_t *int_arg_state = (uint32_t *)arg_state;
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ if (n < BREAK_0) {
+ (void)fprintf(stderr,
+ "random: not enough state (%ld bytes); ignored.\n", n);
+ return(0);
+ }
+ if (n < BREAK_1) {
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ } else if (n < BREAK_2) {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ } else if (n < BREAK_3) {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ } else if (n < BREAK_4) {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ } else {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+ state = int_arg_state + 1; /* first location */
+ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
+ srandom(seed);
+ if (rand_type == TYPE_0)
+ int_arg_state[0] = rand_type;
+ else
+ int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
+ return(ostate);
+}
+
+/*
+ * setstate:
+ *
+ * Restore the state from the given state array.
+ *
+ * Note: it is important that we also remember the locations of the pointers
+ * in the current state information, and restore the locations of the pointers
+ * from the old state information. This is done by multiplexing the pointer
+ * location into the zeroeth word of the state information.
+ *
+ * Note that due to the order in which things are done, it is OK to call
+ * setstate() with the same state as the current state.
+ *
+ * Returns a pointer to the old state information.
+ *
+ * Note: The Sparc platform requires that arg_state begin on an int
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+setstate(arg_state)
+ char *arg_state; /* pointer to state array */
+{
+ uint32_t *new_state = (uint32_t *)arg_state;
+ uint32_t type = new_state[0] % MAX_TYPES;
+ uint32_t rear = new_state[0] / MAX_TYPES;
+ char *ostate = (char *)(&state[-1]);
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ switch(type) {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ default:
+ (void)fprintf(stderr,
+ "random: state info corrupted; not changed.\n");
+ }
+ state = new_state + 1;
+ if (rand_type != TYPE_0) {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ end_ptr = &state[rand_deg]; /* set end_ptr too */
+ return(ostate);
+}
+
+/*
+ * random:
+ *
+ * If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
+ * the same in all the other cases due to all the global variables that have
+ * been set up. The basic operation is to add the number at the rear pointer
+ * into the one at the front pointer. Then both pointers are advanced to
+ * the next location cyclically in the table. The value returned is the sum
+ * generated, reduced to 31 bits by throwing away the "least random" low bit.
+ *
+ * Note: the code takes advantage of the fact that both the front and
+ * rear pointers can't wrap on the same call by not testing the rear
+ * pointer if the front one has wrapped.
+ *
+ * Returns a 31-bit random number.
+ */
+long
+random()
+{
+ uint32_t i;
+ uint32_t *f, *r;
+
+ if (rand_type == TYPE_0) {
+ i = state[0];
+ state[0] = i = (good_rand(i)) & 0x7fffffff;
+ } else {
+ /*
+ * Use local variables rather than static variables for speed.
+ */
+ f = fptr; r = rptr;
+ *f += *r;
+ i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */
+ if (++f >= end_ptr) {
+ f = state;
+ ++r;
+ }
+ else if (++r >= end_ptr) {
+ r = state;
+ }
+
+ fptr = f; rptr = r;
+ }
+ return((long)i);
+}
--- /dev/null
+/*
+ * random.h - redefine name of random lib routines to avoid conflicts
+ */
+
+/*
+ * Copyright (C) 1996, 2001, 2004, 2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define initstate gawk_initstate
+#define setstate gawk_setstate
+#define random gawk_random
+#define srandom gawk_srandom
+
+#if SIZEOF_UNSIGNED_INT == 4
+typedef unsigned int gawk_uint32_t;
+typedef int gawk_int32_t;
+#else
+#if SIZEOF_UNSIGNED_LONG == 4
+typedef unsigned long gawk_uint32_t;
+typedef long gawk_int32_t;
+#endif
+#endif
+#define uint32_t gawk_uint32_t
+#define int32_t gawk_int32_t
+
+#ifdef __STDC__
+#undef __P
+#define __P(s) s
+#else
+#define __P(s) ()
+#endif
+
+extern long random __P((void));
--- /dev/null
+/*
+ * re.c - compile regular expressions.
+ */
+
+/*
+ * Copyright (C) 1991-2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "awk.h"
+
+static reg_syntax_t syn;
+
+/* make_regexp --- generate compiled regular expressions */
+
+Regexp *
+make_regexp(const char *s, size_t len, int ignorecase, int dfa)
+{
+ Regexp *rp;
+ const char *rerr;
+ const char *src = s;
+ char *temp;
+ const char *end = s + len;
+ register char *dest;
+ register int c, c2;
+ static short first = TRUE;
+ static short no_dfa = FALSE;
+ int has_anchor = FALSE;
+
+ /* The number of bytes in the current multibyte character.
+ It is 0, when the current character is a singlebyte character. */
+ size_t is_multibyte = 0;
+#ifdef MBS_SUPPORT
+ mbstate_t mbs;
+
+ if (gawk_mb_cur_max > 1)
+ memset(&mbs, 0, sizeof(mbstate_t)); /* Initialize. */
+#endif
+
+ if (first) {
+ first = FALSE;
+ no_dfa = (getenv("GAWK_NO_DFA") != NULL); /* for debugging and testing */
+ }
+
+ /* Handle escaped characters first. */
+
+ /*
+ * Build a copy of the string (in dest) with the
+ * escaped characters translated, and generate the regex
+ * from that.
+ */
+ emalloc(dest, char *, len + 2, "make_regexp");
+ temp = dest;
+
+ while (src < end) {
+#ifdef MBS_SUPPORT
+ if (gawk_mb_cur_max > 1 && ! is_multibyte) {
+ /* The previous byte is a singlebyte character, or last byte
+ of a multibyte character. We check the next character. */
+ is_multibyte = mbrlen(src, end - src, &mbs);
+ if ((is_multibyte == 1) || (is_multibyte == (size_t) -1)
+ || (is_multibyte == (size_t) -2 || (is_multibyte == 0))) {
+ /* We treat it as a singlebyte character. */
+ is_multibyte = 0;
+ }
+ }
+#endif
+
+ /* We skip multibyte character, since it must not be a special
+ character. */
+ if ((gawk_mb_cur_max == 1 || ! is_multibyte) &&
+ (*src == '\\')) {
+ c = *++src;
+ switch (c) {
+ case 'a':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case 'x':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ c2 = parse_escape(&src);
+ if (c2 < 0)
+ cant_happen();
+ /*
+ * Unix awk treats octal (and hex?) chars
+ * literally in re's, so escape regexp
+ * metacharacters.
+ */
+ if (do_traditional && ! do_posix && (ISDIGIT(c) || c == 'x')
+ && strchr("()|*+?.^$\\[]", c2) != NULL)
+ *dest++ = '\\';
+ *dest++ = (char) c2;
+ break;
+ case '8':
+ case '9': /* a\9b not valid */
+ *dest++ = c;
+ src++;
+ break;
+ case 'y': /* normally \b */
+ /* gnu regex op */
+ if (! do_traditional) {
+ *dest++ = '\\';
+ *dest++ = 'b';
+ src++;
+ break;
+ }
+ /* else, fall through */
+ default:
+ *dest++ = '\\';
+ *dest++ = (char) c;
+ src++;
+ break;
+ } /* switch */
+ } else {
+ c = *src;
+ if (c == '^' || c == '$')
+ has_anchor = TRUE;
+ *dest++ = *src++; /* not '\\' */
+ }
+ if (gawk_mb_cur_max > 1 && is_multibyte)
+ is_multibyte--;
+ } /* while */
+
+ *dest = '\0' ; /* Only necessary if we print dest ? */
+ emalloc(rp, Regexp *, sizeof(*rp), "make_regexp");
+ memset((char *) rp, 0, sizeof(*rp));
+ rp->pat.allocated = 0; /* regex will allocate the buffer */
+ emalloc(rp->pat.fastmap, char *, 256, "make_regexp");
+
+ /*
+ * Lo these many years ago, had I known what a P.I.T.A. IGNORECASE
+ * was going to turn out to be, I wouldn't have bothered with it.
+ *
+ * In the case where we have a multibyte character set, we have no
+ * choice but to use RE_ICASE, since the casetable is for single-byte
+ * character sets only.
+ *
+ * On the other hand, if we do have a single-byte character set,
+ * using the casetable should give a performance improvement, since
+ * it's computed only once, not each time a regex is compiled. We
+ * also think it's probably better for portability. See the
+ * discussion by the definition of casetable[] in eval.c.
+ */
+
+ if (ignorecase) {
+ if (gawk_mb_cur_max > 1) {
+ syn |= RE_ICASE;
+ rp->pat.translate = NULL;
+ } else {
+ syn &= ~RE_ICASE;
+ rp->pat.translate = (char *) casetable;
+ }
+ } else {
+ rp->pat.translate = NULL;
+ syn &= ~RE_ICASE;
+ }
+
+ dfasyntax(syn | (ignorecase ? RE_ICASE : 0), ignorecase ? TRUE : FALSE, '\n');
+ re_set_syntax(syn);
+
+ len = dest - temp;
+ if ((rerr = re_compile_pattern(temp, len, &(rp->pat))) != NULL)
+ fatal("%s: /%s/", rerr, temp); /* rerr already gettextized inside regex routines */
+
+ /* gack. this must be done *after* re_compile_pattern */
+ rp->pat.newline_anchor = FALSE; /* don't get \n in middle of string */
+ if (dfa && ! no_dfa) {
+ dfacomp(temp, len, &(rp->dfareg), TRUE);
+ rp->dfa = TRUE;
+ } else
+ rp->dfa = FALSE;
+ rp->has_anchor = has_anchor;
+
+ free(temp);
+ return rp;
+}
+
+/* research --- do a regexp search. use dfa if possible */
+
+int
+research(Regexp *rp, register char *str, int start,
+ register size_t len, int flags)
+{
+ const char *ret = str;
+ int try_backref;
+ int need_start;
+ int no_bol;
+ int res;
+
+ need_start = ((flags & RE_NEED_START) != 0);
+ no_bol = ((flags & RE_NO_BOL) != 0);
+
+ if (no_bol)
+ rp->pat.not_bol = 1;
+
+ /*
+ * Always do dfa search if can; if it fails, then even if
+ * need_start is true, we won't bother with the regex search.
+ *
+ * The dfa matcher doesn't have a no_bol flag, so don't bother
+ * trying it in that case.
+ */
+ if (rp->dfa && ! no_bol) {
+ char save;
+ int count = 0;
+ /*
+ * dfa likes to stick a '\n' right after the matched
+ * text. So we just save and restore the character.
+ */
+ save = str[start+len];
+ ret = dfaexec(&(rp->dfareg), str+start, str+start+len, TRUE,
+ &count, &try_backref);
+ str[start+len] = save;
+ }
+
+ if (ret) {
+ if (need_start || rp->dfa == FALSE || try_backref) {
+ /*
+ * Passing NULL as last arg speeds up search for cases
+ * where we don't need the start/end info.
+ */
+ res = re_search(&(rp->pat), str, start+len,
+ start, len, need_start ? &(rp->regs) : NULL);
+ } else
+ res = 1;
+ } else
+ res = -1;
+
+ rp->pat.not_bol = 0;
+ return res;
+}
+
+/* refree --- free up the dynamic memory used by a compiled regexp */
+
+void
+refree(Regexp *rp)
+{
+ /*
+ * This isn't malloced, don't let regfree free it.
+ * (This is strictly necessary only for the old
+ * version of regex, but it's a good idea to keep it
+ * here in case regex internals change in the future.)
+ */
+ rp->pat.translate = NULL;
+
+ regfree(& rp->pat);
+ if (rp->regs.start)
+ free(rp->regs.start);
+ if (rp->regs.end)
+ free(rp->regs.end);
+ if (rp->dfa)
+ dfafree(&(rp->dfareg));
+ free(rp);
+}
+
+/* dfaerror --- print an error message for the dfa routines */
+
+void
+dfaerror(const char *s)
+{
+ fatal("%s", s);
+}
+
+/* re_update --- recompile a dynamic regexp */
+
+Regexp *
+re_update(NODE *t)
+{
+ NODE *t1;
+
+ if ((t->re_flags & CASE) == IGNORECASE) {
+ if ((t->re_flags & CONST) != 0) {
+ assert(t->type == Node_regex);
+ return t->re_reg;
+ }
+ t1 = force_string(tree_eval(t->re_exp));
+ if (t->re_text != NULL) {
+ if (cmp_nodes(t->re_text, t1) == 0) {
+ free_temp(t1);
+ return t->re_reg;
+ }
+ unref(t->re_text);
+ }
+ t->re_text = dupnode(t1);
+ free_temp(t1);
+ }
+ if (t->re_reg != NULL)
+ refree(t->re_reg);
+ if (t->re_cnt > 0)
+ t->re_cnt++;
+ if (t->re_cnt > 10)
+ t->re_cnt = 0;
+ if (t->re_text == NULL || (t->re_flags & CASE) != IGNORECASE) {
+ t1 = force_string(tree_eval(t->re_exp));
+ unref(t->re_text);
+ t->re_text = dupnode(t1);
+ free_temp(t1);
+ }
+ t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen,
+ IGNORECASE, t->re_cnt);
+ t->re_flags &= ~CASE;
+ t->re_flags |= IGNORECASE;
+ return t->re_reg;
+}
+
+/* resetup --- choose what kind of regexps we match */
+
+void
+resetup()
+{
+ if (do_posix)
+ syn = RE_SYNTAX_POSIX_AWK; /* strict POSIX re's */
+ else if (do_traditional)
+ syn = RE_SYNTAX_AWK; /* traditional Unix awk re's */
+ else
+ syn = RE_SYNTAX_GNU_AWK; /* POSIX re's + GNU ops */
+
+ /*
+ * Interval expressions are off by default, since it's likely to
+ * break too many old programs to have them on.
+ */
+ if (do_intervals)
+ syn |= RE_INTERVALS;
+
+ (void) re_set_syntax(syn);
+ dfasyntax(syn, FALSE, '\n');
+}
+
+/* avoid_dfa --- FIXME: temporary kludge function until we have a new dfa.c */
+
+int
+avoid_dfa(NODE *re, char *str, size_t len)
+{
+ char *end;
+
+ if (! re->re_reg->has_anchor)
+ return FALSE;
+
+ for (end = str + len; str < end; str++)
+ if (*str == '\n')
+ return TRUE;
+
+ return FALSE;
+}
+
+/* reisstring --- return TRUE if the RE match is a simple string match */
+
+int
+reisstring(const char *text, size_t len, Regexp *re, const char *buf)
+{
+ static char metas[] = ".*+(){}[]|?^$\\";
+ int i;
+ int res;
+ const char *matched;
+
+ /* simple checking for has meta characters in re */
+ for (i = 0; i < len; i++) {
+ if (strchr(metas, text[i]) != NULL) {
+ return FALSE; /* give up early, can't be string match */
+ }
+ }
+
+ /* make accessable to gdb */
+ matched = &buf[RESTART(re, buf)];
+
+ res = (memcmp(text, matched, len) == 0);
+
+ return res;
+}
+
+/* remaybelong --- return TRUE if the RE contains * ? | + */
+
+int
+remaybelong(const char *text, size_t len)
+{
+ while (len--) {
+ if (strchr("*+|?", *text++) != NULL) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* reflags2str --- make a regex flags value readable */
+
+const char *
+reflags2str(int flagval)
+{
+ static const struct flagtab values[] = {
+ { RE_BACKSLASH_ESCAPE_IN_LISTS, "RE_BACKSLASH_ESCAPE_IN_LISTS" },
+ { RE_BK_PLUS_QM, "RE_BK_PLUS_QM" },
+ { RE_CHAR_CLASSES, "RE_CHAR_CLASSES" },
+ { RE_CONTEXT_INDEP_ANCHORS, "RE_CONTEXT_INDEP_ANCHORS" },
+ { RE_CONTEXT_INDEP_OPS, "RE_CONTEXT_INDEP_OPS" },
+ { RE_CONTEXT_INVALID_OPS, "RE_CONTEXT_INVALID_OPS" },
+ { RE_DOT_NEWLINE, "RE_DOT_NEWLINE" },
+ { RE_DOT_NOT_NULL, "RE_DOT_NOT_NULL" },
+ { RE_HAT_LISTS_NOT_NEWLINE, "RE_HAT_LISTS_NOT_NEWLINE" },
+ { RE_INTERVALS, "RE_INTERVALS" },
+ { RE_LIMITED_OPS, "RE_LIMITED_OPS" },
+ { RE_NEWLINE_ALT, "RE_NEWLINE_ALT" },
+ { RE_NO_BK_BRACES, "RE_NO_BK_BRACES" },
+ { RE_NO_BK_PARENS, "RE_NO_BK_PARENS" },
+ { RE_NO_BK_REFS, "RE_NO_BK_REFS" },
+ { RE_NO_BK_VBAR, "RE_NO_BK_VBAR" },
+ { RE_NO_EMPTY_RANGES, "RE_NO_EMPTY_RANGES" },
+ { RE_UNMATCHED_RIGHT_PAREN_ORD, "RE_UNMATCHED_RIGHT_PAREN_ORD" },
+ { RE_NO_POSIX_BACKTRACKING, "RE_NO_POSIX_BACKTRACKING" },
+ { RE_NO_GNU_OPS, "RE_NO_GNU_OPS" },
+ { RE_DEBUG, "RE_DEBUG" },
+ { RE_INVALID_INTERVAL_ORD, "RE_INVALID_INTERVAL_ORD" },
+ { RE_ICASE, "RE_ICASE" },
+ { RE_CARET_ANCHORS_HERE, "RE_CARET_ANCHORS_HERE" },
+ { RE_CONTEXT_INVALID_DUP, "RE_CONTEXT_INVALID_DUP" },
+ { RE_NO_SUB, "RE_NO_SUB" },
+ { 0, NULL },
+ };
+
+ return genflags2str(flagval, values);
+}
--- /dev/null
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+ int length, reg_syntax_t syntax);
+static void re_compile_fastmap_iter (regex_t *bufp,
+ const re_dfastate_t *init_state,
+ char *fastmap);
+static reg_errcode_t init_dfa (re_dfa_t *dfa, int pat_len);
+static void init_word_char (re_dfa_t *dfa);
+#ifdef RE_ENABLE_I18N
+static void free_charset (re_charset_t *cset);
+#endif /* RE_ENABLE_I18N */
+static void free_workarea_compile (regex_t *preg);
+static reg_errcode_t create_initial_state (re_dfa_t *dfa);
+#ifdef RE_ENABLE_I18N
+static void optimize_utf8 (re_dfa_t *dfa);
+#endif
+static reg_errcode_t analyze (regex_t *preg);
+static reg_errcode_t create_initial_state (re_dfa_t *dfa);
+static reg_errcode_t preorder (bin_tree_t *root,
+ reg_errcode_t (fn (void *, bin_tree_t *)),
+ void *extra);
+static reg_errcode_t postorder (bin_tree_t *root,
+ reg_errcode_t (fn (void *, bin_tree_t *)),
+ void *extra);
+static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);
+static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);
+static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
+ bin_tree_t *node);
+static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
+static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
+static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
+static reg_errcode_t duplicate_node_closure (re_dfa_t *dfa, int top_org_node,
+ int top_clone_node, int root_node,
+ unsigned int constraint);
+static reg_errcode_t duplicate_node (int *new_idx, re_dfa_t *dfa, int org_idx,
+ unsigned int constraint);
+static int search_duplicated_node (re_dfa_t *dfa, int org_node,
+ unsigned int constraint);
+static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
+static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
+ int node, int root);
+static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
+static int fetch_number (re_string_t *input, re_token_t *token,
+ reg_syntax_t syntax);
+static void fetch_token (re_token_t *result, re_string_t *input,
+ reg_syntax_t syntax);
+static int peek_token (re_token_t *token, re_string_t *input,
+ reg_syntax_t syntax);
+static int peek_token_bracket (re_token_t *token, re_string_t *input,
+ reg_syntax_t syntax);
+static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
+ reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
+ re_token_t *token, reg_syntax_t syntax,
+ int nest, reg_errcode_t *err);
+static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
+ re_token_t *token, reg_syntax_t syntax,
+ int nest, reg_errcode_t *err);
+static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
+ re_token_t *token, reg_syntax_t syntax,
+ int nest, reg_errcode_t *err);
+static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
+ re_token_t *token, reg_syntax_t syntax,
+ int nest, reg_errcode_t *err);
+static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
+ re_dfa_t *dfa, re_token_t *token,
+ reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
+ re_token_t *token, reg_syntax_t syntax,
+ reg_errcode_t *err);
+static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
+ re_string_t *regexp,
+ re_token_t *token, int token_len,
+ re_dfa_t *dfa,
+ reg_syntax_t syntax,
+ int accept_hyphen);
+static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
+ re_string_t *regexp,
+ re_token_t *token);
+#ifndef _LIBC
+# ifdef RE_ENABLE_I18N
+static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,
+ re_charset_t *mbcset, int *range_alloc,
+ bracket_elem_t *start_elem,
+ bracket_elem_t *end_elem);
+static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,
+ re_charset_t *mbcset,
+ int *coll_sym_alloc,
+ const unsigned char *name);
+# else /* not RE_ENABLE_I18N */
+static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,
+ bracket_elem_t *start_elem,
+ bracket_elem_t *end_elem);
+static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,
+ const unsigned char *name);
+# endif /* not RE_ENABLE_I18N */
+#endif /* not _LIBC */
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
+ re_charset_t *mbcset,
+ int *equiv_class_alloc,
+ const unsigned char *name);
+static reg_errcode_t build_charclass (unsigned RE_TRANSLATE_TYPE trans,
+ re_bitset_ptr_t sbcset,
+ re_charset_t *mbcset,
+ int *char_class_alloc,
+ const char *class_name,
+ reg_syntax_t syntax);
+#else /* not RE_ENABLE_I18N */
+static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
+ const unsigned char *name);
+static reg_errcode_t build_charclass (unsigned RE_TRANSLATE_TYPE trans,
+ re_bitset_ptr_t sbcset,
+ const char *class_name,
+ reg_syntax_t syntax);
+#endif /* not RE_ENABLE_I18N */
+static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
+ unsigned RE_TRANSLATE_TYPE trans,
+ const char *class_name,
+ const char *extra,
+ int non_match, reg_errcode_t *err);
+static bin_tree_t *create_tree (re_dfa_t *dfa,
+ bin_tree_t *left, bin_tree_t *right,
+ re_token_type_t type);
+static bin_tree_t *create_token_tree (re_dfa_t *dfa,
+ bin_tree_t *left, bin_tree_t *right,
+ const re_token_t *token);
+static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
+static void free_token (re_token_t *node);
+static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
+static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
+\f
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there.
+ POSIX doesn't require that we do anything for REG_NOERROR,
+ but why not be nice? */
+
+const ERRMSG_TYPE __re_error_msgid[] attribute_hidden =
+ {
+#define REG_NOERROR_IDX 0
+ gettext_noop ("Success") /* REG_NOERROR */
+ ERRMSG_SEPARATOR
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+ gettext_noop ("No match") /* REG_NOMATCH */
+ ERRMSG_SEPARATOR
+#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match")
+ gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+ ERRMSG_SEPARATOR
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+ gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+ ERRMSG_SEPARATOR
+#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+ gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+ ERRMSG_SEPARATOR
+#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name")
+ gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+ ERRMSG_SEPARATOR
+#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash")
+ gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+ ERRMSG_SEPARATOR
+#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
+ gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
+ ERRMSG_SEPARATOR
+#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+ gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+ ERRMSG_SEPARATOR
+#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+ gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+ ERRMSG_SEPARATOR
+#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{")
+ gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+ ERRMSG_SEPARATOR
+#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+ gettext_noop ("Invalid range end") /* REG_ERANGE */
+ ERRMSG_SEPARATOR
+#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end")
+ gettext_noop ("Memory exhausted") /* REG_ESPACE */
+ ERRMSG_SEPARATOR
+#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted")
+ gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+ ERRMSG_SEPARATOR
+#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+ gettext_noop ("Premature end of regular expression") /* REG_EEND */
+ ERRMSG_SEPARATOR
+#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression")
+ gettext_noop ("Regular expression too big") /* REG_ESIZE */
+ ERRMSG_SEPARATOR
+#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big")
+ gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+ ERRMSG_SEPARATOR
+ };
+
+const size_t __re_error_msgid_idx[] attribute_hidden =
+ {
+ REG_NOERROR_IDX,
+ REG_NOMATCH_IDX,
+ REG_BADPAT_IDX,
+ REG_ECOLLATE_IDX,
+ REG_ECTYPE_IDX,
+ REG_EESCAPE_IDX,
+ REG_ESUBREG_IDX,
+ REG_EBRACK_IDX,
+ REG_EPAREN_IDX,
+ REG_EBRACE_IDX,
+ REG_BADBR_IDX,
+ REG_ERANGE_IDX,
+ REG_ESPACE_IDX,
+ REG_BADRPT_IDX,
+ REG_EEND_IDX,
+ REG_ESIZE_IDX,
+ REG_ERPAREN_IDX
+ };
+\f
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length LENGTH) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ size_t length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub, unless RE_NO_SUB is set. */
+ bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
+
+ if (!ret)
+ return NULL;
+ return gettext (RE_ERRMSG(ret));
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+/* This has no initializer because initialized variables in Emacs
+ become read-only after dumping. */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+ return ret;
+}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+ char *fastmap = bufp->fastmap;
+
+ memset (fastmap, '\0', sizeof (char) * SBC_MAX);
+ re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
+ if (dfa->init_state != dfa->init_state_word)
+ re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
+ if (dfa->init_state != dfa->init_state_nl)
+ re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
+ if (dfa->init_state != dfa->init_state_begbuf)
+ re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
+ bufp->fastmap_accurate = 1;
+ return 0;
+}
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+static inline void
+__attribute ((always_inline))
+re_set_fastmap (char *fastmap, int icase, int ch)
+{
+ fastmap[ch] = 1;
+ if (icase)
+ fastmap[tolower (ch)] = 1;
+}
+
+/* Helper function for re_compile_fastmap.
+ Compile fastmap for the initial_state INIT_STATE. */
+
+static void
+re_compile_fastmap_iter (bufp, init_state, fastmap)
+ regex_t *bufp;
+ const re_dfastate_t *init_state;
+ char *fastmap;
+{
+ re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+ int node_cnt;
+ int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+ for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+ {
+ int node = init_state->nodes.elems[node_cnt];
+ re_token_type_t type = dfa->nodes[node].type;
+
+ if (type == CHARACTER)
+ {
+ re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+#ifdef RE_ENABLE_I18N
+ if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+ {
+ unsigned char *buf = re_malloc (unsigned char, dfa->mb_cur_max), *p;
+ wchar_t wc;
+ mbstate_t state;
+
+ p = buf;
+ *p++ = dfa->nodes[node].opr.c;
+ while (++node < dfa->nodes_len
+ && dfa->nodes[node].type == CHARACTER
+ && dfa->nodes[node].mb_partial)
+ *p++ = dfa->nodes[node].opr.c;
+ memset (&state, 0, sizeof (state));
+ if (mbrtowc (&wc, (const char *) buf, p - buf,
+ &state) == p - buf
+ && __wcrtomb ((char *) buf, towlower (wc), &state) > 0)
+ re_set_fastmap (fastmap, 0, buf[0]);
+ re_free (buf);
+ }
+#endif
+ }
+ else if (type == SIMPLE_BRACKET)
+ {
+ int i, j, ch;
+ for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
+ for (j = 0; j < UINT_BITS; ++j, ++ch)
+ if (dfa->nodes[node].opr.sbcset[i] & (1 << j))
+ re_set_fastmap (fastmap, icase, ch);
+ }
+#ifdef RE_ENABLE_I18N
+ else if (type == COMPLEX_BRACKET)
+ {
+ int i;
+ re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+ if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
+ || cset->nranges || cset->nchar_classes)
+ {
+# ifdef _LIBC
+ if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0)
+ {
+ /* In this case we want to catch the bytes which are
+ the first byte of any collation elements.
+ e.g. In da_DK, we want to catch 'a' since "aa"
+ is a valid collation element, and don't catch
+ 'b' since 'b' is the only collation element
+ which starts from 'b'. */
+ int j, ch;
+ const int32_t *table = (const int32_t *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+ for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
+ for (j = 0; j < UINT_BITS; ++j, ++ch)
+ if (table[ch] < 0)
+ re_set_fastmap (fastmap, icase, ch);
+ }
+# else
+ if (dfa->mb_cur_max > 1)
+ for (i = 0; i < SBC_MAX; ++i)
+ if (__btowc (i) == WEOF)
+ re_set_fastmap (fastmap, icase, i);
+# endif /* not _LIBC */
+ }
+ for (i = 0; i < cset->nmbchars; ++i)
+ {
+ char buf[256];
+ mbstate_t state;
+ memset (&state, '\0', sizeof (state));
+ __wcrtomb (buf, cset->mbchars[i], &state);
+ re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+ if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+ {
+ __wcrtomb (buf, towlower (cset->mbchars[i]), &state);
+ re_set_fastmap (fastmap, 0, *(unsigned char *) buf);
+ }
+ }
+ }
+#endif /* RE_ENABLE_I18N */
+ else if (type == OP_PERIOD
+#ifdef RE_ENABLE_I18N
+ || type == OP_UTF8_PERIOD
+#endif /* RE_ENABLE_I18N */
+ || type == END_OF_RE)
+ {
+ memset (fastmap, '\1', sizeof (char) * SBC_MAX);
+ if (type == END_OF_RE)
+ bufp->can_be_null = 1;
+ return;
+ }
+ }
+}
+\f
+/* Entry point for POSIX code. */
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' to an allocated space for the fastmap;
+ `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *__restrict preg;
+ const char *__restrict pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
+ : RE_SYNTAX_POSIX_BASIC);
+
+ preg->buffer = NULL;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Try to allocate space for the fastmap. */
+ preg->fastmap = re_malloc (char, SBC_MAX);
+ if (BE (preg->fastmap == NULL, 0))
+ return REG_ESPACE;
+
+ syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+ preg->no_sub = !!(cflags & REG_NOSUB);
+ preg->translate = NULL;
+
+ ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN)
+ ret = REG_EPAREN;
+
+ /* We have already checked preg->fastmap != NULL. */
+ if (BE (ret == REG_NOERROR, 1))
+ /* Compute the fastmap now, since regexec cannot modify the pattern
+ buffer. This function never fails in this implementation. */
+ (void) re_compile_fastmap (preg);
+ else
+ {
+ /* Some error occurred while compiling the expression. */
+ re_free (preg->fastmap);
+ preg->fastmap = NULL;
+ }
+
+ return (int) ret;
+}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (BE (errcode < 0
+ || errcode >= (int) (sizeof (__re_error_msgid_idx)
+ / sizeof (__re_error_msgid_idx[0])), 0))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = gettext (RE_ERRMSG(errcode));
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (BE (errbuf_size != 0, 1))
+ {
+ if (BE (msg_size > errbuf_size, 0))
+ {
+ memcpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+ }
+ else
+ memcpy (errbuf, msg, msg_size);
+ }
+
+ return msg_size;
+}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
+
+#ifdef RE_ENABLE_I18N
+/* This static array is used for the map to single-byte characters when
+ UTF-8 is used. Otherwise we would allocate memory just to initialize
+ it the same all the time. UTF-8 is the preferred encoding so this is
+ a worthwhile optimization. */
+static const bitset utf8_sb_map =
+{
+ /* Set the first 128 bits. */
+# if UINT_MAX == 0xffffffff
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
+# else
+# error "Add case for new unsigned int size"
+# endif
+};
+#endif
+
+
+static void
+free_dfa_content (re_dfa_t *dfa)
+{
+ int i, j;
+
+ if (dfa->nodes)
+ for (i = 0; i < dfa->nodes_len; ++i)
+ free_token (dfa->nodes + i);
+ re_free (dfa->nexts);
+ for (i = 0; i < dfa->nodes_len; ++i)
+ {
+ if (dfa->eclosures != NULL)
+ re_node_set_free (dfa->eclosures + i);
+ if (dfa->inveclosures != NULL)
+ re_node_set_free (dfa->inveclosures + i);
+ if (dfa->edests != NULL)
+ re_node_set_free (dfa->edests + i);
+ }
+ re_free (dfa->edests);
+ re_free (dfa->eclosures);
+ re_free (dfa->inveclosures);
+ re_free (dfa->nodes);
+
+ if (dfa->state_table)
+ for (i = 0; i <= dfa->state_hash_mask; ++i)
+ {
+ struct re_state_table_entry *entry = dfa->state_table + i;
+ for (j = 0; j < entry->num; ++j)
+ {
+ re_dfastate_t *state = entry->array[j];
+ free_state (state);
+ }
+ re_free (entry->array);
+ }
+ re_free (dfa->state_table);
+#ifdef RE_ENABLE_I18N
+ if (dfa->sb_char != utf8_sb_map)
+ re_free (dfa->sb_char);
+#endif
+ re_free (dfa->subexp_map);
+#ifdef DEBUG
+ re_free (dfa->re_str);
+#endif
+
+ re_free (dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ if (BE (dfa != NULL, 1))
+ free_dfa_content (dfa);
+ preg->buffer = NULL;
+ preg->allocated = 0;
+
+ re_free (preg->fastmap);
+ preg->fastmap = NULL;
+
+ re_free (preg->translate);
+ preg->translate = NULL;
+}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
+\f
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them unless specifically requested. */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+# ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec above without link errors. */
+weak_function
+# endif
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+ char *fastmap;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return gettext ("No previous regular expression");
+ return 0;
+ }
+
+ if (re_comp_buf.buffer)
+ {
+ fastmap = re_comp_buf.fastmap;
+ re_comp_buf.fastmap = NULL;
+ __regfree (&re_comp_buf);
+ memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
+ re_comp_buf.fastmap = fastmap;
+ }
+
+ if (re_comp_buf.fastmap == NULL)
+ {
+ re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
+ if (re_comp_buf.fastmap == NULL)
+ return (char *) gettext (RE_ERRMSG(REG_ESPACE_IDX));
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
+
+ if (!ret)
+ return NULL;
+
+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (RE_ERRMSG(ret));
+}
+
+#ifdef _LIBC
+libc_freeres_fn (free_mem)
+{
+ __regfree (&re_comp_buf);
+}
+#endif
+
+#endif /* _REGEX_RE_COMP */
+\f
+/* Internal entry point.
+ Compile the regular expression PATTERN, whose length is LENGTH.
+ SYNTAX indicate regular expression's syntax. */
+
+static reg_errcode_t
+re_compile_internal (preg, pattern, length, syntax)
+ regex_t *preg;
+ const char * pattern;
+ int length;
+ reg_syntax_t syntax;
+{
+ reg_errcode_t err = REG_NOERROR;
+ re_dfa_t *dfa;
+ re_string_t regexp;
+
+ /* Initialize the pattern buffer. */
+ preg->fastmap_accurate = 0;
+ preg->syntax = syntax;
+ preg->not_bol = preg->not_eol = 0;
+ preg->used = 0;
+ preg->re_nsub = 0;
+ preg->can_be_null = 0;
+ preg->regs_allocated = REGS_UNALLOCATED;
+
+ /* Initialize the dfa. */
+ dfa = (re_dfa_t *) preg->buffer;
+ if (BE (preg->allocated < sizeof (re_dfa_t), 0))
+ {
+ /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. If ->buffer is NULL this
+ is a simple allocation. */
+ dfa = re_realloc (preg->buffer, re_dfa_t, 1);
+ if (dfa == NULL)
+ return REG_ESPACE;
+ preg->allocated = sizeof (re_dfa_t);
+ preg->buffer = (unsigned char *) dfa;
+ }
+ preg->used = sizeof (re_dfa_t);
+
+ err = init_dfa (dfa, length);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ free_dfa_content (dfa);
+ preg->buffer = NULL;
+ preg->allocated = 0;
+ return err;
+ }
+#ifdef DEBUG
+ dfa->re_str = re_malloc (char, length + 1);
+ strncpy (dfa->re_str, pattern, length + 1);
+#endif
+
+ err = re_string_construct (®exp, pattern, length, preg->translate,
+ syntax & RE_ICASE, dfa);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_compile_internal_free_return:
+ free_workarea_compile (preg);
+ re_string_destruct (®exp);
+ free_dfa_content (dfa);
+ preg->buffer = NULL;
+ preg->allocated = 0;
+ return err;
+ }
+
+ /* Parse the regular expression, and build a structure tree. */
+ preg->re_nsub = 0;
+ dfa->str_tree = parse (®exp, preg, syntax, &err);
+ if (BE (dfa->str_tree == NULL, 0))
+ goto re_compile_internal_free_return;
+
+ /* Analyze the tree and create the nfa. */
+ err = analyze (preg);
+ if (BE (err != REG_NOERROR, 0))
+ goto re_compile_internal_free_return;
+
+#ifdef RE_ENABLE_I18N
+ /* If possible, do searching in single byte encoding to speed things up. */
+ if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
+ optimize_utf8 (dfa);
+#endif
+
+ /* Then create the initial state of the dfa. */
+ err = create_initial_state (dfa);
+
+ /* Release work areas. */
+ free_workarea_compile (preg);
+ re_string_destruct (®exp);
+
+ if (BE (err != REG_NOERROR, 0))
+ {
+ free_dfa_content (dfa);
+ preg->buffer = NULL;
+ preg->allocated = 0;
+ }
+
+ return err;
+}
+
+/* Initialize DFA. We use the length of the regular expression PAT_LEN
+ as the initial length of some arrays. */
+
+static reg_errcode_t
+init_dfa (dfa, pat_len)
+ re_dfa_t *dfa;
+ int pat_len;
+{
+ int table_size;
+#ifndef _LIBC
+ char *codeset_name;
+#endif
+
+ memset (dfa, '\0', sizeof (re_dfa_t));
+
+ /* Force allocation of str_tree_storage the first time. */
+ dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+
+ dfa->nodes_alloc = pat_len + 1;
+ dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
+
+ dfa->states_alloc = pat_len + 1;
+
+ /* table_size = 2 ^ ceil(log pat_len) */
+ for (table_size = 1; table_size > 0; table_size <<= 1)
+ if (table_size > pat_len)
+ break;
+
+ dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
+ dfa->state_hash_mask = table_size - 1;
+
+ dfa->mb_cur_max = MB_CUR_MAX;
+#ifdef _LIBC
+ if (dfa->mb_cur_max == 6
+ && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+ dfa->is_utf8 = 1;
+ dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+ != 0);
+#else
+# ifdef HAVE_LANGINFO_CODESET
+ codeset_name = nl_langinfo (CODESET);
+# else
+ codeset_name = getenv ("LC_ALL");
+ if (codeset_name == NULL || codeset_name[0] == '\0')
+ codeset_name = getenv ("LC_CTYPE");
+ if (codeset_name == NULL || codeset_name[0] == '\0')
+ codeset_name = getenv ("LANG");
+ if (codeset_name == NULL)
+ codeset_name = "";
+ else if (strchr (codeset_name, '.') != NULL)
+ codeset_name = strchr (codeset_name, '.') + 1;
+# endif
+
+ /* strcasecmp isn't a standard interface. brute force check */
+#if 0
+ if (strcasecmp (codeset_name, "UTF-8") == 0
+ || strcasecmp (codeset_name, "UTF8") == 0)
+ dfa->is_utf8 = 1;
+#else
+ if ( (codeset_name[0] == 'U' || codeset_name[0] == 'u')
+ && (codeset_name[1] == 'T' || codeset_name[1] == 't')
+ && (codeset_name[2] == 'F' || codeset_name[2] == 'f')
+ && (codeset_name[3] == '-'
+ ? codeset_name[4] == '8' && codeset_name[5] == '\0'
+ : codeset_name[3] == '8' && codeset_name[4] == '\0'))
+ dfa->is_utf8 = 1;
+#endif
+
+ /* We check exhaustively in the loop below if this charset is a
+ superset of ASCII. */
+ dfa->map_notascii = 0;
+#endif
+
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ {
+ if (dfa->is_utf8)
+ dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+ else
+ {
+ int i, j, ch;
+
+ dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
+ if (BE (dfa->sb_char == NULL, 0))
+ return REG_ESPACE;
+
+ /* Clear all bits by, then set those corresponding to single
+ byte chars. */
+ bitset_empty (dfa->sb_char);
+
+ for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
+ for (j = 0; j < UINT_BITS; ++j, ++ch)
+ {
+ wchar_t wch = __btowc (ch);
+ if (wch != WEOF)
+ dfa->sb_char[i] |= 1 << j;
+# ifndef _LIBC
+ if (isascii (ch) && wch != (wchar_t) ch)
+ dfa->map_notascii = 1;
+# endif
+ }
+ }
+ }
+#endif
+
+ if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
+ return REG_ESPACE;
+ return REG_NOERROR;
+}
+
+/* Initialize WORD_CHAR table, which indicate which character is
+ "word". In this case "word" means that it is the word construction
+ character used by some operators like "\<", "\>", etc. */
+
+static void
+init_word_char (dfa)
+ re_dfa_t *dfa;
+{
+ int i, j, ch;
+ dfa->word_ops_used = 1;
+ for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
+ for (j = 0; j < UINT_BITS; ++j, ++ch)
+ if (isalnum (ch) || ch == '_')
+ dfa->word_char[i] |= 1 << j;
+}
+
+/* Free the work area which are only used while compiling. */
+
+static void
+free_workarea_compile (preg)
+ regex_t *preg;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_storage_t *storage, *next;
+ for (storage = dfa->str_tree_storage; storage; storage = next)
+ {
+ next = storage->next;
+ re_free (storage);
+ }
+ dfa->str_tree_storage = NULL;
+ dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+ dfa->str_tree = NULL;
+ re_free (dfa->org_indices);
+ dfa->org_indices = NULL;
+}
+
+/* Create initial states for all contexts. */
+
+static reg_errcode_t
+create_initial_state (dfa)
+ re_dfa_t *dfa;
+{
+ int first, i;
+ reg_errcode_t err;
+ re_node_set init_nodes;
+
+ /* Initial states have the epsilon closure of the node which is
+ the first node of the regular expression. */
+ first = dfa->str_tree->first->node_idx;
+ dfa->init_node = first;
+ err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ /* The back-references which are in initial states can epsilon transit,
+ since in this case all of the subexpressions can be null.
+ Then we add epsilon closures of the nodes which are the next nodes of
+ the back-references. */
+ if (dfa->nbackref > 0)
+ for (i = 0; i < init_nodes.nelem; ++i)
+ {
+ int node_idx = init_nodes.elems[i];
+ re_token_type_t type = dfa->nodes[node_idx].type;
+
+ int clexp_idx;
+ if (type != OP_BACK_REF)
+ continue;
+ for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
+ {
+ re_token_t *clexp_node;
+ clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
+ if (clexp_node->type == OP_CLOSE_SUBEXP
+ && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
+ break;
+ }
+ if (clexp_idx == init_nodes.nelem)
+ continue;
+
+ if (type == OP_BACK_REF)
+ {
+ int dest_idx = dfa->edests[node_idx].elems[0];
+ if (!re_node_set_contains (&init_nodes, dest_idx))
+ {
+ re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
+ i = 0;
+ }
+ }
+ }
+
+ /* It must be the first time to invoke acquire_state. */
+ dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
+ /* We don't check ERR here, since the initial state must not be NULL. */
+ if (BE (dfa->init_state == NULL, 0))
+ return err;
+ if (dfa->init_state->has_constraint)
+ {
+ dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
+ CONTEXT_WORD);
+ dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
+ CONTEXT_NEWLINE);
+ dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
+ &init_nodes,
+ CONTEXT_NEWLINE
+ | CONTEXT_BEGBUF);
+ if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+ || dfa->init_state_begbuf == NULL, 0))
+ return err;
+ }
+ else
+ dfa->init_state_word = dfa->init_state_nl
+ = dfa->init_state_begbuf = dfa->init_state;
+
+ re_node_set_free (&init_nodes);
+ return REG_NOERROR;
+}
+\f
+#ifdef RE_ENABLE_I18N
+/* If it is possible to do searching in single byte encoding instead of UTF-8
+ to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
+ DFA nodes where needed. */
+
+static void
+optimize_utf8 (dfa)
+ re_dfa_t *dfa;
+{
+ int node, i, mb_chars = 0, has_period = 0;
+
+ for (node = 0; node < dfa->nodes_len; ++node)
+ switch (dfa->nodes[node].type)
+ {
+ case CHARACTER:
+ if (dfa->nodes[node].opr.c >= 0x80)
+ mb_chars = 1;
+ break;
+ case ANCHOR:
+ switch (dfa->nodes[node].opr.idx)
+ {
+ case LINE_FIRST:
+ case LINE_LAST:
+ case BUF_FIRST:
+ case BUF_LAST:
+ break;
+ default:
+ /* Word anchors etc. cannot be handled. */
+ return;
+ }
+ break;
+ case OP_PERIOD:
+ has_period = 1;
+ break;
+ case OP_BACK_REF:
+ case OP_ALT:
+ case END_OF_RE:
+ case OP_DUP_ASTERISK:
+ case OP_OPEN_SUBEXP:
+ case OP_CLOSE_SUBEXP:
+ break;
+ case COMPLEX_BRACKET:
+ return;
+ case SIMPLE_BRACKET:
+ /* Just double check. */
+ for (i = 0x80 / UINT_BITS; i < BITSET_UINTS; ++i)
+ if (dfa->nodes[node].opr.sbcset[i])
+ return;
+ break;
+ default:
+ abort ();
+ }
+
+ if (mb_chars || has_period)
+ for (node = 0; node < dfa->nodes_len; ++node)
+ {
+ if (dfa->nodes[node].type == CHARACTER
+ && dfa->nodes[node].opr.c >= 0x80)
+ dfa->nodes[node].mb_partial = 0;
+ else if (dfa->nodes[node].type == OP_PERIOD)
+ dfa->nodes[node].type = OP_UTF8_PERIOD;
+ }
+
+ /* The search can be in single byte locale. */
+ dfa->mb_cur_max = 1;
+ dfa->is_utf8 = 0;
+ dfa->has_mb_node = dfa->nbackref > 0 || has_period;
+}
+#endif
+\f
+/* Analyze the structure tree, and calculate "first", "next", "edest",
+ "eclosure", and "inveclosure". */
+
+static reg_errcode_t
+analyze (preg)
+ regex_t *preg;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ reg_errcode_t ret;
+
+ /* Allocate arrays. */
+ dfa->nexts = re_malloc (int, dfa->nodes_alloc);
+ dfa->org_indices = re_malloc (int, dfa->nodes_alloc);
+ dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
+ dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
+ if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
+ || dfa->eclosures == NULL, 0))
+ return REG_ESPACE;
+
+ dfa->subexp_map = re_malloc (int, preg->re_nsub);
+ if (dfa->subexp_map != NULL)
+ {
+ int i;
+ for (i = 0; i < preg->re_nsub; i++)
+ dfa->subexp_map[i] = i;
+ preorder (dfa->str_tree, optimize_subexps, dfa);
+ for (i = 0; i < preg->re_nsub; i++)
+ if (dfa->subexp_map[i] != i)
+ break;
+ if (i == preg->re_nsub)
+ {
+ free (dfa->subexp_map);
+ dfa->subexp_map = NULL;
+ }
+ }
+
+ ret = postorder (dfa->str_tree, lower_subexps, preg);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ ret = postorder (dfa->str_tree, calc_first, dfa);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ preorder (dfa->str_tree, calc_next, dfa);
+ ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ ret = calc_eclosure (dfa);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+
+ /* We only need this during the prune_impossible_nodes pass in regexec.c;
+ skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */
+ if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+ || dfa->nbackref)
+ {
+ dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+ if (BE (dfa->inveclosures == NULL, 0))
+ return REG_ESPACE;
+ ret = calc_inveclosure (dfa);
+ }
+
+ return ret;
+}
+
+/* Our parse trees are very unbalanced, so we cannot use a stack to
+ implement parse tree visits. Instead, we use parent pointers and
+ some hairy code in these two functions. */
+static reg_errcode_t
+postorder (root, fn, extra)
+ bin_tree_t *root;
+ reg_errcode_t (fn (void *, bin_tree_t *));
+ void *extra;
+{
+ bin_tree_t *node, *prev;
+
+ for (node = root; ; )
+ {
+ /* Descend down the tree, preferably to the left (or to the right
+ if that's the only child). */
+ while (node->left || node->right)
+ if (node->left)
+ node = node->left;
+ else
+ node = node->right;
+
+ do
+ {
+ reg_errcode_t err = fn (extra, node);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ if (node->parent == NULL)
+ return REG_NOERROR;
+ prev = node;
+ node = node->parent;
+ }
+ /* Go up while we have a node that is reached from the right. */
+ while (node->right == prev || node->right == NULL);
+ node = node->right;
+ }
+}
+
+static reg_errcode_t
+preorder (root, fn, extra)
+ bin_tree_t *root;
+ reg_errcode_t (fn (void *, bin_tree_t *));
+ void *extra;
+{
+ bin_tree_t *node;
+
+ for (node = root; ; )
+ {
+ reg_errcode_t err = fn (extra, node);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ /* Go to the left node, or up and to the right. */
+ if (node->left)
+ node = node->left;
+ else
+ {
+ bin_tree_t *prev = NULL;
+ while (node->right == prev || node->right == NULL)
+ {
+ prev = node;
+ node = node->parent;
+ if (!node)
+ return REG_NOERROR;
+ }
+ node = node->right;
+ }
+ }
+}
+
+/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
+ re_search_internal to map the inner one's opr.idx to this one's. Adjust
+ backreferences as well. Requires a preorder visit. */
+static reg_errcode_t
+optimize_subexps (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ re_dfa_t *dfa = (re_dfa_t *) extra;
+
+ if (node->token.type == OP_BACK_REF && dfa->subexp_map)
+ {
+ int idx = node->token.opr.idx;
+ node->token.opr.idx = dfa->subexp_map[idx];
+ dfa->used_bkref_map |= 1 << node->token.opr.idx;
+ }
+
+ else if (node->token.type == SUBEXP
+ && node->left && node->left->token.type == SUBEXP)
+ {
+ int other_idx = node->left->token.opr.idx;
+
+ node->left = node->left->left;
+ if (node->left)
+ node->left->parent = node;
+
+ dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
+ if (other_idx < 8 * sizeof (dfa->used_bkref_map))
+ dfa->used_bkref_map &= ~(1 << other_idx);
+ }
+
+ return REG_NOERROR;
+}
+
+/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
+ of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */
+static reg_errcode_t
+lower_subexps (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ regex_t *preg = (regex_t *) extra;
+ reg_errcode_t err = REG_NOERROR;
+
+ if (node->left && node->left->token.type == SUBEXP)
+ {
+ node->left = lower_subexp (&err, preg, node->left);
+ if (node->left)
+ node->left->parent = node;
+ }
+ if (node->right && node->right->token.type == SUBEXP)
+ {
+ node->right = lower_subexp (&err, preg, node->right);
+ if (node->right)
+ node->right->parent = node;
+ }
+
+ return err;
+}
+
+static bin_tree_t *
+lower_subexp (err, preg, node)
+ reg_errcode_t *err;
+ regex_t *preg;
+ bin_tree_t *node;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_t *body = node->left;
+ bin_tree_t *op, *cls, *tree1, *tree;
+
+ if (preg->no_sub
+ && (node->token.opr.idx >= 8 * sizeof (dfa->used_bkref_map)
+ || !(dfa->used_bkref_map & (1 << node->token.opr.idx))))
+ return node->left;
+
+ /* Convert the SUBEXP node to the concatenation of an
+ OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */
+ op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);
+ cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
+ tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
+ tree = create_tree (dfa, op, tree1, CONCAT);
+ if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+
+ op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
+ op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
+ return tree;
+}
+
+/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
+ nodes. Requires a postorder visit. */
+static reg_errcode_t
+calc_first (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ re_dfa_t *dfa = (re_dfa_t *) extra;
+ if (node->token.type == CONCAT)
+ {
+ node->first = node->left->first;
+ node->node_idx = node->left->node_idx;
+ }
+ else
+ {
+ node->first = node;
+ node->node_idx = re_dfa_add_node (dfa, node->token);
+ if (BE (node->node_idx == -1, 0))
+ return REG_ESPACE;
+ }
+ return REG_NOERROR;
+}
+
+/* Pass 2: compute NEXT on the tree. Preorder visit. */
+static reg_errcode_t
+calc_next (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ switch (node->token.type)
+ {
+ case OP_DUP_ASTERISK:
+ node->left->next = node;
+ break;
+ case CONCAT:
+ node->left->next = node->right->first;
+ node->right->next = node->next;
+ break;
+ default:
+ if (node->left)
+ node->left->next = node->next;
+ if (node->right)
+ node->right->next = node->next;
+ break;
+ }
+ return REG_NOERROR;
+}
+
+/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */
+static reg_errcode_t
+link_nfa_nodes (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ re_dfa_t *dfa = (re_dfa_t *) extra;
+ int idx = node->node_idx;
+ reg_errcode_t err = REG_NOERROR;
+
+ switch (node->token.type)
+ {
+ case CONCAT:
+ break;
+
+ case END_OF_RE:
+ assert (node->next == NULL);
+ break;
+
+ case OP_DUP_ASTERISK:
+ case OP_ALT:
+ {
+ int left, right;
+ dfa->has_plural_match = 1;
+ if (node->left != NULL)
+ left = node->left->first->node_idx;
+ else
+ left = node->next->node_idx;
+ if (node->right != NULL)
+ right = node->right->first->node_idx;
+ else
+ right = node->next->node_idx;
+ assert (left > -1);
+ assert (right > -1);
+ err = re_node_set_init_2 (dfa->edests + idx, left, right);
+ }
+ break;
+
+ case ANCHOR:
+ case OP_OPEN_SUBEXP:
+ case OP_CLOSE_SUBEXP:
+ err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);
+ break;
+
+ case OP_BACK_REF:
+ dfa->nexts[idx] = node->next->node_idx;
+ if (node->token.type == OP_BACK_REF)
+ re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
+ break;
+
+ default:
+ assert (!IS_EPSILON_NODE (node->token.type));
+ dfa->nexts[idx] = node->next->node_idx;
+ break;
+ }
+
+ return err;
+}
+
+/* Duplicate the epsilon closure of the node ROOT_NODE.
+ Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
+ to their own constraint. */
+
+static reg_errcode_t
+duplicate_node_closure (dfa, top_org_node, top_clone_node, root_node,
+ init_constraint)
+ re_dfa_t *dfa;
+ int top_org_node, top_clone_node, root_node;
+ unsigned int init_constraint;
+{
+ reg_errcode_t err;
+ int org_node, clone_node, ret;
+ unsigned int constraint = init_constraint;
+ for (org_node = top_org_node, clone_node = top_clone_node;;)
+ {
+ int org_dest, clone_dest;
+ if (dfa->nodes[org_node].type == OP_BACK_REF)
+ {
+ /* If the back reference epsilon-transit, its destination must
+ also have the constraint. Then duplicate the epsilon closure
+ of the destination of the back reference, and store it in
+ edests of the back reference. */
+ org_dest = dfa->nexts[org_node];
+ re_node_set_empty (dfa->edests + clone_node);
+ err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ dfa->nexts[clone_node] = dfa->nexts[org_node];
+ ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ }
+ else if (dfa->edests[org_node].nelem == 0)
+ {
+ /* In case of the node can't epsilon-transit, don't duplicate the
+ destination and store the original destination as the
+ destination of the node. */
+ dfa->nexts[clone_node] = dfa->nexts[org_node];
+ break;
+ }
+ else if (dfa->edests[org_node].nelem == 1)
+ {
+ /* In case of the node can epsilon-transit, and it has only one
+ destination. */
+ org_dest = dfa->edests[org_node].elems[0];
+ re_node_set_empty (dfa->edests + clone_node);
+ if (dfa->nodes[org_node].type == ANCHOR)
+ {
+ /* In case of the node has another constraint, append it. */
+ if (org_node == root_node && clone_node != org_node)
+ {
+ /* ...but if the node is root_node itself, it means the
+ epsilon closure have a loop, then tie it to the
+ destination of the root_node. */
+ ret = re_node_set_insert (dfa->edests + clone_node,
+ org_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ break;
+ }
+ constraint |= dfa->nodes[org_node].opr.ctx_type;
+ }
+ err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ }
+ else /* dfa->edests[org_node].nelem == 2 */
+ {
+ /* In case of the node can epsilon-transit, and it has two
+ destinations. In the bin_tree_t and DFA, that's '|' and '*'. */
+ org_dest = dfa->edests[org_node].elems[0];
+ re_node_set_empty (dfa->edests + clone_node);
+ /* Search for a duplicated node which satisfies the constraint. */
+ clone_dest = search_duplicated_node (dfa, org_dest, constraint);
+ if (clone_dest == -1)
+ {
+ /* There are no such a duplicated node, create a new one. */
+ err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ err = duplicate_node_closure (dfa, org_dest, clone_dest,
+ root_node, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ else
+ {
+ /* There are a duplicated node which satisfy the constraint,
+ use it to avoid infinite loop. */
+ ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ }
+
+ org_dest = dfa->edests[org_node].elems[1];
+ err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+ if (BE (ret < 0, 0))
+ return REG_ESPACE;
+ }
+ org_node = org_dest;
+ clone_node = clone_dest;
+ }
+ return REG_NOERROR;
+}
+
+/* Search for a node which is duplicated from the node ORG_NODE, and
+ satisfies the constraint CONSTRAINT. */
+
+static int
+search_duplicated_node (dfa, org_node, constraint)
+ re_dfa_t *dfa;
+ int org_node;
+ unsigned int constraint;
+{
+ int idx;
+ for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
+ {
+ if (org_node == dfa->org_indices[idx]
+ && constraint == dfa->nodes[idx].constraint)
+ return idx; /* Found. */
+ }
+ return -1; /* Not found. */
+}
+
+/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
+ The new index will be stored in NEW_IDX and return REG_NOERROR if succeeded,
+ otherwise return the error code. */
+
+static reg_errcode_t
+duplicate_node (new_idx, dfa, org_idx, constraint)
+ re_dfa_t *dfa;
+ int *new_idx, org_idx;
+ unsigned int constraint;
+{
+ int dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
+ if (BE (dup_idx == -1, 0))
+ return REG_ESPACE;
+ dfa->nodes[dup_idx].constraint = constraint;
+ if (dfa->nodes[org_idx].type == ANCHOR)
+ dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;
+ dfa->nodes[dup_idx].duplicated = 1;
+
+ /* Store the index of the original node. */
+ dfa->org_indices[dup_idx] = org_idx;
+ *new_idx = dup_idx;
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+calc_inveclosure (dfa)
+ re_dfa_t *dfa;
+{
+ int src, idx, ret;
+ for (idx = 0; idx < dfa->nodes_len; ++idx)
+ re_node_set_init_empty (dfa->inveclosures + idx);
+
+ for (src = 0; src < dfa->nodes_len; ++src)
+ {
+ int *elems = dfa->eclosures[src].elems;
+ for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
+ {
+ ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
+ if (BE (ret == -1, 0))
+ return REG_ESPACE;
+ }
+ }
+
+ return REG_NOERROR;
+}
+
+/* Calculate "eclosure" for all the node in DFA. */
+
+static reg_errcode_t
+calc_eclosure (dfa)
+ re_dfa_t *dfa;
+{
+ int node_idx, incomplete;
+#ifdef DEBUG
+ assert (dfa->nodes_len > 0);
+#endif
+ incomplete = 0;
+ /* For each nodes, calculate epsilon closure. */
+ for (node_idx = 0; ; ++node_idx)
+ {
+ reg_errcode_t err;
+ re_node_set eclosure_elem;
+ if (node_idx == dfa->nodes_len)
+ {
+ if (!incomplete)
+ break;
+ incomplete = 0;
+ node_idx = 0;
+ }
+
+#ifdef DEBUG
+ assert (dfa->eclosures[node_idx].nelem != -1);
+#endif
+
+ /* If we have already calculated, skip it. */
+ if (dfa->eclosures[node_idx].nelem != 0)
+ continue;
+ /* Calculate epsilon closure of `node_idx'. */
+ err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ if (dfa->eclosures[node_idx].nelem == 0)
+ {
+ incomplete = 1;
+ re_node_set_free (&eclosure_elem);
+ }
+ }
+ return REG_NOERROR;
+}
+
+/* Calculate epsilon closure of NODE. */
+
+static reg_errcode_t
+calc_eclosure_iter (new_set, dfa, node, root)
+ re_node_set *new_set;
+ re_dfa_t *dfa;
+ int node, root;
+{
+ reg_errcode_t err;
+ unsigned int constraint;
+ int i, incomplete;
+ re_node_set eclosure;
+ incomplete = 0;
+ err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ /* This indicates that we are calculating this node now.
+ We reference this value to avoid infinite loop. */
+ dfa->eclosures[node].nelem = -1;
+
+ constraint = ((dfa->nodes[node].type == ANCHOR)
+ ? dfa->nodes[node].opr.ctx_type : 0);
+ /* If the current node has constraints, duplicate all nodes.
+ Since they must inherit the constraints. */
+ if (constraint
+ && dfa->edests[node].nelem
+ && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
+ {
+ int org_node, cur_node;
+ org_node = cur_node = node;
+ err = duplicate_node_closure (dfa, node, node, node, constraint);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+
+ /* Expand each epsilon destination nodes. */
+ if (IS_EPSILON_NODE(dfa->nodes[node].type))
+ for (i = 0; i < dfa->edests[node].nelem; ++i)
+ {
+ re_node_set eclosure_elem;
+ int edest = dfa->edests[node].elems[i];
+ /* If calculating the epsilon closure of `edest' is in progress,
+ return intermediate result. */
+ if (dfa->eclosures[edest].nelem == -1)
+ {
+ incomplete = 1;
+ continue;
+ }
+ /* If we haven't calculated the epsilon closure of `edest' yet,
+ calculate now. Otherwise use calculated epsilon closure. */
+ if (dfa->eclosures[edest].nelem == 0)
+ {
+ err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ else
+ eclosure_elem = dfa->eclosures[edest];
+ /* Merge the epsilon closure of `edest'. */
+ re_node_set_merge (&eclosure, &eclosure_elem);
+ /* If the epsilon closure of `edest' is incomplete,
+ the epsilon closure of this node is also incomplete. */
+ if (dfa->eclosures[edest].nelem == 0)
+ {
+ incomplete = 1;
+ re_node_set_free (&eclosure_elem);
+ }
+ }
+
+ /* Epsilon closures include itself. */
+ re_node_set_insert (&eclosure, node);
+ if (incomplete && !root)
+ dfa->eclosures[node].nelem = 0;
+ else
+ dfa->eclosures[node] = eclosure;
+ *new_set = eclosure;
+ return REG_NOERROR;
+}
+\f
+/* Functions for token which are used in the parser. */
+
+/* Fetch a token from INPUT.
+ We must not use this function inside bracket expressions. */
+
+static void
+fetch_token (result, input, syntax)
+ re_token_t *result;
+ re_string_t *input;
+ reg_syntax_t syntax;
+{
+ re_string_skip_bytes (input, peek_token (result, input, syntax));
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+ We must not use this function inside bracket expressions. */
+
+static int
+peek_token (token, input, syntax)
+ re_token_t *token;
+ re_string_t *input;
+ reg_syntax_t syntax;
+{
+ unsigned char c;
+
+ if (re_string_eoi (input))
+ {
+ token->type = END_OF_RE;
+ return 0;
+ }
+
+ c = re_string_peek_byte (input, 0);
+ token->opr.c = c;
+
+ token->word_char = 0;
+#ifdef RE_ENABLE_I18N
+ token->mb_partial = 0;
+ if (input->mb_cur_max > 1 &&
+ !re_string_first_byte (input, re_string_cur_idx (input)))
+ {
+ token->type = CHARACTER;
+ token->mb_partial = 1;
+ return 1;
+ }
+#endif
+ if (c == '\\')
+ {
+ unsigned char c2;
+ if (re_string_cur_idx (input) + 1 >= re_string_length (input))
+ {
+ token->type = BACK_SLASH;
+ return 1;
+ }
+
+ c2 = re_string_peek_byte_case (input, 1);
+ token->opr.c = c2;
+ token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+ if (input->mb_cur_max > 1)
+ {
+ wint_t wc = re_string_wchar_at (input,
+ re_string_cur_idx (input) + 1);
+ token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+ }
+ else
+#endif
+ token->word_char = IS_WORD_CHAR (c2) != 0;
+
+ switch (c2)
+ {
+ case '|':
+ if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
+ token->type = OP_ALT;
+ break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (!(syntax & RE_NO_BK_REFS))
+ {
+ token->type = OP_BACK_REF;
+ token->opr.idx = c2 - '1';
+ }
+ break;
+ case '<':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = WORD_FIRST;
+ }
+ break;
+ case '>':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = WORD_LAST;
+ }
+ break;
+ case 'b':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = WORD_DELIM;
+ }
+ break;
+ case 'B':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = NOT_WORD_DELIM;
+ }
+ break;
+ case 'w':
+ if (!(syntax & RE_NO_GNU_OPS))
+ token->type = OP_WORD;
+ break;
+ case 'W':
+ if (!(syntax & RE_NO_GNU_OPS))
+ token->type = OP_NOTWORD;
+ break;
+#ifndef GAWK
+ case 's':
+ if (!(syntax & RE_NO_GNU_OPS))
+ token->type = OP_SPACE;
+ break;
+ case 'S':
+ if (!(syntax & RE_NO_GNU_OPS))
+ token->type = OP_NOTSPACE;
+ break;
+#endif
+ case '`':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = BUF_FIRST;
+ }
+ break;
+ case '\'':
+ if (!(syntax & RE_NO_GNU_OPS))
+ {
+ token->type = ANCHOR;
+ token->opr.ctx_type = BUF_LAST;
+ }
+ break;
+ case '(':
+ if (!(syntax & RE_NO_BK_PARENS))
+ token->type = OP_OPEN_SUBEXP;
+ break;
+ case ')':
+ if (!(syntax & RE_NO_BK_PARENS))
+ token->type = OP_CLOSE_SUBEXP;
+ break;
+ case '+':
+ if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+ token->type = OP_DUP_PLUS;
+ break;
+ case '?':
+ if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+ token->type = OP_DUP_QUESTION;
+ break;
+ case '{':
+ if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+ token->type = OP_OPEN_DUP_NUM;
+ break;
+ case '}':
+ if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+ token->type = OP_CLOSE_DUP_NUM;
+ break;
+ default:
+ break;
+ }
+ return 2;
+ }
+
+ token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+ if (input->mb_cur_max > 1)
+ {
+ wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+ token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+ }
+ else
+#endif
+ token->word_char = IS_WORD_CHAR (token->opr.c);
+
+ switch (c)
+ {
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ token->type = OP_ALT;
+ break;
+ case '|':
+ if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
+ token->type = OP_ALT;
+ break;
+ case '*':
+ token->type = OP_DUP_ASTERISK;
+ break;
+ case '+':
+ if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+ token->type = OP_DUP_PLUS;
+ break;
+ case '?':
+ if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+ token->type = OP_DUP_QUESTION;
+ break;
+ case '{':
+ if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ token->type = OP_OPEN_DUP_NUM;
+ break;
+ case '}':
+ if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ token->type = OP_CLOSE_DUP_NUM;
+ break;
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ token->type = OP_OPEN_SUBEXP;
+ break;
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ token->type = OP_CLOSE_SUBEXP;
+ break;
+ case '[':
+ token->type = OP_OPEN_BRACKET;
+ break;
+ case '.':
+ token->type = OP_PERIOD;
+ break;
+ case '^':
+ if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
+ re_string_cur_idx (input) != 0)
+ {
+ char prev = re_string_peek_byte (input, -1);
+ if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
+ break;
+ }
+ token->type = ANCHOR;
+ token->opr.ctx_type = LINE_FIRST;
+ break;
+ case '$':
+ if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
+ re_string_cur_idx (input) + 1 != re_string_length (input))
+ {
+ re_token_t next;
+ re_string_skip_bytes (input, 1);
+ peek_token (&next, input, syntax);
+ re_string_skip_bytes (input, -1);
+ if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
+ break;
+ }
+ token->type = ANCHOR;
+ token->opr.ctx_type = LINE_LAST;
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+ We must not use this function out of bracket expressions. */
+
+static int
+peek_token_bracket (token, input, syntax)
+ re_token_t *token;
+ re_string_t *input;
+ reg_syntax_t syntax;
+{
+ unsigned char c;
+ if (re_string_eoi (input))
+ {
+ token->type = END_OF_RE;
+ return 0;
+ }
+ c = re_string_peek_byte (input, 0);
+ token->opr.c = c;
+
+#ifdef RE_ENABLE_I18N
+ if (input->mb_cur_max > 1 &&
+ !re_string_first_byte (input, re_string_cur_idx (input)))
+ {
+ token->type = CHARACTER;
+ return 1;
+ }
+#endif /* RE_ENABLE_I18N */
+
+ if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
+ && re_string_cur_idx (input) + 1 < re_string_length (input))
+ {
+ /* In this case, '\' escape a character. */
+ unsigned char c2;
+ re_string_skip_bytes (input, 1);
+ c2 = re_string_peek_byte (input, 0);
+ token->opr.c = c2;
+ token->type = CHARACTER;
+ return 1;
+ }
+ if (c == '[') /* '[' is a special char in a bracket exps. */
+ {
+ unsigned char c2;
+ int token_len;
+ if (re_string_cur_idx (input) + 1 < re_string_length (input))
+ c2 = re_string_peek_byte (input, 1);
+ else
+ c2 = 0;
+ token->opr.c = c2;
+ token_len = 2;
+ switch (c2)
+ {
+ case '.':
+ token->type = OP_OPEN_COLL_ELEM;
+ break;
+ case '=':
+ token->type = OP_OPEN_EQUIV_CLASS;
+ break;
+ case ':':
+ if (syntax & RE_CHAR_CLASSES)
+ {
+ token->type = OP_OPEN_CHAR_CLASS;
+ break;
+ }
+ /* else fall through. */
+ default:
+ token->type = CHARACTER;
+ token->opr.c = c;
+ token_len = 1;
+ break;
+ }
+ return token_len;
+ }
+ switch (c)
+ {
+ case '-':
+ token->type = OP_CHARSET_RANGE;
+ break;
+ case ']':
+ token->type = OP_CLOSE_BRACKET;
+ break;
+ case '^':
+ token->type = OP_NON_MATCH_LIST;
+ break;
+ default:
+ token->type = CHARACTER;
+ }
+ return 1;
+}
+\f
+/* Functions for parser. */
+
+/* Entry point of the parser.
+ Parse the regular expression REGEXP and return the structure tree.
+ If an error is occured, ERR is set by error code, and return NULL.
+ This function build the following tree, from regular expression <reg_exp>:
+ CAT
+ / \
+ / \
+ <reg_exp> EOR
+
+ CAT means concatenation.
+ EOR means end of regular expression. */
+
+static bin_tree_t *
+parse (regexp, preg, syntax, err)
+ re_string_t *regexp;
+ regex_t *preg;
+ reg_syntax_t syntax;
+ reg_errcode_t *err;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_t *tree, *eor, *root;
+ re_token_t current_token;
+ dfa->syntax = syntax;
+ fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+ tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ eor = create_tree (dfa, NULL, NULL, END_OF_RE);
+ if (tree != NULL)
+ root = create_tree (dfa, tree, eor, CONCAT);
+ else
+ root = eor;
+ if (BE (eor == NULL || root == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ return root;
+}
+
+/* This function build the following tree, from regular expression
+ <branch1>|<branch2>:
+ ALT
+ / \
+ / \
+ <branch1> <branch2>
+
+ ALT means alternative, which represents the operator `|'. */
+
+static bin_tree_t *
+parse_reg_exp (regexp, preg, token, syntax, nest, err)
+ re_string_t *regexp;
+ regex_t *preg;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ int nest;
+ reg_errcode_t *err;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_t *tree, *branch = NULL;
+ tree = parse_branch (regexp, preg, token, syntax, nest, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+
+ while (token->type == OP_ALT)
+ {
+ fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+ if (token->type != OP_ALT && token->type != END_OF_RE
+ && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+ {
+ branch = parse_branch (regexp, preg, token, syntax, nest, err);
+ if (BE (*err != REG_NOERROR && branch == NULL, 0))
+ return NULL;
+ }
+ else
+ branch = NULL;
+ tree = create_tree (dfa, tree, branch, OP_ALT);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ }
+ return tree;
+}
+
+/* This function build the following tree, from regular expression
+ <exp1><exp2>:
+ CAT
+ / \
+ / \
+ <exp1> <exp2>
+
+ CAT means concatenation. */
+
+static bin_tree_t *
+parse_branch (regexp, preg, token, syntax, nest, err)
+ re_string_t *regexp;
+ regex_t *preg;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ int nest;
+ reg_errcode_t *err;
+{
+ bin_tree_t *tree, *exp;
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ tree = parse_expression (regexp, preg, token, syntax, nest, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+
+ while (token->type != OP_ALT && token->type != END_OF_RE
+ && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+ {
+ exp = parse_expression (regexp, preg, token, syntax, nest, err);
+ if (BE (*err != REG_NOERROR && exp == NULL, 0))
+ {
+ return NULL;
+ }
+ if (tree != NULL && exp != NULL)
+ {
+ tree = create_tree (dfa, tree, exp, CONCAT);
+ if (tree == NULL)
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ }
+ else if (tree == NULL)
+ tree = exp;
+ /* Otherwise exp == NULL, we don't need to create new tree. */
+ }
+ return tree;
+}
+
+/* This function build the following tree, from regular expression a*:
+ *
+ |
+ a
+*/
+
+static bin_tree_t *
+parse_expression (regexp, preg, token, syntax, nest, err)
+ re_string_t *regexp;
+ regex_t *preg;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ int nest;
+ reg_errcode_t *err;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_t *tree;
+ switch (token->type)
+ {
+ case CHARACTER:
+ tree = create_token_tree (dfa, NULL, NULL, token);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ {
+ while (!re_string_eoi (regexp)
+ && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+ {
+ bin_tree_t *mbc_remain;
+ fetch_token (token, regexp, syntax);
+ mbc_remain = create_token_tree (dfa, NULL, NULL, token);
+ tree = create_tree (dfa, tree, mbc_remain, CONCAT);
+ if (BE (mbc_remain == NULL || tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ }
+ }
+#endif
+ break;
+ case OP_OPEN_SUBEXP:
+ tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ break;
+ case OP_OPEN_BRACKET:
+ tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ break;
+ case OP_BACK_REF:
+ if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
+ {
+ *err = REG_ESUBREG;
+ return NULL;
+ }
+ dfa->used_bkref_map |= 1 << token->opr.idx;
+ tree = create_token_tree (dfa, NULL, NULL, token);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ ++dfa->nbackref;
+ dfa->has_mb_node = 1;
+ break;
+ case OP_OPEN_DUP_NUM:
+ if (syntax & RE_CONTEXT_INVALID_DUP)
+ {
+ *err = REG_BADRPT;
+ return NULL;
+ }
+ /* FALLTHROUGH */
+ case OP_DUP_ASTERISK:
+ case OP_DUP_PLUS:
+ case OP_DUP_QUESTION:
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ {
+ *err = REG_BADRPT;
+ return NULL;
+ }
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ {
+ fetch_token (token, regexp, syntax);
+ return parse_expression (regexp, preg, token, syntax, nest, err);
+ }
+ /* else fall through */
+ case OP_CLOSE_SUBEXP:
+ if ((token->type == OP_CLOSE_SUBEXP) &&
+ !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
+ {
+ *err = REG_ERPAREN;
+ return NULL;
+ }
+ /* else fall through */
+ case OP_CLOSE_DUP_NUM:
+ /* We treat it as a normal character. */
+
+ /* Then we can these characters as normal characters. */
+ token->type = CHARACTER;
+ /* mb_partial and word_char bits should be initialized already
+ by peek_token. */
+ tree = create_token_tree (dfa, NULL, NULL, token);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ break;
+ case ANCHOR:
+ if ((token->opr.ctx_type
+ & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
+ && dfa->word_ops_used == 0)
+ init_word_char (dfa);
+ if (token->opr.ctx_type == WORD_DELIM
+ || token->opr.ctx_type == NOT_WORD_DELIM)
+ {
+ bin_tree_t *tree_first, *tree_last;
+ if (token->opr.ctx_type == WORD_DELIM)
+ {
+ token->opr.ctx_type = WORD_FIRST;
+ tree_first = create_token_tree (dfa, NULL, NULL, token);
+ token->opr.ctx_type = WORD_LAST;
+ }
+ else
+ {
+ token->opr.ctx_type = INSIDE_WORD;
+ tree_first = create_token_tree (dfa, NULL, NULL, token);
+ token->opr.ctx_type = INSIDE_NOTWORD;
+ }
+ tree_last = create_token_tree (dfa, NULL, NULL, token);
+ tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
+ if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ }
+ else
+ {
+ tree = create_token_tree (dfa, NULL, NULL, token);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ }
+ /* We must return here, since ANCHORs can't be followed
+ by repetition operators.
+ eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
+ it must not be "<ANCHOR(^)><REPEAT(*)>". */
+ fetch_token (token, regexp, syntax);
+ return tree;
+ case OP_PERIOD:
+ tree = create_token_tree (dfa, NULL, NULL, token);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ if (dfa->mb_cur_max > 1)
+ dfa->has_mb_node = 1;
+ break;
+ case OP_WORD:
+ case OP_NOTWORD:
+ tree = build_charclass_op (dfa, regexp->trans,
+ (const char *) "alnum",
+ (const char *) "_",
+ token->type == OP_NOTWORD, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ break;
+ case OP_SPACE:
+ case OP_NOTSPACE:
+ tree = build_charclass_op (dfa, regexp->trans,
+ (const char *) "space",
+ (const char *) "",
+ token->type == OP_NOTSPACE, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ break;
+ case OP_ALT:
+ case END_OF_RE:
+ return NULL;
+ case BACK_SLASH:
+ *err = REG_EESCAPE;
+ return NULL;
+ default:
+ /* Must not happen? */
+#ifdef DEBUG
+ assert (0);
+#endif
+ return NULL;
+ }
+ fetch_token (token, regexp, syntax);
+
+ while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
+ || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
+ {
+ tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+ if (BE (*err != REG_NOERROR && tree == NULL, 0))
+ return NULL;
+ /* In BRE consecutive duplications are not allowed. */
+ if ((syntax & RE_CONTEXT_INVALID_DUP)
+ && (token->type == OP_DUP_ASTERISK
+ || token->type == OP_OPEN_DUP_NUM))
+ {
+ *err = REG_BADRPT;
+ return NULL;
+ }
+ }
+
+ return tree;
+}
+
+/* This function build the following tree, from regular expression
+ (<reg_exp>):
+ SUBEXP
+ |
+ <reg_exp>
+*/
+
+static bin_tree_t *
+parse_sub_exp (regexp, preg, token, syntax, nest, err)
+ re_string_t *regexp;
+ regex_t *preg;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ int nest;
+ reg_errcode_t *err;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ bin_tree_t *tree;
+ size_t cur_nsub;
+ cur_nsub = preg->re_nsub++;
+
+ fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+
+ /* The subexpression may be a null string. */
+ if (token->type == OP_CLOSE_SUBEXP)
+ tree = NULL;
+ else
+ {
+ tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
+ if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
+ *err = REG_EPAREN;
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+ }
+ dfa->completed_bkref_map |= 1 << cur_nsub;
+
+ tree = create_tree (dfa, tree, NULL, SUBEXP);
+ if (BE (tree == NULL, 0))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+ tree->token.opr.idx = cur_nsub;
+ return tree;
+}
+
+/* This function parse repetition operators like "*", "+", "{1,3}" etc. */
+
+static bin_tree_t *
+parse_dup_op (elem, regexp, dfa, token, syntax, err)
+ bin_tree_t *elem;
+ re_string_t *regexp;
+ re_dfa_t *dfa;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ reg_errcode_t *err;
+{
+ bin_tree_t *tree = NULL, *old_tree = NULL;
+ int i, start, end, start_idx = re_string_cur_idx (regexp);
+#ifndef RE_TOKEN_INIT_BUG
+ re_token_t start_token = *token;
+#else
+ re_token_t start_token;
+
+ memcpy ((void *) &start_token, (void *) token, sizeof start_token);
+#endif
+
+ if (token->type == OP_OPEN_DUP_NUM)
+ {
+ end = 0;
+ start = fetch_number (regexp, token, syntax);
+ if (start == -1)
+ {
+ if (token->type == CHARACTER && token->opr.c == ',')
+ start = 0; /* We treat "{,m}" as "{0,m}". */
+ else
+ {
+ *err = REG_BADBR; /* <re>{} is invalid. */
+ return NULL;
+ }
+ }
+ if (BE (start != -2, 1))
+ {
+ /* We treat "{n}" as "{n,n}". */
+ end = ((token->type == OP_CLOSE_DUP_NUM) ? start
+ : ((token->type == CHARACTER && token->opr.c == ',')
+ ? fetch_number (regexp, token, syntax) : -2));
+ }
+ if (BE (start == -2 || end == -2, 0))
+ {
+ /* Invalid sequence. */
+ if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
+ {
+ if (token->type == END_OF_RE)
+ *err = REG_EBRACE;
+ else
+ *err = REG_BADBR;
+
+ return NULL;
+ }
+
+ /* If the syntax bit is set, rollback. */
+ re_string_set_index (regexp, start_idx);
+ *token = start_token;
+ token->type = CHARACTER;
+ /* mb_partial and word_char bits should be already initialized by
+ peek_token. */
+ return elem;
+ }
+
+ if (BE (end != -1 && start > end, 0))
+ {
+ /* First number greater than second. */
+ *err = REG_BADBR;
+ return NULL;
+ }
+ }
+ else
+ {
+ start = (token->type == OP_DUP_PLUS) ? 1 : 0;
+ end = (token->type == OP_DUP_QUESTION) ? 1 : -1;
+ }
+
+ fetch_token (token, regexp, syntax);
+
+ if (BE (elem == NULL, 0))
+ return NULL;
+ if (BE (start == 0 && end == 0, 0))
+ {
+ postorder (elem, free_tree, NULL);
+ return NULL;
+ }
+
+ /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}". */
+ if (BE (start > 0, 0))
+ {
+ tree = elem;
+ for (i = 2; i <= start; ++i)
+ {
+ elem = duplicate_tree (elem, dfa);
+ tree = create_tree (dfa, tree, elem, CONCAT);
+ if (BE (elem == NULL || tree == NULL, 0))
+ goto parse_dup_op_espace;
+ }
+
+ if (start == end)
+ return tree;
+
+ /* Duplicate ELEM before it is marked optional. */
+ elem = duplicate_tree (elem, dfa);
+ old_tree = tree;
+ }
+ else
+ old_tree = NULL;
+
+ if (elem->token.type == SUBEXP)
+ postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
+
+ tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT));
+ if (BE (tree == NULL, 0))
+ goto parse_dup_op_espace;
+
+ /* This loop is actually executed only when end != -1,
+ to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have
+ already created the start+1-th copy. */
+ for (i = start + 2; i <= end; ++i)
+ {
+ elem = duplicate_tree (elem, dfa);
+ tree = create_tree (dfa, tree, elem, CONCAT);
+ if (BE (elem == NULL || tree == NULL, 0))
+ goto parse_dup_op_espace;
+
+ tree = create_tree (dfa, tree, NULL, OP_ALT);
+ if (BE (tree == NULL, 0))
+ goto parse_dup_op_espace;
+ }
+
+ if (old_tree)
+ tree = create_tree (dfa, old_tree, tree, CONCAT);
+
+ return tree;
+
+ parse_dup_op_espace:
+ *err = REG_ESPACE;
+ return NULL;
+}
+
+/* Size of the names for collating symbol/equivalence_class/character_class.
+ I'm not sure, but maybe enough. */
+#define BRACKET_NAME_BUF_SIZE 32
+
+#ifndef _LIBC
+ /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+ Build the range expression which starts from START_ELEM, and ends
+ at END_ELEM. The result are written to MBCSET and SBCSET.
+ RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+ mbcset->range_ends, is a pointer argument sinse we may
+ update it. */
+
+static reg_errcode_t
+# ifdef RE_ENABLE_I18N
+build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
+ re_charset_t *mbcset;
+ int *range_alloc;
+# else /* not RE_ENABLE_I18N */
+build_range_exp (sbcset, start_elem, end_elem)
+# endif /* not RE_ENABLE_I18N */
+ re_bitset_ptr_t sbcset;
+ bracket_elem_t *start_elem, *end_elem;
+{
+ unsigned int start_ch, end_ch;
+ /* Equivalence Classes and Character Classes can't be a range start/end. */
+ if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+ || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+ 0))
+ return REG_ERANGE;
+
+ /* We can handle no multi character collating elements without libc
+ support. */
+ if (BE ((start_elem->type == COLL_SYM
+ && strlen ((char *) start_elem->opr.name) > 1)
+ || (end_elem->type == COLL_SYM
+ && strlen ((char *) end_elem->opr.name) > 1), 0))
+ return REG_ECOLLATE;
+
+# ifdef RE_ENABLE_I18N
+ {
+ wchar_t wc, start_wc, end_wc;
+ wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+
+ start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
+ : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+ : 0));
+ end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
+ : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+ : 0));
+ start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
+ ? __btowc (start_ch) : start_elem->opr.wch);
+ end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
+ ? __btowc (end_ch) : end_elem->opr.wch);
+ if (start_wc == WEOF || end_wc == WEOF)
+ return REG_ECOLLATE;
+ cmp_buf[0] = start_wc;
+ cmp_buf[4] = end_wc;
+ if (wcscoll (cmp_buf, cmp_buf + 4) > 0)
+ return REG_ERANGE;
+
+ /* Got valid collation sequence values, add them as a new entry.
+ However, for !_LIBC we have no collation elements: if the
+ character set is single byte, the single byte character set
+ that we build below suffices. parse_bracket_exp passes
+ no MBCSET if dfa->mb_cur_max == 1. */
+ if (mbcset)
+ {
+ /* Check the space of the arrays. */
+ if (BE (*range_alloc == mbcset->nranges, 0))
+ {
+ /* There is not enough space, need realloc. */
+ wchar_t *new_array_start, *new_array_end;
+ int new_nranges;
+
+ /* +1 in case of mbcset->nranges is 0. */
+ new_nranges = 2 * mbcset->nranges + 1;
+ /* Use realloc since mbcset->range_starts and mbcset->range_ends
+ are NULL if *range_alloc == 0. */
+ new_array_start = re_realloc (mbcset->range_starts, wchar_t,
+ new_nranges);
+ new_array_end = re_realloc (mbcset->range_ends, wchar_t,
+ new_nranges);
+
+ if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+ return REG_ESPACE;
+
+ mbcset->range_starts = new_array_start;
+ mbcset->range_ends = new_array_end;
+ *range_alloc = new_nranges;
+ }
+
+ mbcset->range_starts[mbcset->nranges] = start_wc;
+ mbcset->range_ends[mbcset->nranges++] = end_wc;
+ }
+
+ /* Build the table for single byte characters. */
+ for (wc = 0; wc < SBC_MAX; ++wc)
+ {
+ cmp_buf[2] = wc;
+ if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+ && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+ bitset_set (sbcset, wc);
+ }
+ }
+# else /* not RE_ENABLE_I18N */
+ {
+ unsigned int ch;
+ start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
+ : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+ : 0));
+ end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
+ : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+ : 0));
+ if (start_ch > end_ch)
+ return REG_ERANGE;
+ /* Build the table for single byte characters. */
+ for (ch = 0; ch < SBC_MAX; ++ch)
+ if (start_ch <= ch && ch <= end_ch)
+ bitset_set (sbcset, ch);
+ }
+# endif /* not RE_ENABLE_I18N */
+ return REG_NOERROR;
+}
+#endif /* not _LIBC */
+
+#ifndef _LIBC
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+ Build the collating element which is represented by NAME.
+ The result are written to MBCSET and SBCSET.
+ COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+ pointer argument since we may update it. */
+
+static reg_errcode_t
+# ifdef RE_ENABLE_I18N
+build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
+ re_charset_t *mbcset;
+ int *coll_sym_alloc;
+# else /* not RE_ENABLE_I18N */
+build_collating_symbol (sbcset, name)
+# endif /* not RE_ENABLE_I18N */
+ re_bitset_ptr_t sbcset;
+ const unsigned char *name;
+{
+ size_t name_len = strlen ((const char *) name);
+ if (BE (name_len != 1, 0))
+ return REG_ECOLLATE;
+ else
+ {
+ bitset_set (sbcset, name[0]);
+ return REG_NOERROR;
+ }
+}
+#endif /* not _LIBC */
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+ "[[.a-a.]]" etc. */
+
+static bin_tree_t *
+parse_bracket_exp (regexp, dfa, token, syntax, err)
+ re_string_t *regexp;
+ re_dfa_t *dfa;
+ re_token_t *token;
+ reg_syntax_t syntax;
+ reg_errcode_t *err;
+{
+#ifdef _LIBC
+ const unsigned char *collseqmb;
+ const char *collseqwc;
+ uint32_t nrules;
+ int32_t table_size;
+ const int32_t *symb_table;
+ const unsigned char *extra;
+
+ /* Local function for parse_bracket_exp used in _LIBC environement.
+ Seek the collating symbol entry correspondings to NAME.
+ Return the index of the symbol in the SYMB_TABLE. */
+
+ auto inline int32_t
+ __attribute ((always_inline))
+ seek_collating_symbol_entry (name, name_len)
+ const unsigned char *name;
+ size_t name_len;
+ {
+ int32_t hash = elem_hash ((const char *) name, name_len);
+ int32_t elem = hash % table_size;
+ int32_t second = hash % (table_size - 2);
+ while (symb_table[2 * elem] != 0)
+ {
+ /* First compare the hashing value. */
+ if (symb_table[2 * elem] == hash
+ /* Compare the length of the name. */
+ && name_len == extra[symb_table[2 * elem + 1]]
+ /* Compare the name. */
+ && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
+ name_len) == 0)
+ {
+ /* Yep, this is the entry. */
+ break;
+ }
+
+ /* Next entry. */
+ elem += second;
+ }
+ return elem;
+ }
+
+ /* Local function for parse_bracket_exp used in _LIBC environement.
+ Look up the collation sequence value of BR_ELEM.
+ Return the value if succeeded, UINT_MAX otherwise. */
+
+ auto inline unsigned int
+ __attribute ((always_inline))
+ lookup_collation_sequence_value (br_elem)
+ bracket_elem_t *br_elem;
+ {
+ if (br_elem->type == SB_CHAR)
+ {
+ /*
+ if (MB_CUR_MAX == 1)
+ */
+ if (nrules == 0)
+ return collseqmb[br_elem->opr.ch];
+ else
+ {
+ wint_t wc = __btowc (br_elem->opr.ch);
+ return __collseq_table_lookup (collseqwc, wc);
+ }
+ }
+ else if (br_elem->type == MB_CHAR)
+ {
+ return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+ }
+ else if (br_elem->type == COLL_SYM)
+ {
+ size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+ if (nrules != 0)
+ {
+ int32_t elem, idx;
+ elem = seek_collating_symbol_entry (br_elem->opr.name,
+ sym_name_len);
+ if (symb_table[2 * elem] != 0)
+ {
+ /* We found the entry. */
+ idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating element name. */
+ idx += 1 + extra[idx];
+ /* Skip the byte sequence of the collating element. */
+ idx += 1 + extra[idx];
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
+ /* Skip the multibyte collation sequence value. */
+ idx += sizeof (unsigned int);
+ /* Skip the wide char sequence of the collating element. */
+ idx += sizeof (unsigned int) *
+ (1 + *(unsigned int *) (extra + idx));
+ /* Return the collation sequence value. */
+ return *(unsigned int *) (extra + idx);
+ }
+ else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+ {
+ /* No valid character. Match it as a single byte
+ character. */
+ return collseqmb[br_elem->opr.name[0]];
+ }
+ }
+ else if (sym_name_len == 1)
+ return collseqmb[br_elem->opr.name[0]];
+ }
+ return UINT_MAX;
+ }
+
+ /* Local function for parse_bracket_exp used in _LIBC environement.
+ Build the range expression which starts from START_ELEM, and ends
+ at END_ELEM. The result are written to MBCSET and SBCSET.
+ RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+ mbcset->range_ends, is a pointer argument sinse we may
+ update it. */
+
+ auto inline reg_errcode_t
+ __attribute ((always_inline))
+ build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
+ re_charset_t *mbcset;
+ int *range_alloc;
+ re_bitset_ptr_t sbcset;
+ bracket_elem_t *start_elem, *end_elem;
+ {
+ unsigned int ch;
+ uint32_t start_collseq;
+ uint32_t end_collseq;
+
+ /* Equivalence Classes and Character Classes can't be a range
+ start/end. */
+ if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+ || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+ 0))
+ return REG_ERANGE;
+
+ start_collseq = lookup_collation_sequence_value (start_elem);
+ end_collseq = lookup_collation_sequence_value (end_elem);
+ /* Check start/end collation sequence values. */
+ if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
+ return REG_ECOLLATE;
+ if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
+ return REG_ERANGE;
+
+ /* Got valid collation sequence values, add them as a new entry.
+ However, if we have no collation elements, and the character set
+ is single byte, the single byte character set that we
+ build below suffices. */
+ if (nrules > 0 || dfa->mb_cur_max > 1)
+ {
+ /* Check the space of the arrays. */
+ if (BE (*range_alloc == mbcset->nranges, 0))
+ {
+ /* There is not enough space, need realloc. */
+ uint32_t *new_array_start;
+ uint32_t *new_array_end;
+ int new_nranges;
+
+ /* +1 in case of mbcset->nranges is 0. */
+ new_nranges = 2 * mbcset->nranges + 1;
+ new_array_start = re_realloc (mbcset->range_starts, uint32_t,
+ new_nranges);
+ new_array_end = re_realloc (mbcset->range_ends, uint32_t,
+ new_nranges);
+
+ if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+ return REG_ESPACE;
+
+ mbcset->range_starts = new_array_start;
+ mbcset->range_ends = new_array_end;
+ *range_alloc = new_nranges;
+ }
+
+ mbcset->range_starts[mbcset->nranges] = start_collseq;
+ mbcset->range_ends[mbcset->nranges++] = end_collseq;
+ }
+
+ /* Build the table for single byte characters. */
+ for (ch = 0; ch < SBC_MAX; ch++)
+ {
+ uint32_t ch_collseq;
+ /*
+ if (MB_CUR_MAX == 1)
+ */
+ if (nrules == 0)
+ ch_collseq = collseqmb[ch];
+ else
+ ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+ if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+ bitset_set (sbcset, ch);
+ }
+ return REG_NOERROR;
+ }
+
+ /* Local function for parse_bracket_exp used in _LIBC environement.
+ Build the collating element which is represented by NAME.
+ The result are written to MBCSET and SBCSET.
+ COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+ pointer argument sinse we may update it. */
+
+ auto inline reg_errcode_t
+ __attribute ((always_inline))
+ build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
+ re_charset_t *mbcset;
+ int *coll_sym_alloc;
+ re_bitset_ptr_t sbcset;
+ const unsigned char *name;
+ {
+ int32_t elem, idx;
+ size_t name_len = strlen ((const char *) name);
+ if (nrules != 0)
+ {
+ elem = seek_collating_symbol_entry (name, name_len);
+ if (symb_table[2 * elem] != 0)
+ {
+ /* We found the entry. */
+ idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating element name. */
+ idx += 1 + extra[idx];
+ }
+ else if (symb_table[2 * elem] == 0 && name_len == 1)
+ {
+ /* No valid character, treat it as a normal
+ character. */
+ bitset_set (sbcset, name[0]);
+ return REG_NOERROR;
+ }
+ else
+ return REG_ECOLLATE;
+
+ /* Got valid collation sequence, add it as a new entry. */
+ /* Check the space of the arrays. */
+ if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
+ {
+ /* Not enough, realloc it. */
+ /* +1 in case of mbcset->ncoll_syms is 0. */
+ int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+ /* Use realloc since mbcset->coll_syms is NULL
+ if *alloc == 0. */
+ int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
+ new_coll_sym_alloc);
+ if (BE (new_coll_syms == NULL, 0))
+ return REG_ESPACE;
+ mbcset->coll_syms = new_coll_syms;
+ *coll_sym_alloc = new_coll_sym_alloc;
+ }
+ mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+ return REG_NOERROR;
+ }
+ else
+ {
+ if (BE (name_len != 1, 0))
+ return REG_ECOLLATE;
+ else
+ {
+ bitset_set (sbcset, name[0]);
+ return REG_NOERROR;
+ }
+ }
+ }
+#endif
+
+ re_token_t br_token;
+ re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+ re_charset_t *mbcset;
+ int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
+ int equiv_class_alloc = 0, char_class_alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+ int non_match = 0;
+ bin_tree_t *work_tree;
+ int token_len;
+ int first_round = 1;
+#ifdef _LIBC
+ collseqmb = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+ if (nrules)
+ {
+ /*
+ if (MB_CUR_MAX > 1)
+ */
+ collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+ table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
+ symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_SYMB_TABLEMB);
+ extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_SYMB_EXTRAMB);
+ }
+#endif
+ sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
+#ifdef RE_ENABLE_I18N
+ mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+#ifdef RE_ENABLE_I18N
+ if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else
+ if (BE (sbcset == NULL, 0))
+#endif /* RE_ENABLE_I18N */
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+
+ token_len = peek_token_bracket (token, regexp, syntax);
+ if (BE (token->type == END_OF_RE, 0))
+ {
+ *err = REG_BADPAT;
+ goto parse_bracket_exp_free_return;
+ }
+ if (token->type == OP_NON_MATCH_LIST)
+ {
+#ifdef RE_ENABLE_I18N
+ mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+ non_match = 1;
+ if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+ bitset_set (sbcset, '\0');
+ re_string_skip_bytes (regexp, token_len); /* Skip a token. */
+ token_len = peek_token_bracket (token, regexp, syntax);
+ if (BE (token->type == END_OF_RE, 0))
+ {
+ *err = REG_BADPAT;
+ goto parse_bracket_exp_free_return;
+ }
+ }
+
+ /* We treat the first ']' as a normal character. */
+ if (token->type == OP_CLOSE_BRACKET)
+ token->type = CHARACTER;
+
+ while (1)
+ {
+ bracket_elem_t start_elem, end_elem;
+ unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
+ unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
+ reg_errcode_t ret;
+ int token_len2 = 0, is_range_exp = 0;
+ re_token_t token2;
+
+ start_elem.opr.name = start_name_buf;
+ ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
+ syntax, first_round);
+ if (BE (ret != REG_NOERROR, 0))
+ {
+ *err = ret;
+ goto parse_bracket_exp_free_return;
+ }
+ first_round = 0;
+
+ /* Get information about the next token. We need it in any case. */
+ token_len = peek_token_bracket (token, regexp, syntax);
+
+ /* Do not check for ranges if we know they are not allowed. */
+ if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
+ {
+ if (BE (token->type == END_OF_RE, 0))
+ {
+ *err = REG_EBRACK;
+ goto parse_bracket_exp_free_return;
+ }
+ if (token->type == OP_CHARSET_RANGE)
+ {
+ re_string_skip_bytes (regexp, token_len); /* Skip '-'. */
+ token_len2 = peek_token_bracket (&token2, regexp, syntax);
+ if (BE (token2.type == END_OF_RE, 0))
+ {
+ *err = REG_EBRACK;
+ goto parse_bracket_exp_free_return;
+ }
+ if (token2.type == OP_CLOSE_BRACKET)
+ {
+ /* We treat the last '-' as a normal character. */
+ re_string_skip_bytes (regexp, -token_len);
+ token->type = CHARACTER;
+ }
+ else
+ is_range_exp = 1;
+ }
+ }
+
+ if (is_range_exp == 1)
+ {
+ end_elem.opr.name = end_name_buf;
+ ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
+ dfa, syntax, 1);
+ if (BE (ret != REG_NOERROR, 0))
+ {
+ *err = ret;
+ goto parse_bracket_exp_free_return;
+ }
+
+ token_len = peek_token_bracket (token, regexp, syntax);
+
+#ifdef _LIBC
+ *err = build_range_exp (sbcset, mbcset, &range_alloc,
+ &start_elem, &end_elem);
+#else
+# ifdef RE_ENABLE_I18N
+ *err = build_range_exp (sbcset,
+ dfa->mb_cur_max > 1 ? mbcset : NULL,
+ &range_alloc, &start_elem, &end_elem);
+# else
+ *err = build_range_exp (sbcset, &start_elem, &end_elem);
+# endif
+#endif /* RE_ENABLE_I18N */
+ if (BE (*err != REG_NOERROR, 0))
+ goto parse_bracket_exp_free_return;
+ }
+ else
+ {
+ switch (start_elem.type)
+ {
+ case SB_CHAR:
+ bitset_set (sbcset, start_elem.opr.ch);
+ break;
+#ifdef RE_ENABLE_I18N
+ case MB_CHAR:
+ /* Check whether the array has enough space. */
+ if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+ {
+ wchar_t *new_mbchars;
+ /* Not enough, realloc it. */
+ /* +1 in case of mbcset->nmbchars is 0. */
+ mbchar_alloc = 2 * mbcset->nmbchars + 1;
+ /* Use realloc since array is NULL if *alloc == 0. */
+ new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
+ mbchar_alloc);
+ if (BE (new_mbchars == NULL, 0))
+ goto parse_bracket_exp_espace;
+ mbcset->mbchars = new_mbchars;
+ }
+ mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+ break;
+#endif /* RE_ENABLE_I18N */
+ case EQUIV_CLASS:
+ *err = build_equiv_class (sbcset,
+#ifdef RE_ENABLE_I18N
+ mbcset, &equiv_class_alloc,
+#endif /* RE_ENABLE_I18N */
+ start_elem.opr.name);
+ if (BE (*err != REG_NOERROR, 0))
+ goto parse_bracket_exp_free_return;
+ break;
+ case COLL_SYM:
+ *err = build_collating_symbol (sbcset,
+#ifdef RE_ENABLE_I18N
+ mbcset, &coll_sym_alloc,
+#endif /* RE_ENABLE_I18N */
+ start_elem.opr.name);
+ if (BE (*err != REG_NOERROR, 0))
+ goto parse_bracket_exp_free_return;
+ break;
+ case CHAR_CLASS:
+ *err = build_charclass (regexp->trans, sbcset,
+#ifdef RE_ENABLE_I18N
+ mbcset, &char_class_alloc,
+#endif /* RE_ENABLE_I18N */
+ (const char *) start_elem.opr.name, syntax);
+ if (BE (*err != REG_NOERROR, 0))
+ goto parse_bracket_exp_free_return;
+ break;
+ default:
+ assert (0);
+ break;
+ }
+ }
+ if (BE (token->type == END_OF_RE, 0))
+ {
+ *err = REG_EBRACK;
+ goto parse_bracket_exp_free_return;
+ }
+ if (token->type == OP_CLOSE_BRACKET)
+ break;
+ }
+
+ re_string_skip_bytes (regexp, token_len); /* Skip a token. */
+
+ /* If it is non-matching list. */
+ if (non_match)
+ bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+ /* Ensure only single byte characters are set. */
+ if (dfa->mb_cur_max > 1)
+ bitset_mask (sbcset, dfa->sb_char);
+
+ if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+ || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
+ || mbcset->non_match)))
+ {
+ bin_tree_t *mbc_tree;
+ int sbc_idx;
+ /* Build a tree for complex bracket. */
+ dfa->has_mb_node = 1;
+ br_token.type = COMPLEX_BRACKET;
+ br_token.opr.mbcset = mbcset;
+ mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+ if (BE (mbc_tree == NULL, 0))
+ goto parse_bracket_exp_espace;
+ for (sbc_idx = 0; sbc_idx < BITSET_UINTS; ++sbc_idx)
+ if (sbcset[sbc_idx])
+ break;
+ /* If there are no bits set in sbcset, there is no point
+ of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */
+ if (sbc_idx < BITSET_UINTS)
+ {
+ /* Build a tree for simple bracket. */
+ br_token.type = SIMPLE_BRACKET;
+ br_token.opr.sbcset = sbcset;
+ work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+ if (BE (work_tree == NULL, 0))
+ goto parse_bracket_exp_espace;
+
+ /* Then join them by ALT node. */
+ work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
+ if (BE (work_tree == NULL, 0))
+ goto parse_bracket_exp_espace;
+ }
+ else
+ {
+ re_free (sbcset);
+ work_tree = mbc_tree;
+ }
+ }
+ else
+#endif /* not RE_ENABLE_I18N */
+ {
+#ifdef RE_ENABLE_I18N
+ free_charset (mbcset);
+#endif
+ /* Build a tree for simple bracket. */
+ br_token.type = SIMPLE_BRACKET;
+ br_token.opr.sbcset = sbcset;
+ work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+ if (BE (work_tree == NULL, 0))
+ goto parse_bracket_exp_espace;
+ }
+ return work_tree;
+
+ parse_bracket_exp_espace:
+ *err = REG_ESPACE;
+ parse_bracket_exp_free_return:
+ re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+ free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+ return NULL;
+}
+
+/* Parse an element in the bracket expression. */
+
+static reg_errcode_t
+parse_bracket_element (elem, regexp, token, token_len, dfa, syntax,
+ accept_hyphen)
+ bracket_elem_t *elem;
+ re_string_t *regexp;
+ re_token_t *token;
+ int token_len;
+ re_dfa_t *dfa;
+ reg_syntax_t syntax;
+ int accept_hyphen;
+{
+#ifdef RE_ENABLE_I18N
+ int cur_char_size;
+ cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+ if (cur_char_size > 1)
+ {
+ elem->type = MB_CHAR;
+ elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
+ re_string_skip_bytes (regexp, cur_char_size);
+ return REG_NOERROR;
+ }
+#endif /* RE_ENABLE_I18N */
+ re_string_skip_bytes (regexp, token_len); /* Skip a token. */
+ if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+ || token->type == OP_OPEN_EQUIV_CLASS)
+ return parse_bracket_symbol (elem, regexp, token);
+ if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
+ {
+ /* A '-' must only appear as anything but a range indicator before
+ the closing bracket. Everything else is an error. */
+ re_token_t token2;
+ (void) peek_token_bracket (&token2, regexp, syntax);
+ if (token2.type != OP_CLOSE_BRACKET)
+ /* The actual error value is not standardized since this whole
+ case is undefined. But ERANGE makes good sense. */
+ return REG_ERANGE;
+ }
+ elem->type = SB_CHAR;
+ elem->opr.ch = token->opr.c;
+ return REG_NOERROR;
+}
+
+/* Parse a bracket symbol in the bracket expression. Bracket symbols are
+ such as [:<character_class>:], [.<collating_element>.], and
+ [=<equivalent_class>=]. */
+
+static reg_errcode_t
+parse_bracket_symbol (elem, regexp, token)
+ bracket_elem_t *elem;
+ re_string_t *regexp;
+ re_token_t *token;
+{
+ unsigned char ch, delim = token->opr.c;
+ int i = 0;
+ if (re_string_eoi(regexp))
+ return REG_EBRACK;
+ for (;; ++i)
+ {
+ if (i >= BRACKET_NAME_BUF_SIZE)
+ return REG_EBRACK;
+ if (token->type == OP_OPEN_CHAR_CLASS)
+ ch = re_string_fetch_byte_case (regexp);
+ else
+ ch = re_string_fetch_byte (regexp);
+ if (re_string_eoi(regexp))
+ return REG_EBRACK;
+ if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
+ break;
+ elem->opr.name[i] = ch;
+ }
+ re_string_skip_bytes (regexp, 1);
+ elem->opr.name[i] = '\0';
+ switch (token->type)
+ {
+ case OP_OPEN_COLL_ELEM:
+ elem->type = COLL_SYM;
+ break;
+ case OP_OPEN_EQUIV_CLASS:
+ elem->type = EQUIV_CLASS;
+ break;
+ case OP_OPEN_CHAR_CLASS:
+ elem->type = CHAR_CLASS;
+ break;
+ default:
+ break;
+ }
+ return REG_NOERROR;
+}
+
+ /* Helper function for parse_bracket_exp.
+ Build the equivalence class which is represented by NAME.
+ The result are written to MBCSET and SBCSET.
+ EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
+ is a pointer argument sinse we may update it. */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_equiv_class (sbcset, mbcset, equiv_class_alloc, name)
+ re_charset_t *mbcset;
+ int *equiv_class_alloc;
+#else /* not RE_ENABLE_I18N */
+build_equiv_class (sbcset, name)
+#endif /* not RE_ENABLE_I18N */
+ re_bitset_ptr_t sbcset;
+ const unsigned char *name;
+{
+#if defined _LIBC
+ uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+ if (nrules != 0)
+ {
+ const int32_t *table, *indirect;
+ const unsigned char *weights, *extra, *cp;
+ unsigned char char_buf[2];
+ int32_t idx1, idx2;
+ unsigned int ch;
+ size_t len;
+ /* This #include defines a local function! */
+# include <locale/weight.h>
+ /* Calculate the index for equivalence class. */
+ cp = name;
+ table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+ weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_WEIGHTMB);
+ extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_EXTRAMB);
+ indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_INDIRECTMB);
+ idx1 = findidx (&cp);
+ if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
+ /* This isn't a valid character. */
+ return REG_ECOLLATE;
+
+ /* Build single byte matcing table for this equivalence class. */
+ char_buf[1] = (unsigned char) '\0';
+ len = weights[idx1];
+ for (ch = 0; ch < SBC_MAX; ++ch)
+ {
+ char_buf[0] = ch;
+ cp = char_buf;
+ idx2 = findidx (&cp);
+/*
+ idx2 = table[ch];
+*/
+ if (idx2 == 0)
+ /* This isn't a valid character. */
+ continue;
+ if (len == weights[idx2])
+ {
+ int cnt = 0;
+ while (cnt <= len &&
+ weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt])
+ ++cnt;
+
+ if (cnt > len)
+ bitset_set (sbcset, ch);
+ }
+ }
+ /* Check whether the array has enough space. */
+ if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
+ {
+ /* Not enough, realloc it. */
+ /* +1 in case of mbcset->nequiv_classes is 0. */
+ int new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
+ /* Use realloc since the array is NULL if *alloc == 0. */
+ int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
+ int32_t,
+ new_equiv_class_alloc);
+ if (BE (new_equiv_classes == NULL, 0))
+ return REG_ESPACE;
+ mbcset->equiv_classes = new_equiv_classes;
+ *equiv_class_alloc = new_equiv_class_alloc;
+ }
+ mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+ }
+ else
+#endif /* _LIBC */
+ {
+ if (BE (strlen ((const char *) name) != 1, 0))
+ return REG_ECOLLATE;
+ bitset_set (sbcset, *name);
+ }
+ return REG_NOERROR;
+}
+
+ /* Helper function for parse_bracket_exp.
+ Build the character class which is represented by NAME.
+ The result are written to MBCSET and SBCSET.
+ CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
+ is a pointer argument sinse we may update it. */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_charclass (trans, sbcset, mbcset, char_class_alloc, class_name, syntax)
+ re_charset_t *mbcset;
+ int *char_class_alloc;
+#else /* not RE_ENABLE_I18N */
+build_charclass (trans, sbcset, class_name, syntax)
+#endif /* not RE_ENABLE_I18N */
+ unsigned RE_TRANSLATE_TYPE trans;
+ re_bitset_ptr_t sbcset;
+ const char *class_name;
+ reg_syntax_t syntax;
+{
+ int i;
+
+ /* In case of REG_ICASE "upper" and "lower" match the both of
+ upper and lower cases. */
+ if ((syntax & RE_ICASE)
+ && (strcmp (class_name, "upper") == 0 || strcmp (class_name, "lower") == 0))
+ class_name = "alpha";
+
+#ifdef RE_ENABLE_I18N
+ /* Check the space of the arrays. */
+ if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+ {
+ /* Not enough, realloc it. */
+ /* +1 in case of mbcset->nchar_classes is 0. */
+ int new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
+ /* Use realloc since array is NULL if *alloc == 0. */
+ wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
+ new_char_class_alloc);
+ if (BE (new_char_classes == NULL, 0))
+ return REG_ESPACE;
+ mbcset->char_classes = new_char_classes;
+ *char_class_alloc = new_char_class_alloc;
+ }
+ mbcset->char_classes[mbcset->nchar_classes++] = __wctype (class_name);
+#endif /* RE_ENABLE_I18N */
+
+#define BUILD_CHARCLASS_LOOP(ctype_func) \
+ for (i = 0; i < SBC_MAX; ++i) \
+ { \
+ if (ctype_func (i)) \
+ { \
+ int ch = trans ? trans[i] : i; \
+ bitset_set (sbcset, ch); \
+ } \
+ }
+
+ if (strcmp (class_name, "alnum") == 0)
+ BUILD_CHARCLASS_LOOP (isalnum)
+ else if (strcmp (class_name, "cntrl") == 0)
+ BUILD_CHARCLASS_LOOP (iscntrl)
+ else if (strcmp (class_name, "lower") == 0)
+ BUILD_CHARCLASS_LOOP (islower)
+ else if (strcmp (class_name, "space") == 0)
+ BUILD_CHARCLASS_LOOP (isspace)
+ else if (strcmp (class_name, "alpha") == 0)
+ BUILD_CHARCLASS_LOOP (isalpha)
+ else if (strcmp (class_name, "digit") == 0)
+ BUILD_CHARCLASS_LOOP (isdigit)
+ else if (strcmp (class_name, "print") == 0)
+ BUILD_CHARCLASS_LOOP (isprint)
+ else if (strcmp (class_name, "upper") == 0)
+ BUILD_CHARCLASS_LOOP (isupper)
+#ifndef GAWK
+ else if (strcmp (class_name, "blank") == 0)
+ BUILD_CHARCLASS_LOOP (isblank)
+#else
+ /* see comments above */
+ else if (strcmp (class_name, "blank") == 0)
+ BUILD_CHARCLASS_LOOP (is_blank)
+#endif
+ else if (strcmp (class_name, "graph") == 0)
+ BUILD_CHARCLASS_LOOP (isgraph)
+ else if (strcmp (class_name, "punct") == 0)
+ BUILD_CHARCLASS_LOOP (ispunct)
+ else if (strcmp (class_name, "xdigit") == 0)
+ BUILD_CHARCLASS_LOOP (isxdigit)
+ else
+ return REG_ECTYPE;
+
+ return REG_NOERROR;
+}
+
+static bin_tree_t *
+build_charclass_op (dfa, trans, class_name, extra, non_match, err)
+ re_dfa_t *dfa;
+ unsigned RE_TRANSLATE_TYPE trans;
+ const char *class_name;
+ const char *extra;
+ int non_match;
+ reg_errcode_t *err;
+{
+ re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+ re_charset_t *mbcset;
+ int alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+ reg_errcode_t ret;
+ re_token_t br_token;
+ bin_tree_t *tree;
+
+ sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
+#ifdef RE_ENABLE_I18N
+ mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+
+#ifdef RE_ENABLE_I18N
+ if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else /* not RE_ENABLE_I18N */
+ if (BE (sbcset == NULL, 0))
+#endif /* not RE_ENABLE_I18N */
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+
+ if (non_match)
+ {
+#ifdef RE_ENABLE_I18N
+ /*
+ if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+ bitset_set(cset->sbcset, '\0');
+ */
+ mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+ }
+
+ /* We don't care the syntax in this case. */
+ ret = build_charclass (trans, sbcset,
+#ifdef RE_ENABLE_I18N
+ mbcset, &alloc,
+#endif /* RE_ENABLE_I18N */
+ class_name, 0);
+
+ if (BE (ret != REG_NOERROR, 0))
+ {
+ re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+ free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+ *err = ret;
+ return NULL;
+ }
+ /* \w match '_' also. */
+ for (; *extra; extra++)
+ bitset_set (sbcset, *extra);
+
+ /* If it is non-matching list. */
+ if (non_match)
+ bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+ /* Ensure only single byte characters are set. */
+ if (dfa->mb_cur_max > 1)
+ bitset_mask (sbcset, dfa->sb_char);
+#endif
+
+ /* Build a tree for simple bracket. */
+ br_token.type = SIMPLE_BRACKET;
+ br_token.opr.sbcset = sbcset;
+ tree = create_token_tree (dfa, NULL, NULL, &br_token);
+ if (BE (tree == NULL, 0))
+ goto build_word_op_espace;
+
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ {
+ bin_tree_t *mbc_tree;
+ /* Build a tree for complex bracket. */
+ br_token.type = COMPLEX_BRACKET;
+ br_token.opr.mbcset = mbcset;
+ dfa->has_mb_node = 1;
+ mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+ if (BE (mbc_tree == NULL, 0))
+ goto build_word_op_espace;
+ /* Then join them by ALT node. */
+ tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
+ if (BE (mbc_tree != NULL, 1))
+ return tree;
+ }
+ else
+ {
+ free_charset (mbcset);
+ return tree;
+ }
+#else /* not RE_ENABLE_I18N */
+ return tree;
+#endif /* not RE_ENABLE_I18N */
+
+ build_word_op_espace:
+ re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+ free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+ *err = REG_ESPACE;
+ return NULL;
+}
+
+/* This is intended for the expressions like "a{1,3}".
+ Fetch a number from `input', and return the number.
+ Return -1, if the number field is empty like "{,1}".
+ Return -2, If an error is occured. */
+
+static int
+fetch_number (input, token, syntax)
+ re_string_t *input;
+ re_token_t *token;
+ reg_syntax_t syntax;
+{
+ int num = -1;
+ unsigned char c;
+ while (1)
+ {
+ fetch_token (token, input, syntax);
+ c = token->opr.c;
+ if (BE (token->type == END_OF_RE, 0))
+ return -2;
+ if (token->type == OP_CLOSE_DUP_NUM || c == ',')
+ break;
+ num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)
+ ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0'));
+ num = (num > RE_DUP_MAX) ? -2 : num;
+ }
+ return num;
+}
+\f
+#ifdef RE_ENABLE_I18N
+static void
+free_charset (re_charset_t *cset)
+{
+ re_free (cset->mbchars);
+# ifdef _LIBC
+ re_free (cset->coll_syms);
+ re_free (cset->equiv_classes);
+ re_free (cset->range_starts);
+ re_free (cset->range_ends);
+# endif
+ re_free (cset->char_classes);
+ re_free (cset);
+}
+#endif /* RE_ENABLE_I18N */
+\f
+/* Functions for binary tree operation. */
+
+/* Create a tree node. */
+
+static bin_tree_t *
+create_tree (dfa, left, right, type)
+ re_dfa_t *dfa;
+ bin_tree_t *left;
+ bin_tree_t *right;
+ re_token_type_t type;
+{
+ re_token_t t;
+ t.type = type;
+ return create_token_tree (dfa, left, right, &t);
+}
+
+static bin_tree_t *
+create_token_tree (dfa, left, right, token)
+ re_dfa_t *dfa;
+ bin_tree_t *left;
+ bin_tree_t *right;
+ const re_token_t *token;
+{
+ bin_tree_t *tree;
+ if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
+ {
+ bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
+
+ if (storage == NULL)
+ return NULL;
+ storage->next = dfa->str_tree_storage;
+ dfa->str_tree_storage = storage;
+ dfa->str_tree_storage_idx = 0;
+ }
+ tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
+
+ tree->parent = NULL;
+ tree->left = left;
+ tree->right = right;
+ tree->token = *token;
+ tree->token.duplicated = 0;
+ tree->token.opt_subexp = 0;
+ tree->first = NULL;
+ tree->next = NULL;
+ tree->node_idx = -1;
+
+ if (left != NULL)
+ left->parent = tree;
+ if (right != NULL)
+ right->parent = tree;
+ return tree;
+}
+
+/* Mark the tree SRC as an optional subexpression.
+ To be called from preorder or postorder. */
+
+static reg_errcode_t
+mark_opt_subexp (extra, node)
+ void *extra;
+ bin_tree_t *node;
+{
+ int idx = (int) (long) extra;
+ if (node->token.type == SUBEXP && node->token.opr.idx == idx)
+ node->token.opt_subexp = 1;
+
+ return REG_NOERROR;
+}
+
+/* Free the allocated memory inside NODE. */
+
+static void
+free_token (re_token_t *node)
+{
+#ifdef RE_ENABLE_I18N
+ if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
+ free_charset (node->opr.mbcset);
+ else
+#endif /* RE_ENABLE_I18N */
+ if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+ re_free (node->opr.sbcset);
+}
+
+/* Worker function for tree walking. Free the allocated memory inside NODE
+ and its children. */
+
+static reg_errcode_t
+free_tree (void *extra, bin_tree_t *node)
+{
+ free_token (&node->token);
+ return REG_NOERROR;
+}
+
+
+/* Duplicate the node SRC, and return new node. This is a preorder
+ visit similar to the one implemented by the generic visitor, but
+ we need more infrastructure to maintain two parallel trees --- so,
+ it's easier to duplicate. */
+
+static bin_tree_t *
+duplicate_tree (root, dfa)
+ const bin_tree_t *root;
+ re_dfa_t *dfa;
+{
+ const bin_tree_t *node;
+ bin_tree_t *dup_root;
+ bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
+
+ for (node = root; ; )
+ {
+ /* Create a new tree and link it back to the current parent. */
+ *p_new = create_token_tree (dfa, NULL, NULL, &node->token);
+ if (*p_new == NULL)
+ return NULL;
+ (*p_new)->parent = dup_node;
+ (*p_new)->token.duplicated = 1;
+ dup_node = *p_new;
+
+ /* Go to the left node, or up and to the right. */
+ if (node->left)
+ {
+ node = node->left;
+ p_new = &dup_node->left;
+ }
+ else
+ {
+ const bin_tree_t *prev = NULL;
+ while (node->right == prev || node->right == NULL)
+ {
+ prev = node;
+ node = node->parent;
+ dup_node = dup_node->parent;
+ if (!node)
+ return dup_root;
+ }
+ node = node->right;
+ p_new = &dup_node->right;
+ }
+ }
+}
--- /dev/null
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef _LIBC
+/* We have to keep the namespace clean. */
+# define regfree(preg) __regfree (preg)
+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
+# define regerror(errcode, preg, errbuf, errbuf_size) \
+ __regerror(errcode, preg, errbuf, errbuf_size)
+# define re_set_registers(bu, re, nu, st, en) \
+ __re_set_registers (bu, re, nu, st, en)
+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
+ __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+# define re_match(bufp, string, size, pos, regs) \
+ __re_match (bufp, string, size, pos, regs)
+# define re_search(bufp, string, size, startpos, range, regs) \
+ __re_search (bufp, string, size, startpos, range, regs)
+# define re_compile_pattern(pattern, length, bufp) \
+ __re_compile_pattern (pattern, length, bufp)
+# define re_set_syntax(syntax) __re_set_syntax (syntax)
+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
+ __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
+
+# include "../locale/localeinfo.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+#include <sys/types.h>
+#endif
+
+#if defined (_MSC_VER)
+#include <stdio.h> /* for size_t */
+#endif
+
+/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
+ GNU regex allows. Include it before <regex.h>, which correctly
+ #undefs RE_DUP_MAX and sets it to the right value. */
+#include <limits.h>
+
+#include <regex.h>
+#include "regex_internal.h"
+
+#include "regex_internal.c"
+#include "regcomp.c"
+#include "regexec.c"
+
+/* Binary backward compatibility. */
+#if _LIBC
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
+int re_max_failures = 2000;
+# endif
+#endif
--- /dev/null
+/* Definitions for data structures and routines for the regular
+ expression library.
+ Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+/* Allow the use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+# include <stddef.h>
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+ wide enough to hold a value of a pointer. For most ANSI compilers
+ ptrdiff_t and size_t should be likely OK. Still size of these two
+ types is 2 for Microsoft C. Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned long int reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+ without further backtracking. */
+#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+ If not set, then the GNU regex operators are recognized. */
+#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+ If not set, and debugging was on, turn it off.
+ This only works if regex.c is compiled -DDEBUG.
+ We define this bit always, so that all that's needed to turn on
+ debugging is to recompile regex.c; the calling code can always have
+ this bit set, and it won't affect anything in the normal case. */
+#define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+ a string of ordinary characters. For example, the ERE 'a{1' is
+ treated as 'a\{1'. */
+#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+ for ^, because it is difficult to scan the regex backwards to find
+ whether ^ should be special. */
+#define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in an bre or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+ re_compile_pattern. */
+#define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+\f
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK \
+ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
+ & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \
+ | RE_CONTEXT_INVALID_OPS ))
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
+ | RE_INTERVALS | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \
+ | RE_INVALID_INTERVAL_ORD)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+ removed and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+\f
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+# undef RE_DUP_MAX
+#endif
+/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
+#define RE_DUP_MAX (0x7fff)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+ buffer. */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+#ifdef _XOPEN_SOURCE
+ REG_ENOSYS = -1, /* This will never happen for this implementation. */
+#endif
+
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Inalid collating element. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+\f
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+#ifndef RE_TRANSLATE_TYPE
+# define RE_TRANSLATE_TYPE char *
+#endif
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long int allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long int used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ RE_TRANSLATE_TYPE translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+\f
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+\f
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+# define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+# define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, size_t length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+# ifndef _CRAY
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+ "restrict", and "configure" may have defined "restrict". */
+#ifndef __restrict
+# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
+# if defined restrict || 199901L <= __STDC_VERSION__
+# define __restrict restrict
+# else
+# define __restrict
+# endif
+# endif
+#endif
+/* gcc 3.1 and up support the [restrict] syntax. */
+#ifndef __restrict_arr
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define __restrict_arr __restrict
+# else
+# define __restrict_arr
+# endif
+#endif
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *__restrict __preg,
+ const char *__restrict __pattern,
+ int __cflags));
+
+extern int regexec _RE_ARGS ((const regex_t *__restrict __preg,
+ const char *__restrict __string, size_t __nmatch,
+ regmatch_t __pmatch[__restrict_arr],
+ int __eflags));
+
+extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
+ char *__errbuf, size_t __errbuf_size));
+
+extern void regfree _RE_ARGS ((regex_t *__preg));
+
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* regex.h */
+\f
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
--- /dev/null
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+static void re_string_construct_common (const char *str, int len,
+ re_string_t *pstr,
+ RE_TRANSLATE_TYPE trans, int icase,
+ const re_dfa_t *dfa) internal_function;
+#ifdef RE_ENABLE_I18N
+static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx,
+ wint_t *last_wc) internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t register_state (re_dfa_t *dfa, re_dfastate_t *newstate,
+ unsigned int hash) internal_function;
+static re_dfastate_t *create_ci_newstate (re_dfa_t *dfa,
+ const re_node_set *nodes,
+ unsigned int hash) internal_function;
+static re_dfastate_t *create_cd_newstate (re_dfa_t *dfa,
+ const re_node_set *nodes,
+ unsigned int context,
+ unsigned int hash) internal_function;
+static unsigned int inline calc_state_hash (const re_node_set *nodes,
+ unsigned int context) internal_function;
+\f
+/* Functions for string operation. */
+
+/* This function allocate the buffers. It is necessary to call
+ re_string_reconstruct before using the object. */
+
+static reg_errcode_t
+re_string_allocate (pstr, str, len, init_len, trans, icase, dfa)
+ re_string_t *pstr;
+ const char *str;
+ int len, init_len, icase;
+ RE_TRANSLATE_TYPE trans;
+ const re_dfa_t *dfa;
+{
+ reg_errcode_t ret;
+ int init_buf_len;
+
+ /* Ensure at least one character fits into the buffers. */
+ if (init_len < dfa->mb_cur_max)
+ init_len = dfa->mb_cur_max;
+ init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+ re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+ ret = re_string_realloc_buffers (pstr, init_buf_len);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+
+ pstr->word_char = dfa->word_char;
+ pstr->word_ops_used = dfa->word_ops_used;
+ pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+ pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
+ pstr->valid_raw_len = pstr->valid_len;
+ return REG_NOERROR;
+}
+
+/* This function allocate the buffers, and initialize them. */
+
+static reg_errcode_t
+re_string_construct (pstr, str, len, trans, icase, dfa)
+ re_string_t *pstr;
+ const char *str;
+ int len, icase;
+ RE_TRANSLATE_TYPE trans;
+ const re_dfa_t *dfa;
+{
+ reg_errcode_t ret;
+ memset (pstr, '\0', sizeof (re_string_t));
+ re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+ if (len > 0)
+ {
+ ret = re_string_realloc_buffers (pstr, len + 1);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ }
+ pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+
+ if (icase)
+ {
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ {
+ while (1)
+ {
+ ret = build_wcs_upper_buffer (pstr);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ if (pstr->valid_raw_len >= len)
+ break;
+ if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
+ break;
+ ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ }
+ }
+ else
+#endif /* RE_ENABLE_I18N */
+ build_upper_buffer (pstr);
+ }
+ else
+ {
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ build_wcs_buffer (pstr);
+ else
+#endif /* RE_ENABLE_I18N */
+ {
+ if (trans != NULL)
+ re_string_translate_buffer (pstr);
+ else
+ {
+ pstr->valid_len = pstr->bufs_len;
+ pstr->valid_raw_len = pstr->bufs_len;
+ }
+ }
+ }
+
+ return REG_NOERROR;
+}
+
+/* Helper functions for re_string_allocate, and re_string_construct. */
+
+static reg_errcode_t
+re_string_realloc_buffers (pstr, new_buf_len)
+ re_string_t *pstr;
+ int new_buf_len;
+{
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ {
+ wint_t *new_array = re_realloc (pstr->wcs, wint_t, new_buf_len);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ pstr->wcs = new_array;
+ if (pstr->offsets != NULL)
+ {
+ int *new_array = re_realloc (pstr->offsets, int, new_buf_len);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ pstr->offsets = new_array;
+ }
+ }
+#endif /* RE_ENABLE_I18N */
+ if (pstr->mbs_allocated)
+ {
+ unsigned char *new_array = re_realloc (pstr->mbs, unsigned char,
+ new_buf_len);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ pstr->mbs = new_array;
+ }
+ pstr->bufs_len = new_buf_len;
+ return REG_NOERROR;
+}
+
+
+static void
+re_string_construct_common (str, len, pstr, trans, icase, dfa)
+ const char *str;
+ int len;
+ re_string_t *pstr;
+ RE_TRANSLATE_TYPE trans;
+ int icase;
+ const re_dfa_t *dfa;
+{
+ pstr->raw_mbs = (const unsigned char *) str;
+ pstr->len = len;
+ pstr->raw_len = len;
+ pstr->trans = (unsigned RE_TRANSLATE_TYPE) trans;
+ pstr->icase = icase ? 1 : 0;
+ pstr->mbs_allocated = (trans != NULL || icase);
+ pstr->mb_cur_max = dfa->mb_cur_max;
+ pstr->is_utf8 = dfa->is_utf8;
+ pstr->map_notascii = dfa->map_notascii;
+ pstr->stop = pstr->len;
+ pstr->raw_stop = pstr->stop;
+}
+
+#ifdef RE_ENABLE_I18N
+
+/* Build wide character buffer PSTR->WCS.
+ If the byte sequence of the string are:
+ <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
+ Then wide character buffer will be:
+ <wc1> , WEOF , <wc2> , WEOF , <wc3>
+ We use WEOF for padding, they indicate that the position isn't
+ a first byte of a multibyte character.
+
+ Note that this function assumes PSTR->VALID_LEN elements are already
+ built and starts from PSTR->VALID_LEN. */
+
+static void
+build_wcs_buffer (pstr)
+ re_string_t *pstr;
+{
+#ifdef _LIBC
+ unsigned char buf[pstr->mb_cur_max];
+#else
+ unsigned char buf[64];
+#endif
+ mbstate_t prev_st;
+ int byte_idx, end_idx, mbclen, remain_len;
+
+ /* Build the buffers from pstr->valid_len to either pstr->len or
+ pstr->bufs_len. */
+ end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+ for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
+ {
+ wchar_t wc;
+ const char *p;
+
+ remain_len = end_idx - byte_idx;
+ prev_st = pstr->cur_state;
+ /* Apply the translation if we need. */
+ if (BE (pstr->trans != NULL, 0))
+ {
+ int i, ch;
+
+ for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+ {
+ ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+ buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+ }
+ p = (const char *) buf;
+ }
+ else
+ p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
+ mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+ if (BE (mbclen == (size_t) -2, 0))
+ {
+ /* The buffer doesn't have enough space, finish to build. */
+ pstr->cur_state = prev_st;
+ break;
+ }
+ else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
+ {
+ /* We treat these cases as a singlebyte character. */
+ mbclen = 1;
+ wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+ if (BE (pstr->trans != NULL, 0))
+ wc = pstr->trans[wc];
+ pstr->cur_state = prev_st;
+ }
+
+ /* Write wide character and padding. */
+ pstr->wcs[byte_idx++] = wc;
+ /* Write paddings. */
+ for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+ pstr->wcs[byte_idx++] = WEOF;
+ }
+ pstr->valid_len = byte_idx;
+ pstr->valid_raw_len = byte_idx;
+}
+
+/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
+ but for REG_ICASE. */
+
+static int
+build_wcs_upper_buffer (pstr)
+ re_string_t *pstr;
+{
+ mbstate_t prev_st;
+ int src_idx, byte_idx, end_idx, mbclen, remain_len;
+#ifdef _LIBC
+ unsigned char buf[pstr->mb_cur_max];
+#else
+ unsigned char buf[64];
+#endif
+
+ byte_idx = pstr->valid_len;
+ end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+ /* The following optimization assumes that ASCII characters can be
+ mapped to wide characters with a simple cast. */
+ if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
+ {
+ while (byte_idx < end_idx)
+ {
+ wchar_t wc;
+
+ if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
+ && mbsinit (&pstr->cur_state))
+ {
+ /* In case of a singlebyte character. */
+ pstr->mbs[byte_idx]
+ = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+ /* The next step uses the assumption that wchar_t is encoded
+ ASCII-safe: all ASCII values can be converted like this. */
+ pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
+ ++byte_idx;
+ continue;
+ }
+
+ remain_len = end_idx - byte_idx;
+ prev_st = pstr->cur_state;
+ mbclen = mbrtowc (&wc,
+ ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+ + byte_idx), remain_len, &pstr->cur_state);
+ if (BE (mbclen > 0, 1))
+ {
+ wchar_t wcu = wc;
+ if (iswlower (wc))
+ {
+ int mbcdlen;
+
+ wcu = towupper (wc);
+ mbcdlen = wcrtomb ((char *)buf, wcu, &prev_st);
+ if (BE (mbclen == mbcdlen, 1))
+ memcpy (pstr->mbs + byte_idx, buf, mbclen);
+ else
+ {
+ src_idx = byte_idx;
+ goto offsets_needed;
+ }
+ }
+ else
+ memcpy (pstr->mbs + byte_idx,
+ pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
+ pstr->wcs[byte_idx++] = wcu;
+ /* Write paddings. */
+ for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+ pstr->wcs[byte_idx++] = WEOF;
+ }
+ else if (mbclen == (size_t) -1 || mbclen == 0)
+ {
+ /* It is an invalid character or '\0'. Just use the byte. */
+ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+ pstr->mbs[byte_idx] = ch;
+ /* And also cast it to wide char. */
+ pstr->wcs[byte_idx++] = (wchar_t) ch;
+ if (BE (mbclen == (size_t) -1, 0))
+ pstr->cur_state = prev_st;
+ }
+ else
+ {
+ /* The buffer doesn't have enough space, finish to build. */
+ pstr->cur_state = prev_st;
+ break;
+ }
+ }
+ pstr->valid_len = byte_idx;
+ pstr->valid_raw_len = byte_idx;
+ return REG_NOERROR;
+ }
+ else
+ for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
+ {
+ wchar_t wc;
+ const char *p;
+
+ offsets_needed:
+ remain_len = end_idx - byte_idx;
+ prev_st = pstr->cur_state;
+ if (BE (pstr->trans != NULL, 0))
+ {
+ int i, ch;
+
+ for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+ {
+ ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+ buf[i] = pstr->trans[ch];
+ }
+ p = (const char *) buf;
+ }
+ else
+ p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
+ mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+ if (BE (mbclen > 0, 1))
+ {
+ wchar_t wcu = wc;
+ if (iswlower (wc))
+ {
+ int mbcdlen;
+
+ wcu = towupper (wc);
+ mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
+ if (BE (mbclen == mbcdlen, 1))
+ memcpy (pstr->mbs + byte_idx, buf, mbclen);
+ else
+ {
+ int i;
+
+ if (byte_idx + mbcdlen > pstr->bufs_len)
+ {
+ pstr->cur_state = prev_st;
+ break;
+ }
+
+ if (pstr->offsets == NULL)
+ {
+ pstr->offsets = re_malloc (int, pstr->bufs_len);
+
+ if (pstr->offsets == NULL)
+ return REG_ESPACE;
+ }
+ if (!pstr->offsets_needed)
+ {
+ for (i = 0; i < byte_idx; ++i)
+ pstr->offsets[i] = i;
+ pstr->offsets_needed = 1;
+ }
+
+ memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
+ pstr->wcs[byte_idx] = wcu;
+ pstr->offsets[byte_idx] = src_idx;
+ for (i = 1; i < mbcdlen; ++i)
+ {
+ pstr->offsets[byte_idx + i]
+ = src_idx + (i < mbclen ? i : mbclen - 1);
+ pstr->wcs[byte_idx + i] = WEOF;
+ }
+ pstr->len += mbcdlen - mbclen;
+ if (pstr->raw_stop > src_idx)
+ pstr->stop += mbcdlen - mbclen;
+ end_idx = (pstr->bufs_len > pstr->len)
+ ? pstr->len : pstr->bufs_len;
+ byte_idx += mbcdlen;
+ src_idx += mbclen;
+ continue;
+ }
+ }
+ else
+ memcpy (pstr->mbs + byte_idx, p, mbclen);
+
+ if (BE (pstr->offsets_needed != 0, 0))
+ {
+ int i;
+ for (i = 0; i < mbclen; ++i)
+ pstr->offsets[byte_idx + i] = src_idx + i;
+ }
+ src_idx += mbclen;
+
+ pstr->wcs[byte_idx++] = wcu;
+ /* Write paddings. */
+ for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+ pstr->wcs[byte_idx++] = WEOF;
+ }
+ else if (mbclen == (size_t) -1 || mbclen == 0)
+ {
+ /* It is an invalid character or '\0'. Just use the byte. */
+ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
+
+ if (BE (pstr->trans != NULL, 0))
+ ch = pstr->trans [ch];
+ pstr->mbs[byte_idx] = ch;
+
+ if (BE (pstr->offsets_needed != 0, 0))
+ pstr->offsets[byte_idx] = src_idx;
+ ++src_idx;
+
+ /* And also cast it to wide char. */
+ pstr->wcs[byte_idx++] = (wchar_t) ch;
+ if (BE (mbclen == (size_t) -1, 0))
+ pstr->cur_state = prev_st;
+ }
+ else
+ {
+ /* The buffer doesn't have enough space, finish to build. */
+ pstr->cur_state = prev_st;
+ break;
+ }
+ }
+ pstr->valid_len = byte_idx;
+ pstr->valid_raw_len = src_idx;
+ return REG_NOERROR;
+}
+
+/* Skip characters until the index becomes greater than NEW_RAW_IDX.
+ Return the index. */
+
+static int
+re_string_skip_chars (pstr, new_raw_idx, last_wc)
+ re_string_t *pstr;
+ int new_raw_idx;
+ wint_t *last_wc;
+{
+ mbstate_t prev_st;
+ int rawbuf_idx, mbclen;
+ wchar_t wc = 0;
+
+ /* Skip the characters which are not necessary to check. */
+ for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
+ rawbuf_idx < new_raw_idx;)
+ {
+ int remain_len;
+ remain_len = pstr->len - rawbuf_idx;
+ prev_st = pstr->cur_state;
+ mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
+ remain_len, &pstr->cur_state);
+ if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
+ {
+ /* We treat these cases as a singlebyte character. */
+ mbclen = 1;
+ pstr->cur_state = prev_st;
+ }
+ /* Then proceed the next character. */
+ rawbuf_idx += mbclen;
+ }
+ *last_wc = (wint_t) wc;
+ return rawbuf_idx;
+}
+#endif /* RE_ENABLE_I18N */
+
+/* Build the buffer PSTR->MBS, and apply the translation if we need.
+ This function is used in case of REG_ICASE. */
+
+static void
+build_upper_buffer (pstr)
+ re_string_t *pstr;
+{
+ int char_idx, end_idx;
+ end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+ for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
+ {
+ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
+ if (BE (pstr->trans != NULL, 0))
+ ch = pstr->trans[ch];
+ if (islower (ch))
+ pstr->mbs[char_idx] = toupper (ch);
+ else
+ pstr->mbs[char_idx] = ch;
+ }
+ pstr->valid_len = char_idx;
+ pstr->valid_raw_len = char_idx;
+}
+
+/* Apply TRANS to the buffer in PSTR. */
+
+static void
+re_string_translate_buffer (pstr)
+ re_string_t *pstr;
+{
+ int buf_idx, end_idx;
+ end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+ for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
+ {
+ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
+ pstr->mbs[buf_idx] = pstr->trans[ch];
+ }
+
+ pstr->valid_len = buf_idx;
+ pstr->valid_raw_len = buf_idx;
+}
+
+/* This function re-construct the buffers.
+ Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+ convert to upper case in case of REG_ICASE, apply translation. */
+
+static reg_errcode_t
+re_string_reconstruct (pstr, idx, eflags)
+ re_string_t *pstr;
+ int idx, eflags;
+{
+ int offset = idx - pstr->raw_mbs_idx;
+ if (BE (offset < 0, 0))
+ {
+ /* Reset buffer. */
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+#endif /* RE_ENABLE_I18N */
+ pstr->len = pstr->raw_len;
+ pstr->stop = pstr->raw_stop;
+ pstr->valid_len = 0;
+ pstr->raw_mbs_idx = 0;
+ pstr->valid_raw_len = 0;
+ pstr->offsets_needed = 0;
+ pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+ : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
+ if (!pstr->mbs_allocated)
+ pstr->mbs = (unsigned char *) pstr->raw_mbs;
+ offset = idx;
+ }
+
+ if (BE (offset != 0, 1))
+ {
+ /* Are the characters which are already checked remain? */
+ if (BE (offset < pstr->valid_raw_len, 1)
+#ifdef RE_ENABLE_I18N
+ /* Handling this would enlarge the code too much.
+ Accept a slowdown in that case. */
+ && pstr->offsets_needed == 0
+#endif
+ )
+ {
+ /* Yes, move them to the front of the buffer. */
+ pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags);
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ memmove (pstr->wcs, pstr->wcs + offset,
+ (pstr->valid_len - offset) * sizeof (wint_t));
+#endif /* RE_ENABLE_I18N */
+ if (BE (pstr->mbs_allocated, 0))
+ memmove (pstr->mbs, pstr->mbs + offset,
+ pstr->valid_len - offset);
+ pstr->valid_len -= offset;
+ pstr->valid_raw_len -= offset;
+#if DEBUG
+ assert (pstr->valid_len > 0);
+#endif
+ }
+ else
+ {
+ /* No, skip all characters until IDX. */
+#ifdef RE_ENABLE_I18N
+ if (BE (pstr->offsets_needed, 0))
+ {
+ pstr->len = pstr->raw_len - idx + offset;
+ pstr->stop = pstr->raw_stop - idx + offset;
+ pstr->offsets_needed = 0;
+ }
+#endif
+ pstr->valid_len = 0;
+ pstr->valid_raw_len = 0;
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ {
+ int wcs_idx;
+ wint_t wc = WEOF;
+
+ if (pstr->is_utf8)
+ {
+ const unsigned char *raw, *p, *q, *end;
+
+ /* Special case UTF-8. Multi-byte chars start with any
+ byte other than 0x80 - 0xbf. */
+ raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+ end = raw + (offset - pstr->mb_cur_max);
+ for (p = raw + offset - 1; p >= end; --p)
+ if ((*p & 0xc0) != 0x80)
+ {
+ mbstate_t cur_state;
+ wchar_t wc2;
+ int mlen = raw + pstr->len - p;
+ unsigned char buf[6];
+
+ q = p;
+ if (BE (pstr->trans != NULL, 0))
+ {
+ int i = mlen < 6 ? mlen : 6;
+ while (--i >= 0)
+ buf[i] = pstr->trans[p[i]];
+ q = buf;
+ }
+ /* XXX Don't use mbrtowc, we know which conversion
+ to use (UTF-8 -> UCS4). */
+ memset (&cur_state, 0, sizeof (cur_state));
+ mlen = mbrtowc (&wc2, p, mlen, &cur_state)
+ - (raw + offset - p);
+ if (mlen >= 0)
+ {
+ memset (&pstr->cur_state, '\0',
+ sizeof (mbstate_t));
+ pstr->valid_len = mlen;
+ wc = wc2;
+ }
+ break;
+ }
+ }
+
+ if (wc == WEOF)
+ pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
+ if (BE (pstr->valid_len, 0))
+ {
+ for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
+ pstr->wcs[wcs_idx] = WEOF;
+ if (pstr->mbs_allocated)
+ memset (pstr->mbs, 255, pstr->valid_len);
+ }
+ pstr->valid_raw_len = pstr->valid_len;
+ pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+ && IS_WIDE_WORD_CHAR (wc))
+ ? CONTEXT_WORD
+ : ((IS_WIDE_NEWLINE (wc)
+ && pstr->newline_anchor)
+ ? CONTEXT_NEWLINE : 0));
+ }
+ else
+#endif /* RE_ENABLE_I18N */
+ {
+ int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+ if (pstr->trans)
+ c = pstr->trans[c];
+ pstr->tip_context = (bitset_contain (pstr->word_char, c)
+ ? CONTEXT_WORD
+ : ((IS_NEWLINE (c) && pstr->newline_anchor)
+ ? CONTEXT_NEWLINE : 0));
+ }
+ }
+ if (!BE (pstr->mbs_allocated, 0))
+ pstr->mbs += offset;
+ }
+ pstr->raw_mbs_idx = idx;
+ pstr->len -= offset;
+ pstr->stop -= offset;
+
+ /* Then build the buffers. */
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ {
+ if (pstr->icase)
+ {
+ int ret = build_wcs_upper_buffer (pstr);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ }
+ else
+ build_wcs_buffer (pstr);
+ }
+ else
+#endif /* RE_ENABLE_I18N */
+ if (BE (pstr->mbs_allocated, 0))
+ {
+ if (pstr->icase)
+ build_upper_buffer (pstr);
+ else if (pstr->trans != NULL)
+ re_string_translate_buffer (pstr);
+ }
+ else
+ pstr->valid_len = pstr->len;
+
+ pstr->cur_idx = 0;
+ return REG_NOERROR;
+}
+
+static unsigned char
+re_string_peek_byte_case (pstr, idx)
+ const re_string_t *pstr;
+ int idx;
+{
+ int ch, off;
+
+ /* Handle the common (easiest) cases first. */
+ if (BE (!pstr->mbs_allocated, 1))
+ return re_string_peek_byte (pstr, idx);
+
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1
+ && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+ return re_string_peek_byte (pstr, idx);
+#endif
+
+ off = pstr->cur_idx + idx;
+#ifdef RE_ENABLE_I18N
+ if (pstr->offsets_needed)
+ off = pstr->offsets[off];
+#endif
+
+ ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+#ifdef RE_ENABLE_I18N
+ /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
+ this function returns CAPITAL LETTER I instead of first byte of
+ DOTLESS SMALL LETTER I. The latter would confuse the parser,
+ since peek_byte_case doesn't advance cur_idx in any way. */
+ if (pstr->offsets_needed && !isascii (ch))
+ return re_string_peek_byte (pstr, idx);
+#endif
+
+ return ch;
+}
+
+static unsigned char
+re_string_fetch_byte_case (pstr)
+ re_string_t *pstr;
+{
+ if (BE (!pstr->mbs_allocated, 1))
+ return re_string_fetch_byte (pstr);
+
+#ifdef RE_ENABLE_I18N
+ if (pstr->offsets_needed)
+ {
+ int off, ch;
+
+ /* For tr_TR.UTF-8 [[:islower:]] there is
+ [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip
+ in that case the whole multi-byte character and return
+ the original letter. On the other side, with
+ [[: DOTLESS SMALL LETTER I return [[:I, as doing
+ anything else would complicate things too much. */
+
+ if (!re_string_first_byte (pstr, pstr->cur_idx))
+ return re_string_fetch_byte (pstr);
+
+ off = pstr->offsets[pstr->cur_idx];
+ ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+ if (! isascii (ch))
+ return re_string_fetch_byte (pstr);
+
+ re_string_skip_bytes (pstr,
+ re_string_char_size_at (pstr, pstr->cur_idx));
+ return ch;
+ }
+#endif
+
+ return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
+}
+
+static void
+re_string_destruct (pstr)
+ re_string_t *pstr;
+{
+#ifdef RE_ENABLE_I18N
+ re_free (pstr->wcs);
+ re_free (pstr->offsets);
+#endif /* RE_ENABLE_I18N */
+ if (pstr->mbs_allocated)
+ re_free (pstr->mbs);
+}
+
+/* Return the context at IDX in INPUT. */
+
+static unsigned int
+re_string_context_at (input, idx, eflags)
+ const re_string_t *input;
+ int idx, eflags;
+{
+ int c;
+ if (BE (idx < 0, 0))
+ /* In this case, we use the value stored in input->tip_context,
+ since we can't know the character in input->mbs[-1] here. */
+ return input->tip_context;
+ if (BE (idx == input->len, 0))
+ return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+ : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+#ifdef RE_ENABLE_I18N
+ if (input->mb_cur_max > 1)
+ {
+ wint_t wc;
+ int wc_idx = idx;
+ while(input->wcs[wc_idx] == WEOF)
+ {
+#ifdef DEBUG
+ /* It must not happen. */
+ assert (wc_idx >= 0);
+#endif
+ --wc_idx;
+ if (wc_idx < 0)
+ return input->tip_context;
+ }
+ wc = input->wcs[wc_idx];
+ if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
+ return CONTEXT_WORD;
+ return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
+ ? CONTEXT_NEWLINE : 0);
+ }
+ else
+#endif
+ {
+ c = re_string_byte_at (input, idx);
+ if (bitset_contain (input->word_char, c))
+ return CONTEXT_WORD;
+ return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
+ }
+}
+\f
+/* Functions for set operation. */
+
+static reg_errcode_t
+re_node_set_alloc (set, size)
+ re_node_set *set;
+ int size;
+{
+ /*
+ * ADR: valgrind says size can be 0, which then doesn't
+ * free the block of size 0. Harumph. This seems
+ * to work ok, though.
+ */
+ if (size == 0)
+ {
+ memset(set, 0, sizeof(*set));
+ return REG_NOERROR;
+ }
+ set->alloc = size;
+ set->nelem = 0;
+ set->elems = re_malloc (int, size);
+ if (BE (set->elems == NULL, 0))
+ return REG_ESPACE;
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+re_node_set_init_1 (set, elem)
+ re_node_set *set;
+ int elem;
+{
+ set->alloc = 1;
+ set->nelem = 1;
+ set->elems = re_malloc (int, 1);
+ if (BE (set->elems == NULL, 0))
+ {
+ set->alloc = set->nelem = 0;
+ return REG_ESPACE;
+ }
+ set->elems[0] = elem;
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+re_node_set_init_2 (set, elem1, elem2)
+ re_node_set *set;
+ int elem1, elem2;
+{
+ set->alloc = 2;
+ set->elems = re_malloc (int, 2);
+ if (BE (set->elems == NULL, 0))
+ return REG_ESPACE;
+ if (elem1 == elem2)
+ {
+ set->nelem = 1;
+ set->elems[0] = elem1;
+ }
+ else
+ {
+ set->nelem = 2;
+ if (elem1 < elem2)
+ {
+ set->elems[0] = elem1;
+ set->elems[1] = elem2;
+ }
+ else
+ {
+ set->elems[0] = elem2;
+ set->elems[1] = elem1;
+ }
+ }
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+re_node_set_init_copy (dest, src)
+ re_node_set *dest;
+ const re_node_set *src;
+{
+ dest->nelem = src->nelem;
+ if (src->nelem > 0)
+ {
+ dest->alloc = dest->nelem;
+ dest->elems = re_malloc (int, dest->alloc);
+ if (BE (dest->elems == NULL, 0))
+ {
+ dest->alloc = dest->nelem = 0;
+ return REG_ESPACE;
+ }
+ memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
+ }
+ else
+ re_node_set_init_empty (dest);
+ return REG_NOERROR;
+}
+
+/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
+ DEST. Return value indicate the error code or REG_NOERROR if succeeded.
+ Note: We assume dest->elems is NULL, when dest->alloc is 0. */
+
+static reg_errcode_t
+re_node_set_add_intersect (dest, src1, src2)
+ re_node_set *dest;
+ const re_node_set *src1, *src2;
+{
+ int i1, i2, is, id, delta, sbase;
+ if (src1->nelem == 0 || src2->nelem == 0)
+ return REG_NOERROR;
+
+ /* We need dest->nelem + 2 * elems_in_intersection; this is a
+ conservative estimate. */
+ if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
+ {
+ int new_alloc = src1->nelem + src2->nelem + dest->alloc;
+ int *new_elems = re_realloc (dest->elems, int, new_alloc);
+ if (BE (new_elems == NULL, 0))
+ return REG_ESPACE;
+ dest->elems = new_elems;
+ dest->alloc = new_alloc;
+ }
+
+ /* Find the items in the intersection of SRC1 and SRC2, and copy
+ into the top of DEST those that are not already in DEST itself. */
+ sbase = dest->nelem + src1->nelem + src2->nelem;
+ i1 = src1->nelem - 1;
+ i2 = src2->nelem - 1;
+ id = dest->nelem - 1;
+ for (;;)
+ {
+ if (src1->elems[i1] == src2->elems[i2])
+ {
+ /* Try to find the item in DEST. Maybe we could binary search? */
+ while (id >= 0 && dest->elems[id] > src1->elems[i1])
+ --id;
+
+ if (id < 0 || dest->elems[id] != src1->elems[i1])
+ dest->elems[--sbase] = src1->elems[i1];
+
+ if (--i1 < 0 || --i2 < 0)
+ break;
+ }
+
+ /* Lower the highest of the two items. */
+ else if (src1->elems[i1] < src2->elems[i2])
+ {
+ if (--i2 < 0)
+ break;
+ }
+ else
+ {
+ if (--i1 < 0)
+ break;
+ }
+ }
+
+ id = dest->nelem - 1;
+ is = dest->nelem + src1->nelem + src2->nelem - 1;
+ delta = is - sbase + 1;
+
+ /* Now copy. When DELTA becomes zero, the remaining
+ DEST elements are already in place; this is more or
+ less the same loop that is in re_node_set_merge. */
+ dest->nelem += delta;
+ if (delta > 0 && id >= 0)
+ for (;;)
+ {
+ if (dest->elems[is] > dest->elems[id])
+ {
+ /* Copy from the top. */
+ dest->elems[id + delta--] = dest->elems[is--];
+ if (delta == 0)
+ break;
+ }
+ else
+ {
+ /* Slide from the bottom. */
+ dest->elems[id + delta] = dest->elems[id];
+ if (--id < 0)
+ break;
+ }
+ }
+
+ /* Copy remaining SRC elements. */
+ memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int));
+
+ return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets SRC1 and SRC2. And store it to
+ DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
+
+static reg_errcode_t
+re_node_set_init_union (dest, src1, src2)
+ re_node_set *dest;
+ const re_node_set *src1, *src2;
+{
+ int i1, i2, id;
+ if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
+ {
+ dest->alloc = src1->nelem + src2->nelem;
+ dest->elems = re_malloc (int, dest->alloc);
+ if (BE (dest->elems == NULL, 0))
+ return REG_ESPACE;
+ }
+ else
+ {
+ if (src1 != NULL && src1->nelem > 0)
+ return re_node_set_init_copy (dest, src1);
+ else if (src2 != NULL && src2->nelem > 0)
+ return re_node_set_init_copy (dest, src2);
+ else
+ re_node_set_init_empty (dest);
+ return REG_NOERROR;
+ }
+ for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
+ {
+ if (src1->elems[i1] > src2->elems[i2])
+ {
+ dest->elems[id++] = src2->elems[i2++];
+ continue;
+ }
+ if (src1->elems[i1] == src2->elems[i2])
+ ++i2;
+ dest->elems[id++] = src1->elems[i1++];
+ }
+ if (i1 < src1->nelem)
+ {
+ memcpy (dest->elems + id, src1->elems + i1,
+ (src1->nelem - i1) * sizeof (int));
+ id += src1->nelem - i1;
+ }
+ else if (i2 < src2->nelem)
+ {
+ memcpy (dest->elems + id, src2->elems + i2,
+ (src2->nelem - i2) * sizeof (int));
+ id += src2->nelem - i2;
+ }
+ dest->nelem = id;
+ return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets DEST and SRC. And store it to
+ DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
+
+static reg_errcode_t
+re_node_set_merge (dest, src)
+ re_node_set *dest;
+ const re_node_set *src;
+{
+ int is, id, sbase, delta;
+ if (src == NULL || src->nelem == 0)
+ return REG_NOERROR;
+ if (dest->alloc < 2 * src->nelem + dest->nelem)
+ {
+ int new_alloc = 2 * (src->nelem + dest->alloc);
+ int *new_buffer = re_realloc (dest->elems, int, new_alloc);
+ if (BE (new_buffer == NULL, 0))
+ return REG_ESPACE;
+ dest->elems = new_buffer;
+ dest->alloc = new_alloc;
+ }
+
+ if (BE (dest->nelem == 0, 0))
+ {
+ dest->nelem = src->nelem;
+ memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
+ return REG_NOERROR;
+ }
+
+ /* Copy into the top of DEST the items of SRC that are not
+ found in DEST. Maybe we could binary search in DEST? */
+ for (sbase = dest->nelem + 2 * src->nelem,
+ is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
+ {
+ if (dest->elems[id] == src->elems[is])
+ is--, id--;
+ else if (dest->elems[id] < src->elems[is])
+ dest->elems[--sbase] = src->elems[is--];
+ else /* if (dest->elems[id] > src->elems[is]) */
+ --id;
+ }
+
+ if (is >= 0)
+ {
+ /* If DEST is exhausted, the remaining items of SRC must be unique. */
+ sbase -= is + 1;
+ memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int));
+ }
+
+ id = dest->nelem - 1;
+ is = dest->nelem + 2 * src->nelem - 1;
+ delta = is - sbase + 1;
+ if (delta == 0)
+ return REG_NOERROR;
+
+ /* Now copy. When DELTA becomes zero, the remaining
+ DEST elements are already in place. */
+ dest->nelem += delta;
+ for (;;)
+ {
+ if (dest->elems[is] > dest->elems[id])
+ {
+ /* Copy from the top. */
+ dest->elems[id + delta--] = dest->elems[is--];
+ if (delta == 0)
+ break;
+ }
+ else
+ {
+ /* Slide from the bottom. */
+ dest->elems[id + delta] = dest->elems[id];
+ if (--id < 0)
+ {
+ /* Copy remaining SRC elements. */
+ memcpy (dest->elems, dest->elems + sbase,
+ delta * sizeof (int));
+ break;
+ }
+ }
+ }
+
+ return REG_NOERROR;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+ SET should not already have ELEM.
+ return -1 if an error is occured, return 1 otherwise. */
+
+static int
+re_node_set_insert (set, elem)
+ re_node_set *set;
+ int elem;
+{
+ int idx;
+ /* In case the set is empty. */
+ if (set->alloc == 0)
+ {
+ if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
+ return 1;
+ else
+ return -1;
+ }
+
+ if (BE (set->nelem, 0) == 0)
+ {
+ /* We already guaranteed above that set->alloc != 0. */
+ set->elems[0] = elem;
+ ++set->nelem;
+ return 1;
+ }
+
+ /* Realloc if we need. */
+ if (set->alloc == set->nelem)
+ {
+ int *new_array;
+ set->alloc = set->alloc * 2;
+ new_array = re_realloc (set->elems, int, set->alloc);
+ if (BE (new_array == NULL, 0))
+ return -1;
+ set->elems = new_array;
+ }
+
+ /* Move the elements which follows the new element. Test the
+ first element separately to skip a check in the inner loop. */
+ if (elem < set->elems[0])
+ {
+ idx = 0;
+ for (idx = set->nelem; idx > 0; idx--)
+ set->elems[idx] = set->elems[idx - 1];
+ }
+ else
+ {
+ for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+ set->elems[idx] = set->elems[idx - 1];
+ }
+
+ /* Insert the new element. */
+ set->elems[idx] = elem;
+ ++set->nelem;
+ return 1;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+ SET should not already have any element greater than or equal to ELEM.
+ Return -1 if an error is occured, return 1 otherwise. */
+
+static int
+re_node_set_insert_last (set, elem)
+ re_node_set *set;
+ int elem;
+{
+ /* Realloc if we need. */
+ if (set->alloc == set->nelem)
+ {
+ int *new_array;
+ set->alloc = (set->alloc + 1) * 2;
+ new_array = re_realloc (set->elems, int, set->alloc);
+ if (BE (new_array == NULL, 0))
+ return -1;
+ set->elems = new_array;
+ }
+
+ /* Insert the new element. */
+ set->elems[set->nelem++] = elem;
+ return 1;
+}
+
+/* Compare two node sets SET1 and SET2.
+ return 1 if SET1 and SET2 are equivalent, return 0 otherwise. */
+
+static int
+re_node_set_compare (set1, set2)
+ const re_node_set *set1, *set2;
+{
+ int i;
+ if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
+ return 0;
+ for (i = set1->nelem ; --i >= 0 ; )
+ if (set1->elems[i] != set2->elems[i])
+ return 0;
+ return 1;
+}
+
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */
+
+static int
+re_node_set_contains (set, elem)
+ const re_node_set *set;
+ int elem;
+{
+ unsigned int idx, right, mid;
+ if (set->nelem <= 0)
+ return 0;
+
+ /* Binary search the element. */
+ idx = 0;
+ right = set->nelem - 1;
+ while (idx < right)
+ {
+ mid = (idx + right) / 2;
+ if (set->elems[mid] < elem)
+ idx = mid + 1;
+ else
+ right = mid;
+ }
+ return set->elems[idx] == elem ? idx + 1 : 0;
+}
+
+static void
+re_node_set_remove_at (set, idx)
+ re_node_set *set;
+ int idx;
+{
+ if (idx < 0 || idx >= set->nelem)
+ return;
+ --set->nelem;
+ for (; idx < set->nelem; idx++)
+ set->elems[idx] = set->elems[idx + 1];
+}
+\f
+
+/* Add the token TOKEN to dfa->nodes, and return the index of the token.
+ Or return -1, if an error will be occured. */
+
+static int
+re_dfa_add_node (dfa, token)
+ re_dfa_t *dfa;
+ re_token_t token;
+{
+ if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
+ {
+ int new_nodes_alloc = dfa->nodes_alloc * 2;
+ int *new_nexts, *new_indices;
+ re_node_set *new_edests, *new_eclosures;
+
+ re_token_t *new_array = re_realloc (dfa->nodes, re_token_t,
+ new_nodes_alloc);
+ if (BE (new_array == NULL, 0))
+ return -1;
+ dfa->nodes = new_array;
+ new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc);
+ new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc);
+ new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+ new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
+ if (BE (new_nexts == NULL || new_indices == NULL
+ || new_edests == NULL || new_eclosures == NULL, 0))
+ return -1;
+ dfa->nexts = new_nexts;
+ dfa->org_indices = new_indices;
+ dfa->edests = new_edests;
+ dfa->eclosures = new_eclosures;
+ dfa->nodes_alloc = new_nodes_alloc;
+ }
+ dfa->nodes[dfa->nodes_len] = token;
+ dfa->nodes[dfa->nodes_len].constraint = 0;
+#ifdef RE_ENABLE_I18N
+ dfa->nodes[dfa->nodes_len].accept_mb =
+ (token.type == OP_PERIOD && dfa->mb_cur_max > 1) || token.type == COMPLEX_BRACKET;
+#endif
+ dfa->nexts[dfa->nodes_len] = -1;
+ re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+ re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
+ return dfa->nodes_len++;
+}
+
+static unsigned int inline
+calc_state_hash (nodes, context)
+ const re_node_set *nodes;
+ unsigned int context;
+{
+ unsigned int hash = nodes->nelem + context;
+ int i;
+ for (i = 0 ; i < nodes->nelem ; i++)
+ hash += nodes->elems[i];
+ return hash;
+}
+
+/* Search for the state whose node_set is equivalent to NODES.
+ Return the pointer to the state, if we found it in the DFA.
+ Otherwise create the new one and return it. In case of an error
+ return NULL and set the error code in ERR.
+ Note: - We assume NULL as the invalid state, then it is possible that
+ return value is NULL and ERR is REG_NOERROR.
+ - We never return non-NULL value in case of any errors, it is for
+ optimization. */
+
+static re_dfastate_t*
+re_acquire_state (err, dfa, nodes)
+ reg_errcode_t *err;
+ re_dfa_t *dfa;
+ const re_node_set *nodes;
+{
+ unsigned int hash;
+ re_dfastate_t *new_state;
+ struct re_state_table_entry *spot;
+ int i;
+ if (BE (nodes->nelem == 0, 0))
+ {
+ *err = REG_NOERROR;
+ return NULL;
+ }
+ hash = calc_state_hash (nodes, 0);
+ spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+ for (i = 0 ; i < spot->num ; i++)
+ {
+ re_dfastate_t *state = spot->array[i];
+ if (hash != state->hash)
+ continue;
+ if (re_node_set_compare (&state->nodes, nodes))
+ return state;
+ }
+
+ /* There are no appropriate state in the dfa, create the new one. */
+ new_state = create_ci_newstate (dfa, nodes, hash);
+ if (BE (new_state != NULL, 1))
+ return new_state;
+ else
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+}
+
+/* Search for the state whose node_set is equivalent to NODES and
+ whose context is equivalent to CONTEXT.
+ Return the pointer to the state, if we found it in the DFA.
+ Otherwise create the new one and return it. In case of an error
+ return NULL and set the error code in ERR.
+ Note: - We assume NULL as the invalid state, then it is possible that
+ return value is NULL and ERR is REG_NOERROR.
+ - We never return non-NULL value in case of any errors, it is for
+ optimization. */
+
+static re_dfastate_t*
+re_acquire_state_context (err, dfa, nodes, context)
+ reg_errcode_t *err;
+ re_dfa_t *dfa;
+ const re_node_set *nodes;
+ unsigned int context;
+{
+ unsigned int hash;
+ re_dfastate_t *new_state;
+ struct re_state_table_entry *spot;
+ int i;
+ if (nodes->nelem == 0)
+ {
+ *err = REG_NOERROR;
+ return NULL;
+ }
+ hash = calc_state_hash (nodes, context);
+ spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+ for (i = 0 ; i < spot->num ; i++)
+ {
+ re_dfastate_t *state = spot->array[i];
+ if (state->hash == hash
+ && state->context == context
+ && re_node_set_compare (state->entrance_nodes, nodes))
+ return state;
+ }
+ /* There are no appropriate state in `dfa', create the new one. */
+ new_state = create_cd_newstate (dfa, nodes, context, hash);
+ if (BE (new_state != NULL, 1))
+ return new_state;
+ else
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+}
+
+/* Finish initialization of the new state NEWSTATE, and using its hash value
+ HASH put in the appropriate bucket of DFA's state table. Return value
+ indicates the error code if failed. */
+
+static reg_errcode_t
+register_state (dfa, newstate, hash)
+ re_dfa_t *dfa;
+ re_dfastate_t *newstate;
+ unsigned int hash;
+{
+ struct re_state_table_entry *spot;
+ reg_errcode_t err;
+ int i;
+
+ newstate->hash = hash;
+ err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
+ if (BE (err != REG_NOERROR, 0))
+ return REG_ESPACE;
+ for (i = 0; i < newstate->nodes.nelem; i++)
+ {
+ int elem = newstate->nodes.elems[i];
+ if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
+ re_node_set_insert_last (&newstate->non_eps_nodes, elem);
+ }
+
+ spot = dfa->state_table + (hash & dfa->state_hash_mask);
+ if (BE (spot->alloc <= spot->num, 0))
+ {
+ int new_alloc = 2 * spot->num + 2;
+ re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
+ new_alloc);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ spot->array = new_array;
+ spot->alloc = new_alloc;
+ }
+ spot->array[spot->num++] = newstate;
+ return REG_NOERROR;
+}
+
+/* Create the new state which is independ of contexts.
+ Return the new state if succeeded, otherwise return NULL. */
+
+static re_dfastate_t *
+create_ci_newstate (dfa, nodes, hash)
+ re_dfa_t *dfa;
+ const re_node_set *nodes;
+ unsigned int hash;
+{
+ int i;
+ reg_errcode_t err;
+ re_dfastate_t *newstate;
+
+ newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+ if (BE (newstate == NULL, 0))
+ return NULL;
+ err = re_node_set_init_copy (&newstate->nodes, nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_free (newstate);
+ return NULL;
+ }
+
+ newstate->entrance_nodes = &newstate->nodes;
+ for (i = 0 ; i < nodes->nelem ; i++)
+ {
+ re_token_t *node = dfa->nodes + nodes->elems[i];
+ re_token_type_t type = node->type;
+ if (type == CHARACTER && !node->constraint)
+ continue;
+#ifdef RE_ENABLE_I18N
+ newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+ /* If the state has the halt node, the state is a halt state. */
+ if (type == END_OF_RE)
+ newstate->halt = 1;
+ else if (type == OP_BACK_REF)
+ newstate->has_backref = 1;
+ else if (type == ANCHOR || node->constraint)
+ newstate->has_constraint = 1;
+ }
+ err = register_state (dfa, newstate, hash);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ free_state (newstate);
+ newstate = NULL;
+ }
+ return newstate;
+}
+
+/* Create the new state which is depend on the context CONTEXT.
+ Return the new state if succeeded, otherwise return NULL. */
+
+static re_dfastate_t *
+create_cd_newstate (dfa, nodes, context, hash)
+ re_dfa_t *dfa;
+ const re_node_set *nodes;
+ unsigned int context, hash;
+{
+ int i, nctx_nodes = 0;
+ reg_errcode_t err;
+ re_dfastate_t *newstate;
+
+ newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+ if (BE (newstate == NULL, 0))
+ return NULL;
+ err = re_node_set_init_copy (&newstate->nodes, nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_free (newstate);
+ return NULL;
+ }
+
+ newstate->context = context;
+ newstate->entrance_nodes = &newstate->nodes;
+
+ for (i = 0 ; i < nodes->nelem ; i++)
+ {
+ unsigned int constraint = 0;
+ re_token_t *node = dfa->nodes + nodes->elems[i];
+ re_token_type_t type = node->type;
+ if (node->constraint)
+ constraint = node->constraint;
+
+ if (type == CHARACTER && !constraint)
+ continue;
+#ifdef RE_ENABLE_I18N
+ newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+ /* If the state has the halt node, the state is a halt state. */
+ if (type == END_OF_RE)
+ newstate->halt = 1;
+ else if (type == OP_BACK_REF)
+ newstate->has_backref = 1;
+ else if (type == ANCHOR)
+ constraint = node->opr.ctx_type;
+
+ if (constraint)
+ {
+ if (newstate->entrance_nodes == &newstate->nodes)
+ {
+ newstate->entrance_nodes = re_malloc (re_node_set, 1);
+ if (BE (newstate->entrance_nodes == NULL, 0))
+ {
+ free_state (newstate);
+ return NULL;
+ }
+ re_node_set_init_copy (newstate->entrance_nodes, nodes);
+ nctx_nodes = 0;
+ newstate->has_constraint = 1;
+ }
+
+ if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
+ {
+ re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
+ ++nctx_nodes;
+ }
+ }
+ }
+ err = register_state (dfa, newstate, hash);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ free_state (newstate);
+ newstate = NULL;
+ }
+ return newstate;
+}
+
+static void
+free_state (state)
+ re_dfastate_t *state;
+{
+ re_node_set_free (&state->non_eps_nodes);
+ re_node_set_free (&state->inveclosure);
+ if (state->entrance_nodes != &state->nodes)
+ {
+ re_node_set_free (state->entrance_nodes);
+ re_free (state->entrance_nodes);
+ }
+ re_node_set_free (&state->nodes);
+ re_free (state->word_trtable);
+ re_free (state->trtable);
+ re_free (state);
+}
--- /dev/null
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+#ifndef _REGEX_INTERNAL_H
+#define _REGEX_INTERNAL_H 1
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+# include <langinfo.h>
+#endif
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+#if defined HAVE_WCHAR_H || defined _LIBC
+# include <wchar.h>
+#endif /* HAVE_WCHAR_H || _LIBC */
+#if defined HAVE_WCTYPE_H || defined _LIBC
+# include <wctype.h>
+#endif /* HAVE_WCTYPE_H || _LIBC */
+
+#ifndef GAWK
+/* In case that the system doesn't have isblank(). */
+#if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank
+# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#endif
+#else /* GAWK */
+/*
+ * This is a freaking mess. On glibc systems you have to define
+ * a magic constant to get isblank() out of <ctype.h>, since it's
+ * a C99 function. To heck wiht all that and borrow a page from
+ * dfa.c's book.
+ */
+
+static int
+is_blank (int c)
+{
+ return (c == ' ' || c == '\t');
+}
+#endif /* GAWK */
+
+#ifdef _LIBC
+# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
+# define _RE_DEFINE_LOCALE_FUNCTIONS 1
+# include <locale/localeinfo.h>
+# include <locale/elem-hash.h>
+# include <locale/coll-lookup.h>
+# endif
+#endif
+
+/* This is for other GNU distributions with internationalized messages. */
+#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifdef _LIBC
+# undef gettext
+# define gettext(msgid) \
+ INTUSE(__dcgettext) (INTUSE(_libc_intl_domainname), msgid, LC_MESSAGES)
+# endif
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+ strings. */
+# define gettext_noop(String) String
+#endif
+
+#ifndef NO_MBSUPPORT
+#include "mbsupport.h" /* gawk */
+#endif
+#ifndef MB_CUR_MAX
+#define MB_CUR_MAX 1
+#endif
+
+#if (defined MBS_SUPPORT) || _LIBC
+# define RE_ENABLE_I18N
+#endif
+
+#if __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+# define inline
+#endif
+
+/* Number of bits in a byte. */
+#define BYTE_BITS 8
+/* Number of single byte character. */
+#define SBC_MAX 256
+
+#define COLL_ELEM_LEN_MAX 8
+
+/* The character which represents newline. */
+#define NEWLINE_CHAR '\n'
+#define WIDE_NEWLINE_CHAR L'\n'
+
+/* Rename to standard API for using out of glibc. */
+#ifndef _LIBC
+# define __wctype wctype
+# define __iswctype iswctype
+# define __btowc btowc
+# define __mempcpy mempcpy
+# define __wcrtomb wcrtomb
+# define __regfree regfree
+# define attribute_hidden
+#endif /* not _LIBC */
+
+#ifdef __GNUC__
+# define __attribute(arg) __attribute__ (arg)
+#else
+# define __attribute(arg)
+#endif
+
+/* Error messages (regcomp.c), with hackery to support very old compilers. */
+#ifdef NO_TOKEN_PASTING
+#define RE_ERRMSG(idx) __re_error_msgid[(int) (idx)]
+#define ERRMSG_TYPE char * const /* pointers */
+#define ERRMSG_OFFSET(base,offset) ((base)+1) /* array index */
+#define ERRMSG_SEPARATOR ,
+#else
+#define RE_ERRMSG(idx) (__re_error_msgid + __re_error_msgid_idx[(int) (idx)])
+#define ERRMSG_TYPE char /* one string */
+#define ERRMSG_OFFSET(base,offset) ((base)+(offset)) /* substring index */
+#define ERRMSG_SEPARATOR "\0"
+#endif
+
+extern const ERRMSG_TYPE __re_error_msgid[] attribute_hidden;
+extern const size_t __re_error_msgid_idx[] attribute_hidden;
+
+/* Number of bits in an unsinged int. */
+#define UINT_BITS (sizeof (unsigned int) * BYTE_BITS)
+/* Number of unsigned int in an bit_set. */
+#define BITSET_UINTS ((SBC_MAX + UINT_BITS - 1) / UINT_BITS)
+typedef unsigned int bitset[BITSET_UINTS];
+typedef unsigned int *re_bitset_ptr_t;
+typedef const unsigned int *re_const_bitset_ptr_t;
+
+#define bitset_set(set,i) (set[i / UINT_BITS] |= 1 << i % UINT_BITS)
+#define bitset_clear(set,i) (set[i / UINT_BITS] &= ~(1 << i % UINT_BITS))
+#define bitset_contain(set,i) (set[i / UINT_BITS] & (1 << i % UINT_BITS))
+#define bitset_empty(set) memset (set, 0, sizeof (unsigned int) * BITSET_UINTS)
+#define bitset_set_all(set) \
+ memset (set, 255, sizeof (unsigned int) * BITSET_UINTS)
+#define bitset_copy(dest,src) \
+ memcpy (dest, src, sizeof (unsigned int) * BITSET_UINTS)
+static inline void bitset_not (bitset set);
+static inline void bitset_merge (bitset dest, const bitset src);
+static inline void bitset_not_merge (bitset dest, const bitset src);
+static inline void bitset_mask (bitset dest, const bitset src);
+
+#define PREV_WORD_CONSTRAINT 0x0001
+#define PREV_NOTWORD_CONSTRAINT 0x0002
+#define NEXT_WORD_CONSTRAINT 0x0004
+#define NEXT_NOTWORD_CONSTRAINT 0x0008
+#define PREV_NEWLINE_CONSTRAINT 0x0010
+#define NEXT_NEWLINE_CONSTRAINT 0x0020
+#define PREV_BEGBUF_CONSTRAINT 0x0040
+#define NEXT_ENDBUF_CONSTRAINT 0x0080
+#define WORD_DELIM_CONSTRAINT 0x0100
+#define NOT_WORD_DELIM_CONSTRAINT 0x0200
+
+typedef enum
+{
+ INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+ WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+ WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+ INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+ LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
+ LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
+ BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
+ BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
+ WORD_DELIM = WORD_DELIM_CONSTRAINT,
+ NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
+} re_context_type;
+
+typedef struct
+{
+ int alloc;
+ int nelem;
+ int *elems;
+} re_node_set;
+
+typedef enum
+{
+ NON_TYPE = 0,
+
+ /* Node type, These are used by token, node, tree. */
+ CHARACTER = 1,
+ END_OF_RE = 2,
+ SIMPLE_BRACKET = 3,
+ OP_BACK_REF = 4,
+ OP_PERIOD = 5,
+#ifdef RE_ENABLE_I18N
+ COMPLEX_BRACKET = 6,
+ OP_UTF8_PERIOD = 7,
+#endif /* RE_ENABLE_I18N */
+
+ /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
+ when the debugger shows values of this enum type. */
+#define EPSILON_BIT 8
+ OP_OPEN_SUBEXP = EPSILON_BIT | 0,
+ OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
+ OP_ALT = EPSILON_BIT | 2,
+ OP_DUP_ASTERISK = EPSILON_BIT | 3,
+ ANCHOR = EPSILON_BIT | 4,
+
+ /* Tree type, these are used only by tree. */
+ CONCAT = 16,
+ SUBEXP = 17,
+
+ /* Token type, these are used only by token. */
+ OP_DUP_PLUS = 18,
+ OP_DUP_QUESTION,
+ OP_OPEN_BRACKET,
+ OP_CLOSE_BRACKET,
+ OP_CHARSET_RANGE,
+ OP_OPEN_DUP_NUM,
+ OP_CLOSE_DUP_NUM,
+ OP_NON_MATCH_LIST,
+ OP_OPEN_COLL_ELEM,
+ OP_CLOSE_COLL_ELEM,
+ OP_OPEN_EQUIV_CLASS,
+ OP_CLOSE_EQUIV_CLASS,
+ OP_OPEN_CHAR_CLASS,
+ OP_CLOSE_CHAR_CLASS,
+ OP_WORD,
+ OP_NOTWORD,
+ OP_SPACE,
+ OP_NOTSPACE,
+ BACK_SLASH
+
+} re_token_type_t;
+
+#ifdef RE_ENABLE_I18N
+typedef struct
+{
+ /* Multibyte characters. */
+ wchar_t *mbchars;
+
+ /* Collating symbols. */
+# ifdef _LIBC
+ int32_t *coll_syms;
+# endif
+
+ /* Equivalence classes. */
+# ifdef _LIBC
+ int32_t *equiv_classes;
+# endif
+
+ /* Range expressions. */
+# ifdef _LIBC
+ uint32_t *range_starts;
+ uint32_t *range_ends;
+# else /* not _LIBC */
+ wchar_t *range_starts;
+ wchar_t *range_ends;
+# endif /* not _LIBC */
+
+ /* Character classes. */
+ wctype_t *char_classes;
+
+ /* If this character set is the non-matching list. */
+ unsigned int non_match : 1;
+
+ /* # of multibyte characters. */
+ int nmbchars;
+
+ /* # of collating symbols. */
+ int ncoll_syms;
+
+ /* # of equivalence classes. */
+ int nequiv_classes;
+
+ /* # of range expressions. */
+ int nranges;
+
+ /* # of character classes. */
+ int nchar_classes;
+} re_charset_t;
+#endif /* RE_ENABLE_I18N */
+
+typedef struct
+{
+ union
+ {
+ unsigned char c; /* for CHARACTER */
+ re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */
+#ifdef RE_ENABLE_I18N
+ re_charset_t *mbcset; /* for COMPLEX_BRACKET */
+#endif /* RE_ENABLE_I18N */
+ int idx; /* for BACK_REF */
+ re_context_type ctx_type; /* for ANCHOR */
+ } opr;
+#if __GNUC__ >= 2
+ re_token_type_t type : 8;
+#else
+ re_token_type_t type;
+#endif
+ unsigned int constraint : 10; /* context constraint */
+ unsigned int duplicated : 1;
+ unsigned int opt_subexp : 1;
+#ifdef RE_ENABLE_I18N
+ unsigned int accept_mb : 1;
+ /* These 2 bits can be moved into the union if needed (e.g. if running out
+ of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */
+ unsigned int mb_partial : 1;
+#endif
+ unsigned int word_char : 1;
+} re_token_t;
+
+#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
+
+struct re_string_t
+{
+ /* Indicate the raw buffer which is the original string passed as an
+ argument of regexec(), re_search(), etc.. */
+ const unsigned char *raw_mbs;
+ /* Store the multibyte string. In case of "case insensitive mode" like
+ REG_ICASE, upper cases of the string are stored, otherwise MBS points
+ the same address that RAW_MBS points. */
+ unsigned char *mbs;
+#ifdef RE_ENABLE_I18N
+ /* Store the wide character string which is corresponding to MBS. */
+ wint_t *wcs;
+ int *offsets;
+ mbstate_t cur_state;
+#endif
+ /* Index in RAW_MBS. Each character mbs[i] corresponds to
+ raw_mbs[raw_mbs_idx + i]. */
+ int raw_mbs_idx;
+ /* The length of the valid characters in the buffers. */
+ int valid_len;
+ /* The corresponding number of bytes in raw_mbs array. */
+ int valid_raw_len;
+ /* The length of the buffers MBS and WCS. */
+ int bufs_len;
+ /* The index in MBS, which is updated by re_string_fetch_byte. */
+ int cur_idx;
+ /* length of RAW_MBS array. */
+ int raw_len;
+ /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */
+ int len;
+ /* End of the buffer may be shorter than its length in the cases such
+ as re_match_2, re_search_2. Then, we use STOP for end of the buffer
+ instead of LEN. */
+ int raw_stop;
+ /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */
+ int stop;
+
+ /* The context of mbs[0]. We store the context independently, since
+ the context of mbs[0] may be different from raw_mbs[0], which is
+ the beginning of the input string. */
+ unsigned int tip_context;
+ /* The translation passed as a part of an argument of re_compile_pattern. */
+ unsigned RE_TRANSLATE_TYPE trans;
+ /* Copy of re_dfa_t's word_char. */
+ re_const_bitset_ptr_t word_char;
+ /* 1 if REG_ICASE. */
+ unsigned char icase;
+ unsigned char is_utf8;
+ unsigned char map_notascii;
+ unsigned char mbs_allocated;
+ unsigned char offsets_needed;
+ unsigned char newline_anchor;
+ unsigned char word_ops_used;
+ int mb_cur_max;
+};
+typedef struct re_string_t re_string_t;
+
+
+struct re_dfa_t;
+typedef struct re_dfa_t re_dfa_t;
+
+#ifndef _LIBC
+# ifdef __i386__
+# define internal_function __attribute ((regparm (3), stdcall))
+# else
+# define internal_function
+# endif
+#endif
+
+#ifndef RE_NO_INTERNAL_PROTOTYPES
+static reg_errcode_t re_string_allocate (re_string_t *pstr, const char *str,
+ int len, int init_len,
+ RE_TRANSLATE_TYPE trans, int icase,
+ const re_dfa_t *dfa)
+ internal_function;
+static reg_errcode_t re_string_construct (re_string_t *pstr, const char *str,
+ int len, RE_TRANSLATE_TYPE trans,
+ int icase, const re_dfa_t *dfa)
+ internal_function;
+static reg_errcode_t re_string_reconstruct (re_string_t *pstr, int idx,
+ int eflags) internal_function;
+static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
+ int new_buf_len)
+ internal_function;
+# ifdef RE_ENABLE_I18N
+static void build_wcs_buffer (re_string_t *pstr) internal_function;
+static int build_wcs_upper_buffer (re_string_t *pstr) internal_function;
+# endif /* RE_ENABLE_I18N */
+static void build_upper_buffer (re_string_t *pstr) internal_function;
+static void re_string_translate_buffer (re_string_t *pstr) internal_function;
+static void re_string_destruct (re_string_t *pstr) internal_function;
+# ifdef RE_ENABLE_I18N
+static int re_string_elem_size_at (const re_string_t *pstr, int idx)
+ internal_function __attribute ((pure));
+static inline int re_string_char_size_at (const re_string_t *pstr, int idx)
+ internal_function __attribute ((pure));
+static inline wint_t re_string_wchar_at (const re_string_t *pstr, int idx)
+ internal_function __attribute ((pure));
+# endif /* RE_ENABLE_I18N */
+static unsigned int re_string_context_at (const re_string_t *input, int idx,
+ int eflags)
+ internal_function __attribute ((pure));
+static unsigned char re_string_peek_byte_case (const re_string_t *pstr,
+ int idx)
+ internal_function __attribute ((pure));
+static unsigned char re_string_fetch_byte_case (re_string_t *pstr)
+ internal_function __attribute ((pure));
+#endif
+#define re_string_peek_byte(pstr, offset) \
+ ((pstr)->mbs[(pstr)->cur_idx + offset])
+#define re_string_fetch_byte(pstr) \
+ ((pstr)->mbs[(pstr)->cur_idx++])
+#define re_string_first_byte(pstr, idx) \
+ ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
+#define re_string_is_single_byte_char(pstr, idx) \
+ ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
+ || (pstr)->wcs[(idx) + 1] != WEOF))
+#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
+#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
+#define re_string_get_buffer(pstr) ((pstr)->mbs)
+#define re_string_length(pstr) ((pstr)->len)
+#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
+#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
+#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
+
+#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+/* SunOS 4.1.x realloc doesn't accept null pointers: pre-Standard C. Sigh. */
+#define re_realloc(p,t,n) ((p != NULL) ? (t *) realloc (p,(n)*sizeof(t)) : (t *) calloc(n,sizeof(t)))
+#define re_free(p) free (p)
+
+struct bin_tree_t
+{
+ struct bin_tree_t *parent;
+ struct bin_tree_t *left;
+ struct bin_tree_t *right;
+ struct bin_tree_t *first;
+ struct bin_tree_t *next;
+
+ re_token_t token;
+
+ /* `node_idx' is the index in dfa->nodes, if `type' == 0.
+ Otherwise `type' indicate the type of this node. */
+ int node_idx;
+};
+typedef struct bin_tree_t bin_tree_t;
+
+#define BIN_TREE_STORAGE_SIZE \
+ ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
+
+struct bin_tree_storage_t
+{
+ struct bin_tree_storage_t *next;
+ bin_tree_t data[BIN_TREE_STORAGE_SIZE];
+};
+typedef struct bin_tree_storage_t bin_tree_storage_t;
+
+#define CONTEXT_WORD 1
+#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
+#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
+#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
+
+#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
+#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
+#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
+#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
+#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
+
+#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
+#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
+#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
+#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
+
+#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
+ ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+ || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+ || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
+ || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
+
+#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
+ ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+ || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+ || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
+ || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
+
+struct re_dfastate_t
+{
+ unsigned int hash;
+ re_node_set nodes;
+ re_node_set non_eps_nodes;
+ re_node_set inveclosure;
+ re_node_set *entrance_nodes;
+ struct re_dfastate_t **trtable, **word_trtable;
+ unsigned int context : 4;
+ unsigned int halt : 1;
+ /* If this state can accept `multi byte'.
+ Note that we refer to multibyte characters, and multi character
+ collating elements as `multi byte'. */
+ unsigned int accept_mb : 1;
+ /* If this state has backreference node(s). */
+ unsigned int has_backref : 1;
+ unsigned int has_constraint : 1;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+
+struct re_state_table_entry
+{
+ int num;
+ int alloc;
+ re_dfastate_t **array;
+};
+
+/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */
+
+typedef struct
+{
+ int next_idx;
+ int alloc;
+ re_dfastate_t **array;
+} state_array_t;
+
+/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */
+
+typedef struct
+{
+ int node;
+ int str_idx; /* The position NODE match at. */
+ state_array_t path;
+} re_sub_match_last_t;
+
+/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
+ And information about the node, whose type is OP_CLOSE_SUBEXP,
+ corresponding to NODE is stored in LASTS. */
+
+typedef struct
+{
+ int str_idx;
+ int node;
+ int next_last_offset;
+ state_array_t *path;
+ int alasts; /* Allocation size of LASTS. */
+ int nlasts; /* The number of LASTS. */
+ re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+
+struct re_backref_cache_entry
+{
+ int node;
+ int str_idx;
+ int subexp_from;
+ int subexp_to;
+ char more;
+ char unused;
+ unsigned short int eps_reachable_subexps_map;
+};
+
+typedef struct
+{
+ /* The string object corresponding to the input string. */
+ re_string_t input;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+ re_dfa_t *const dfa;
+#else
+ re_dfa_t *dfa;
+#endif
+ /* EFLAGS of the argument of regexec. */
+ int eflags;
+ /* Where the matching ends. */
+ int match_last;
+ int last_node;
+ /* The state log used by the matcher. */
+ re_dfastate_t **state_log;
+ int state_log_top;
+ /* Back reference cache. */
+ int nbkref_ents;
+ int abkref_ents;
+ struct re_backref_cache_entry *bkref_ents;
+ int max_mb_elem_len;
+ int nsub_tops;
+ int asub_tops;
+ re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+
+typedef struct
+{
+ re_dfastate_t **sifted_states;
+ re_dfastate_t **limited_states;
+ int last_node;
+ int last_str_idx;
+ re_node_set limits;
+} re_sift_context_t;
+
+struct re_fail_stack_ent_t
+{
+ int idx;
+ int node;
+ regmatch_t *regs;
+ re_node_set eps_via_nodes;
+};
+
+struct re_fail_stack_t
+{
+ int num;
+ int alloc;
+ struct re_fail_stack_ent_t *stack;
+};
+
+struct re_dfa_t
+{
+ re_token_t *nodes;
+ int nodes_alloc;
+ int nodes_len;
+ int *nexts;
+ int *org_indices;
+ re_node_set *edests;
+ re_node_set *eclosures;
+ re_node_set *inveclosures;
+ struct re_state_table_entry *state_table;
+ re_dfastate_t *init_state;
+ re_dfastate_t *init_state_word;
+ re_dfastate_t *init_state_nl;
+ re_dfastate_t *init_state_begbuf;
+ bin_tree_t *str_tree;
+ bin_tree_storage_t *str_tree_storage;
+ re_bitset_ptr_t sb_char;
+ int str_tree_storage_idx;
+
+ /* number of subexpressions `re_nsub' is in regex_t. */
+ unsigned int state_hash_mask;
+ int states_alloc;
+ int init_node;
+ int nbackref; /* The number of backreference in this dfa. */
+
+ /* Bitmap expressing which backreference is used. */
+ unsigned int used_bkref_map;
+ unsigned int completed_bkref_map;
+
+ unsigned int has_plural_match : 1;
+ /* If this dfa has "multibyte node", which is a backreference or
+ a node which can accept multibyte character or multi character
+ collating element. */
+ unsigned int has_mb_node : 1;
+ unsigned int is_utf8 : 1;
+ unsigned int map_notascii : 1;
+ unsigned int word_ops_used : 1;
+ int mb_cur_max;
+ bitset word_char;
+ reg_syntax_t syntax;
+ int *subexp_map;
+#ifdef DEBUG
+ char* re_str;
+#endif
+};
+
+#ifndef RE_NO_INTERNAL_PROTOTYPES
+static reg_errcode_t re_node_set_alloc (re_node_set *set, int size) internal_function;
+static reg_errcode_t re_node_set_init_1 (re_node_set *set, int elem) internal_function;
+static reg_errcode_t re_node_set_init_2 (re_node_set *set, int elem1,
+ int elem2) internal_function;
+#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+static reg_errcode_t re_node_set_init_copy (re_node_set *dest,
+ const re_node_set *src) internal_function;
+static reg_errcode_t re_node_set_add_intersect (re_node_set *dest,
+ const re_node_set *src1,
+ const re_node_set *src2) internal_function;
+static reg_errcode_t re_node_set_init_union (re_node_set *dest,
+ const re_node_set *src1,
+ const re_node_set *src2) internal_function;
+static reg_errcode_t re_node_set_merge (re_node_set *dest,
+ const re_node_set *src) internal_function;
+static int re_node_set_insert (re_node_set *set, int elem) internal_function;
+static int re_node_set_insert_last (re_node_set *set,
+ int elem) internal_function;
+static int re_node_set_compare (const re_node_set *set1,
+ const re_node_set *set2)
+ internal_function __attribute ((pure));
+static int re_node_set_contains (const re_node_set *set, int elem)
+ internal_function __attribute ((pure));
+static void re_node_set_remove_at (re_node_set *set, int idx) internal_function;
+#define re_node_set_remove(set,id) \
+ (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+#define re_node_set_empty(p) ((p)->nelem = 0)
+#define re_node_set_free(set) re_free ((set)->elems)
+static int re_dfa_add_node (re_dfa_t *dfa, re_token_t token) internal_function;
+static re_dfastate_t *re_acquire_state (reg_errcode_t *err, re_dfa_t *dfa,
+ const re_node_set *nodes) internal_function;
+static re_dfastate_t *re_acquire_state_context (reg_errcode_t *err,
+ re_dfa_t *dfa,
+ const re_node_set *nodes,
+ unsigned int context) internal_function;
+static void free_state (re_dfastate_t *state) internal_function;
+#endif
+\f
+
+typedef enum
+{
+ SB_CHAR,
+ MB_CHAR,
+ EQUIV_CLASS,
+ COLL_SYM,
+ CHAR_CLASS
+} bracket_elem_type;
+
+typedef struct
+{
+ bracket_elem_type type;
+ union
+ {
+ unsigned char ch;
+ unsigned char *name;
+ wchar_t wch;
+ } opr;
+} bracket_elem_t;
+
+
+/* Inline functions for bitset operation. */
+static inline void
+bitset_not (bitset set)
+{
+ int bitset_i;
+ for (bitset_i = 0; bitset_i < BITSET_UINTS; ++bitset_i)
+ set[bitset_i] = ~set[bitset_i];
+}
+
+static inline void
+bitset_merge (bitset dest, const bitset src)
+{
+ int bitset_i;
+ for (bitset_i = 0; bitset_i < BITSET_UINTS; ++bitset_i)
+ dest[bitset_i] |= src[bitset_i];
+}
+
+static inline void
+bitset_not_merge (bitset dest, const bitset src)
+{
+ int i;
+ for (i = 0; i < BITSET_UINTS; ++i)
+ dest[i] |= ~src[i];
+}
+
+static inline void
+bitset_mask (bitset dest, const bitset src)
+{
+ int bitset_i;
+ for (bitset_i = 0; bitset_i < BITSET_UINTS; ++bitset_i)
+ dest[bitset_i] &= src[bitset_i];
+}
+
+#if defined RE_ENABLE_I18N && !defined RE_NO_INTERNAL_PROTOTYPES
+/* Inline functions for re_string. */
+static inline int
+internal_function
+re_string_char_size_at (const re_string_t *pstr, int idx)
+{
+ int byte_idx;
+ if (pstr->mb_cur_max == 1)
+ return 1;
+ for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+ if (pstr->wcs[idx + byte_idx] != WEOF)
+ break;
+ return byte_idx;
+}
+
+static inline wint_t
+internal_function
+re_string_wchar_at (const re_string_t *pstr, int idx)
+{
+ if (pstr->mb_cur_max == 1)
+ return (wint_t) pstr->mbs[idx];
+ return (wint_t) pstr->wcs[idx];
+}
+
+static int
+internal_function
+re_string_elem_size_at (const re_string_t *pstr, int idx)
+{
+#ifdef _LIBC
+ const unsigned char *p, *extra;
+ const int32_t *table, *indirect;
+ int32_t tmp;
+# include <locale/weight.h>
+ uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+
+ if (nrules != 0)
+ {
+ table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+ extra = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+ indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+ _NL_COLLATE_INDIRECTMB);
+ p = pstr->mbs + idx;
+ tmp = findidx (&p);
+ return p - pstr->mbs - idx;
+ }
+ else
+#endif /* _LIBC */
+ return 1;
+}
+#endif /* RE_ENABLE_I18N */
+
+#endif /* _REGEX_INTERNAL_H */
--- /dev/null
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+ int n) internal_function;
+static void match_ctx_clean (re_match_context_t *mctx) internal_function;
+static void match_ctx_free (re_match_context_t *cache) internal_function;
+static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,
+ int str_idx, int from, int to)
+ internal_function;
+static int search_cur_bkref_entry (re_match_context_t *mctx, int str_idx)
+ internal_function;
+static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node,
+ int str_idx) internal_function;
+static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
+ int node, int str_idx)
+ internal_function;
+static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+ re_dfastate_t **limited_sts, int last_node,
+ int last_str_idx)
+ internal_function;
+static reg_errcode_t re_search_internal (const regex_t *preg,
+ const char *string, int length,
+ int start, int range, int stop,
+ size_t nmatch, regmatch_t pmatch[],
+ int eflags) internal_function;
+static int re_search_2_stub (struct re_pattern_buffer *bufp,
+ const char *string1, int length1,
+ const char *string2, int length2,
+ int start, int range, struct re_registers *regs,
+ int stop, int ret_len) internal_function;
+static int re_search_stub (struct re_pattern_buffer *bufp,
+ const char *string, int length, int start,
+ int range, int stop, struct re_registers *regs,
+ int ret_len) internal_function;
+static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
+ int nregs, int regs_allocated) internal_function;
+static inline re_dfastate_t *acquire_init_state_context
+ (reg_errcode_t *err, const re_match_context_t *mctx, int idx)
+ __attribute ((always_inline)) internal_function;
+static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)
+ internal_function;
+static int check_matching (re_match_context_t *mctx, int fl_longest_match,
+ int *p_match_first)
+ internal_function;
+static int check_halt_node_context (const re_dfa_t *dfa, int node,
+ unsigned int context) internal_function;
+static int check_halt_state_context (const re_match_context_t *mctx,
+ const re_dfastate_t *state, int idx)
+ internal_function;
+static void update_regs (re_dfa_t *dfa, regmatch_t *pmatch,
+ regmatch_t *prev_idx_match, int cur_node,
+ int cur_idx, int nmatch) internal_function;
+static int proceed_next_node (const re_match_context_t *mctx,
+ int nregs, regmatch_t *regs,
+ int *pidx, int node, re_node_set *eps_via_nodes,
+ struct re_fail_stack_t *fs) internal_function;
+static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+ int str_idx, int dest_node, int nregs,
+ regmatch_t *regs,
+ re_node_set *eps_via_nodes) internal_function;
+static int pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
+ regmatch_t *regs, re_node_set *eps_via_nodes) internal_function;
+static reg_errcode_t set_regs (const regex_t *preg,
+ const re_match_context_t *mctx,
+ size_t nmatch, regmatch_t *pmatch,
+ int fl_backtrack) internal_function;
+static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) internal_function;
+
+#ifdef RE_ENABLE_I18N
+static int sift_states_iter_mb (const re_match_context_t *mctx,
+ re_sift_context_t *sctx,
+ int node_idx, int str_idx, int max_str_idx) internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t sift_states_backward (re_match_context_t *mctx,
+ re_sift_context_t *sctx) internal_function;
+static reg_errcode_t build_sifted_states (re_match_context_t *mctx,
+ re_sift_context_t *sctx, int str_idx,
+ re_node_set *cur_dest) internal_function;
+static reg_errcode_t update_cur_sifted_state (re_match_context_t *mctx,
+ re_sift_context_t *sctx,
+ int str_idx,
+ re_node_set *dest_nodes) internal_function;
+static reg_errcode_t add_epsilon_src_nodes (re_dfa_t *dfa,
+ re_node_set *dest_nodes,
+ const re_node_set *candidates) internal_function;
+static reg_errcode_t sub_epsilon_src_nodes (re_dfa_t *dfa, int node,
+ re_node_set *dest_nodes,
+ const re_node_set *and_nodes) internal_function;
+static int check_dst_limits (re_match_context_t *mctx, re_node_set *limits,
+ int dst_node, int dst_idx, int src_node,
+ int src_idx) internal_function;
+static int check_dst_limits_calc_pos_1 (re_match_context_t *mctx,
+ int boundaries, int subexp_idx,
+ int from_node, int bkref_idx) internal_function;
+static int check_dst_limits_calc_pos (re_match_context_t *mctx,
+ int limit, int subexp_idx,
+ int node, int str_idx,
+ int bkref_idx) internal_function;
+static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
+ re_node_set *dest_nodes,
+ const re_node_set *candidates,
+ re_node_set *limits,
+ struct re_backref_cache_entry *bkref_ents,
+ int str_idx) internal_function;
+static reg_errcode_t sift_states_bkref (re_match_context_t *mctx,
+ re_sift_context_t *sctx,
+ int str_idx, const re_node_set *candidates) internal_function;
+static reg_errcode_t clean_state_log_if_needed (re_match_context_t *mctx,
+ int next_state_log_idx) internal_function;
+static reg_errcode_t merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst,
+ re_dfastate_t **src, int num) internal_function;
+static re_dfastate_t *find_recover_state (reg_errcode_t *err,
+ re_match_context_t *mctx) internal_function;
+static re_dfastate_t *transit_state (reg_errcode_t *err,
+ re_match_context_t *mctx,
+ re_dfastate_t *state) internal_function;
+static re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
+ re_match_context_t *mctx,
+ re_dfastate_t *next_state) internal_function;
+static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
+ re_node_set *cur_nodes,
+ int str_idx) internal_function;
+#if 0
+static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
+ re_match_context_t *mctx,
+ re_dfastate_t *pstate) internal_function;
+#endif
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
+ re_dfastate_t *pstate) internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
+ const re_node_set *nodes) internal_function;
+static reg_errcode_t get_subexp (re_match_context_t *mctx,
+ int bkref_node, int bkref_str_idx) internal_function;
+static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
+ const re_sub_match_top_t *sub_top,
+ re_sub_match_last_t *sub_last,
+ int bkref_node, int bkref_str) internal_function;
+static int find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+ int subexp_idx, int type) internal_function;
+static reg_errcode_t check_arrival (re_match_context_t *mctx,
+ state_array_t *path, int top_node,
+ int top_str, int last_node, int last_str,
+ int type) internal_function;
+static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
+ int str_idx,
+ re_node_set *cur_nodes,
+ re_node_set *next_nodes) internal_function;
+static reg_errcode_t check_arrival_expand_ecl (re_dfa_t *dfa,
+ re_node_set *cur_nodes,
+ int ex_subexp, int type) internal_function;
+static reg_errcode_t check_arrival_expand_ecl_sub (re_dfa_t *dfa,
+ re_node_set *dst_nodes,
+ int target, int ex_subexp,
+ int type) internal_function;
+static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
+ re_node_set *cur_nodes, int cur_str,
+ int subexp_num, int type) internal_function;
+static int build_trtable (re_dfa_t *dfa,
+ re_dfastate_t *state) internal_function;
+#ifdef RE_ENABLE_I18N
+static int check_node_accept_bytes (re_dfa_t *dfa, int node_idx,
+ const re_string_t *input, int idx) internal_function;
+# ifdef _LIBC
+static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+ size_t name_len) internal_function;
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+static int group_nodes_into_DFAstates (re_dfa_t *dfa,
+ const re_dfastate_t *state,
+ re_node_set *states_node,
+ bitset *states_ch) internal_function;
+static int check_node_accept (const re_match_context_t *mctx,
+ const re_token_t *node, int idx) internal_function;
+static reg_errcode_t extend_buffers (re_match_context_t *mctx) internal_function;
+\f
+/* Entry point for POSIX code. */
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *__restrict preg;
+ const char *__restrict string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ reg_errcode_t err;
+ int start, length;
+
+ if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
+ return REG_BADPAT;
+
+ if (eflags & REG_STARTEND)
+ {
+ start = pmatch[0].rm_so;
+ length = pmatch[0].rm_eo;
+ }
+ else
+ {
+ start = 0;
+ length = strlen (string);
+ }
+ if (preg->no_sub)
+ err = re_search_internal (preg, string, length, start, length - start,
+ length, 0, NULL, eflags);
+ else
+ err = re_search_internal (preg, string, length, start, length - start,
+ length, nmatch, pmatch, eflags);
+ return err != REG_NOERROR;
+}
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+__typeof__ (__regexec) __compat_regexec;
+
+int
+attribute_compat_text_section
+__compat_regexec (const regex_t *__restrict preg,
+ const char *__restrict string, size_t nmatch,
+ regmatch_t pmatch[], int eflags)
+{
+ return regexec (preg, string, nmatch, pmatch,
+ eflags & (REG_NOTBOL | REG_NOTEOL));
+}
+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+# endif
+#endif
+
+/* Entry points for GNU code. */
+
+/* re_match, re_search, re_match_2, re_search_2
+
+ The former two functions operate on STRING with length LENGTH,
+ while the later two operate on concatenation of STRING1 and STRING2
+ with lengths LENGTH1 and LENGTH2, respectively.
+
+ re_match() matches the compiled pattern in BUFP against the string,
+ starting at index START.
+
+ re_search() first tries matching at index START, then it tries to match
+ starting from index START + 1, and so on. The last start position tried
+ is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same
+ way as re_match().)
+
+ The parameter STOP of re_{match,search}_2 specifies that no match exceeding
+ the first STOP characters of the concatenation of the strings should be
+ concerned.
+
+ If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
+ and all groups is stroed in REGS. (For the "_2" variants, the offsets are
+ computed relative to the concatenation, not relative to the individual
+ strings.)
+
+ On success, re_match* functions return the length of the match, re_search*
+ return the position of the start of the match. Return value -1 means no
+ match was found and -2 indicates an internal error. */
+
+int
+re_match (bufp, string, length, start, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int length, start;
+ struct re_registers *regs;
+{
+ return re_search_stub (bufp, string, length, start, 0, length, regs, 1);
+}
+#ifdef _LIBC
+weak_alias (__re_match, re_match)
+#endif
+
+int
+re_search (bufp, string, length, start, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int length, start, range;
+ struct re_registers *regs;
+{
+ return re_search_stub (bufp, string, length, start, range, length, regs, 0);
+}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
+int
+re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int length1, length2, start, stop;
+ struct re_registers *regs;
+{
+ return re_search_2_stub (bufp, string1, length1, string2, length2,
+ start, 0, regs, stop, 1);
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+int
+re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int length1, length2, start, range, stop;
+ struct re_registers *regs;
+{
+ return re_search_2_stub (bufp, string1, length1, string2, length2,
+ start, range, regs, stop, 0);
+}
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
+
+static int
+re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
+ stop, ret_len)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int length1, length2, start, range, stop, ret_len;
+ struct re_registers *regs;
+{
+ const char *str;
+ int rval;
+ int len = length1 + length2;
+ int free_str = 0;
+
+ if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
+ return -2;
+
+ /* Concatenate the strings. */
+ if (length2 > 0)
+ if (length1 > 0)
+ {
+ char *s = re_malloc (char, len);
+
+ if (BE (s == NULL, 0))
+ return -2;
+ memcpy (s, string1, length1);
+ memcpy (s + length1, string2, length2);
+ str = s;
+ free_str = 1;
+ }
+ else
+ str = string2;
+ else
+ str = string1;
+
+ rval = re_search_stub (bufp, str, len, start, range, stop, regs,
+ ret_len);
+ if (free_str)
+ re_free ((char *) str);
+ return rval;
+}
+
+/* The parameters have the same meaning as those of re_search.
+ Additional parameters:
+ If RET_LEN is nonzero the length of the match is returned (re_match style);
+ otherwise the position of the match is returned. */
+
+static int
+re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int length, start, range, stop, ret_len;
+ struct re_registers *regs;
+{
+ reg_errcode_t result;
+ regmatch_t *pmatch;
+ int nregs, rval;
+ int eflags = 0;
+
+ /* Check for out-of-range. */
+ if (BE (start < 0 || start > length, 0))
+ return -1;
+ if (BE (start + range > length, 0))
+ range = length - start;
+ else if (BE (start + range < 0, 0))
+ range = -start;
+
+ eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
+ eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
+
+ /* Compile fastmap if we haven't yet. */
+ if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate)
+ re_compile_fastmap (bufp);
+
+ if (BE (bufp->no_sub, 0))
+ regs = NULL;
+
+ /* We need at least 1 register. */
+ if (regs == NULL)
+ nregs = 1;
+ else if (BE (bufp->regs_allocated == REGS_FIXED &&
+ regs->num_regs < bufp->re_nsub + 1, 0))
+ {
+ nregs = regs->num_regs;
+ if (BE (nregs < 1, 0))
+ {
+ /* Nothing can be copied to regs. */
+ regs = NULL;
+ nregs = 1;
+ }
+ }
+ else
+ nregs = bufp->re_nsub + 1;
+ pmatch = re_malloc (regmatch_t, nregs);
+ if (BE (pmatch == NULL, 0))
+ return -2;
+
+ result = re_search_internal (bufp, string, length, start, range, stop,
+ nregs, pmatch, eflags);
+
+ rval = 0;
+
+ /* I hope we needn't fill ther regs with -1's when no match was found. */
+ if (result != REG_NOERROR)
+ rval = -1;
+ else if (regs != NULL)
+ {
+ /* If caller wants register contents data back, copy them. */
+ bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
+ bufp->regs_allocated);
+ if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
+ rval = -2;
+ }
+
+ if (BE (rval == 0, 1))
+ {
+ if (ret_len)
+ {
+ assert (pmatch[0].rm_so == start);
+ rval = pmatch[0].rm_eo - start;
+ }
+ else
+ rval = pmatch[0].rm_so;
+ }
+ re_free (pmatch);
+ return rval;
+}
+
+static unsigned
+re_copy_regs (regs, pmatch, nregs, regs_allocated)
+ struct re_registers *regs;
+ regmatch_t *pmatch;
+ int nregs, regs_allocated;
+{
+ int rval = REGS_REALLOCATE;
+ int i;
+ int need_regs = nregs + 1;
+ /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
+ uses. */
+
+ /* Have the register data arrays been allocated? */
+ if (regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. */
+ regs->start = re_malloc (regoff_t, need_regs);
+ regs->end = re_malloc (regoff_t, need_regs);
+ if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))
+ return REGS_UNALLOCATED;
+ regs->num_regs = need_regs;
+ }
+ else if (regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (BE (need_regs > regs->num_regs, 0))
+ {
+ regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
+ regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
+ if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
+ return REGS_UNALLOCATED;
+ regs->start = new_start;
+ regs->end = new_end;
+ regs->num_regs = need_regs;
+ }
+ }
+ else
+ {
+ assert (regs_allocated == REGS_FIXED);
+ /* This function may not be called with REGS_FIXED and nregs too big. */
+ assert (regs->num_regs >= nregs);
+ rval = REGS_FIXED;
+ }
+
+ /* Copy the regs. */
+ for (i = 0; i < nregs; ++i)
+ {
+ regs->start[i] = pmatch[i].rm_so;
+ regs->end[i] = pmatch[i].rm_eo;
+ }
+ for ( ; i < regs->num_regs; ++i)
+ regs->start[i] = regs->end[i] = -1;
+
+ return rval;
+}
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t *) 0;
+ }
+}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
+\f
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them unless specifically requested. */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+int
+# ifdef _LIBC
+weak_function
+# endif
+re_exec (s)
+ const char *s;
+{
+ return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
+}
+#endif /* _REGEX_RE_COMP */
+\f
+/* Internal entry point. */
+
+/* Searches for a compiled pattern PREG in the string STRING, whose
+ length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same
+ mingings with regexec. START, and RANGE have the same meanings
+ with re_search.
+ Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
+ otherwise return the error code.
+ Note: We assume front end functions already check ranges.
+ (START + RANGE >= 0 && START + RANGE <= LENGTH) */
+
+static reg_errcode_t
+re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
+ eflags)
+ const regex_t *preg;
+ const char *string;
+ int length, start, range, stop, eflags;
+ size_t nmatch;
+ regmatch_t pmatch[];
+{
+ reg_errcode_t err;
+ re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
+ int left_lim, right_lim, incr;
+ int fl_longest_match, match_first, match_kind, match_last = -1;
+ int extra_nmatch;
+ int sb, ch;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+ re_match_context_t mctx = { .dfa = dfa };
+#else
+ re_match_context_t mctx;
+#endif
+ char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate
+ && range && !preg->can_be_null) ? preg->fastmap : NULL;
+ unsigned RE_TRANSLATE_TYPE t = (unsigned RE_TRANSLATE_TYPE) preg->translate;
+
+#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+ memset (&mctx, '\0', sizeof (re_match_context_t));
+ mctx.dfa = dfa;
+#endif
+
+ extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
+ nmatch -= extra_nmatch;
+
+ /* Check if the DFA haven't been compiled. */
+ if (BE (preg->used == 0 || dfa->init_state == NULL
+ || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+ || dfa->init_state_begbuf == NULL, 0))
+ return REG_NOMATCH;
+
+#ifdef DEBUG
+ /* We assume front-end functions already check them. */
+ assert (start + range >= 0 && start + range <= length);
+#endif
+
+ /* If initial states with non-begbuf contexts have no elements,
+ the regex must be anchored. If preg->newline_anchor is set,
+ we'll never use init_state_nl, so do not check it. */
+ if (dfa->init_state->nodes.nelem == 0
+ && dfa->init_state_word->nodes.nelem == 0
+ && (dfa->init_state_nl->nodes.nelem == 0
+ || !preg->newline_anchor))
+ {
+ if (start != 0 && start + range != 0)
+ return REG_NOMATCH;
+ start = range = 0;
+ }
+
+ /* We must check the longest matching, if nmatch > 0. */
+ fl_longest_match = (nmatch != 0 || dfa->nbackref);
+
+ err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
+ preg->translate, preg->syntax & RE_ICASE, dfa);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ mctx.input.stop = stop;
+ mctx.input.raw_stop = stop;
+ mctx.input.newline_anchor = preg->newline_anchor;
+
+ err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+
+ /* We will log all the DFA states through which the dfa pass,
+ if nmatch > 1, or this dfa has "multibyte node", which is a
+ back-reference or a node which can accept multibyte character or
+ multi character collating element. */
+ if (nmatch > 1 || dfa->has_mb_node)
+ {
+ mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
+ if (BE (mctx.state_log == NULL, 0))
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
+ }
+ else
+ mctx.state_log = NULL;
+
+ match_first = start;
+ mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+ : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
+
+ /* Check incrementally whether of not the input string match. */
+ incr = (range < 0) ? -1 : 1;
+ left_lim = (range < 0) ? start + range : start;
+ right_lim = (range < 0) ? start : start + range;
+ sb = dfa->mb_cur_max == 1;
+ match_kind =
+ (fastmap
+ ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+ | (range >= 0 ? 2 : 0)
+ | (t != NULL ? 1 : 0))
+ : 8);
+
+ for (;; match_first += incr)
+ {
+ err = REG_NOMATCH;
+ if (match_first < left_lim || right_lim < match_first)
+ goto free_return;
+
+ /* Advance as rapidly as possible through the string, until we
+ find a plausible place to start matching. This may be done
+ with varying efficiency, so there are various possibilities:
+ only the most common of them are specialized, in order to
+ save on code size. We use a switch statement for speed. */
+ switch (match_kind)
+ {
+ case 8:
+ /* No fastmap. */
+ break;
+
+ case 7:
+ /* Fastmap with single-byte translation, match forward. */
+ while (BE (match_first < right_lim, 1)
+ && !fastmap[t[(unsigned char) string[match_first]]])
+ ++match_first;
+ goto forward_match_found_start_or_reached_end;
+
+ case 6:
+ /* Fastmap without translation, match forward. */
+ while (BE (match_first < right_lim, 1)
+ && !fastmap[(unsigned char) string[match_first]])
+ ++match_first;
+
+ forward_match_found_start_or_reached_end:
+ if (BE (match_first == right_lim, 0))
+ {
+ ch = match_first >= length
+ ? 0 : (unsigned char) string[match_first];
+ if (!fastmap[t ? t[ch] : ch])
+ goto free_return;
+ }
+ break;
+
+ case 4:
+ case 5:
+ /* Fastmap without multi-byte translation, match backwards. */
+ while (match_first >= left_lim)
+ {
+ ch = match_first >= length
+ ? 0 : (unsigned char) string[match_first];
+ if (fastmap[t ? t[ch] : ch])
+ break;
+ --match_first;
+ }
+ if (match_first < left_lim)
+ goto free_return;
+ break;
+
+ default:
+ /* In this case, we can't determine easily the current byte,
+ since it might be a component byte of a multibyte
+ character. Then we use the constructed buffer instead. */
+ for (;;)
+ {
+ /* If MATCH_FIRST is out of the valid range, reconstruct the
+ buffers. */
+ unsigned int offset = match_first - mctx.input.raw_mbs_idx;
+ if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0))
+ {
+ err = re_string_reconstruct (&mctx.input, match_first,
+ eflags);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+
+ offset = match_first - mctx.input.raw_mbs_idx;
+ }
+ /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+ Note that MATCH_FIRST must not be smaller than 0. */
+ ch = (match_first >= length
+ ? 0 : re_string_byte_at (&mctx.input, offset));
+ if (fastmap[ch])
+ break;
+ match_first += incr;
+ if (match_first < left_lim || match_first > right_lim)
+ {
+ err = REG_NOMATCH;
+ goto free_return;
+ }
+ }
+ break;
+ }
+
+ /* Reconstruct the buffers so that the matcher can assume that
+ the matching starts from the beginning of the buffer. */
+ err = re_string_reconstruct (&mctx.input, match_first, eflags);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+
+#ifdef RE_ENABLE_I18N
+ /* Don't consider this char as a possible match start if it part,
+ yet isn't the head, of a multibyte character. */
+ if (!sb && !re_string_first_byte (&mctx.input, 0))
+ continue;
+#endif
+
+ /* It seems to be appropriate one, then use the matcher. */
+ /* We assume that the matching starts from 0. */
+ mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+ match_last = check_matching (&mctx, fl_longest_match,
+ range >= 0 ? &match_first : NULL);
+ if (match_last != -1)
+ {
+ if (BE (match_last == -2, 0))
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
+ else
+ {
+ mctx.match_last = match_last;
+ if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
+ {
+ re_dfastate_t *pstate = mctx.state_log[match_last];
+ mctx.last_node = check_halt_state_context (&mctx, pstate,
+ match_last);
+ }
+ if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+ || dfa->nbackref)
+ {
+ err = prune_impossible_nodes (&mctx);
+ if (err == REG_NOERROR)
+ break;
+ if (BE (err != REG_NOMATCH, 0))
+ goto free_return;
+ match_last = -1;
+ }
+ else
+ break; /* We found a match. */
+ }
+ }
+
+ match_ctx_clean (&mctx);
+ }
+
+#ifdef DEBUG
+ assert (match_last != -1);
+ assert (err == REG_NOERROR);
+#endif
+
+ /* Set pmatch[] if we need. */
+ if (nmatch > 0)
+ {
+ int reg_idx;
+
+ /* Initialize registers. */
+ for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
+ pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
+
+ /* Set the points where matching start/end. */
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = mctx.match_last;
+
+ if (!preg->no_sub && nmatch > 1)
+ {
+ err = set_regs (preg, &mctx, nmatch, pmatch,
+ dfa->has_plural_match && dfa->nbackref > 0);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+
+ /* At last, add the offset to the each registers, since we slided
+ the buffers so that we could assume that the matching starts
+ from 0. */
+ for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+ if (pmatch[reg_idx].rm_so != -1)
+ {
+#ifdef RE_ENABLE_I18N
+ if (BE (mctx.input.offsets_needed != 0, 0))
+ {
+ if (pmatch[reg_idx].rm_so == mctx.input.valid_len)
+ pmatch[reg_idx].rm_so += mctx.input.valid_raw_len - mctx.input.valid_len;
+ else
+ pmatch[reg_idx].rm_so = mctx.input.offsets[pmatch[reg_idx].rm_so];
+ if (pmatch[reg_idx].rm_eo == mctx.input.valid_len)
+ pmatch[reg_idx].rm_eo += mctx.input.valid_raw_len - mctx.input.valid_len;
+ else
+ pmatch[reg_idx].rm_eo = mctx.input.offsets[pmatch[reg_idx].rm_eo];
+ }
+#else
+ assert (mctx.input.offsets_needed == 0);
+#endif
+ pmatch[reg_idx].rm_so += match_first;
+ pmatch[reg_idx].rm_eo += match_first;
+ }
+ for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
+ {
+ pmatch[nmatch + reg_idx].rm_so = -1;
+ pmatch[nmatch + reg_idx].rm_eo = -1;
+ }
+
+ if (dfa->subexp_map)
+ for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+ if (dfa->subexp_map[reg_idx] != reg_idx)
+ {
+ pmatch[reg_idx + 1].rm_so
+ = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+ pmatch[reg_idx + 1].rm_eo
+ = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+ }
+ }
+
+ free_return:
+ re_free (mctx.state_log);
+ if (dfa->nbackref)
+ match_ctx_free (&mctx);
+ re_string_destruct (&mctx.input);
+ return err;
+}
+
+static reg_errcode_t
+prune_impossible_nodes (mctx)
+ re_match_context_t *mctx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int halt_node, match_last;
+ reg_errcode_t ret;
+ re_dfastate_t **sifted_states;
+ re_dfastate_t **lim_states = NULL;
+ re_sift_context_t sctx;
+#ifdef DEBUG
+ assert (mctx->state_log != NULL);
+#endif
+ match_last = mctx->match_last;
+ halt_node = mctx->last_node;
+ sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
+ if (BE (sifted_states == NULL, 0))
+ {
+ ret = REG_ESPACE;
+ goto free_return;
+ }
+ if (dfa->nbackref)
+ {
+ lim_states = re_malloc (re_dfastate_t *, match_last + 1);
+ if (BE (lim_states == NULL, 0))
+ {
+ ret = REG_ESPACE;
+ goto free_return;
+ }
+ while (1)
+ {
+ memset (lim_states, '\0',
+ sizeof (re_dfastate_t *) * (match_last + 1));
+ sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
+ match_last);
+ ret = sift_states_backward (mctx, &sctx);
+ re_node_set_free (&sctx.limits);
+ if (BE (ret != REG_NOERROR, 0))
+ goto free_return;
+ if (sifted_states[0] != NULL || lim_states[0] != NULL)
+ break;
+ do
+ {
+ --match_last;
+ if (match_last < 0)
+ {
+ ret = REG_NOMATCH;
+ goto free_return;
+ }
+ } while (mctx->state_log[match_last] == NULL
+ || !mctx->state_log[match_last]->halt);
+ halt_node = check_halt_state_context (mctx,
+ mctx->state_log[match_last],
+ match_last);
+ }
+ ret = merge_state_array (dfa, sifted_states, lim_states,
+ match_last + 1);
+ re_free (lim_states);
+ lim_states = NULL;
+ if (BE (ret != REG_NOERROR, 0))
+ goto free_return;
+ }
+ else
+ {
+ sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
+ ret = sift_states_backward (mctx, &sctx);
+ re_node_set_free (&sctx.limits);
+ if (BE (ret != REG_NOERROR, 0))
+ goto free_return;
+ }
+ re_free (mctx->state_log);
+ mctx->state_log = sifted_states;
+ sifted_states = NULL;
+ mctx->last_node = halt_node;
+ mctx->match_last = match_last;
+ ret = REG_NOERROR;
+ free_return:
+ re_free (sifted_states);
+ re_free (lim_states);
+ return ret;
+}
+
+/* Acquire an initial state and return it.
+ We must select appropriate initial state depending on the context,
+ since initial states may have constraints like "\<", "^", etc.. */
+
+static inline re_dfastate_t *
+acquire_init_state_context (err, mctx, idx)
+ reg_errcode_t *err;
+ const re_match_context_t *mctx;
+ int idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ if (dfa->init_state->has_constraint)
+ {
+ unsigned int context;
+ context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
+ if (IS_WORD_CONTEXT (context))
+ return dfa->init_state_word;
+ else if (IS_ORDINARY_CONTEXT (context))
+ return dfa->init_state;
+ else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
+ return dfa->init_state_begbuf;
+ else if (IS_NEWLINE_CONTEXT (context))
+ return dfa->init_state_nl;
+ else if (IS_BEGBUF_CONTEXT (context))
+ {
+ /* It is relatively rare case, then calculate on demand. */
+ return re_acquire_state_context (err, dfa,
+ dfa->init_state->entrance_nodes,
+ context);
+ }
+ else
+ /* Must not happen? */
+ return dfa->init_state;
+ }
+ else
+ return dfa->init_state;
+}
+
+/* Check whether the regular expression match input string INPUT or not,
+ and return the index where the matching end, return -1 if not match,
+ or return -2 in case of an error.
+ FL_LONGEST_MATCH means we want the POSIX longest matching.
+ If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
+ next place where we may want to try matching.
+ Note that the matcher assume that the maching starts from the current
+ index of the buffer. */
+
+static int
+check_matching (mctx, fl_longest_match, p_match_first)
+ re_match_context_t *mctx;
+ int fl_longest_match;
+ int *p_match_first;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int match = 0;
+ int match_last = -1;
+ int cur_str_idx = re_string_cur_idx (&mctx->input);
+ re_dfastate_t *cur_state;
+ int at_init_state = p_match_first != NULL;
+ int next_start_idx = cur_str_idx;
+
+ err = REG_NOERROR;
+ cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
+ /* An initial state must not be NULL (invalid). */
+ if (BE (cur_state == NULL, 0))
+ {
+ assert (err == REG_ESPACE);
+ return -2;
+ }
+
+ if (mctx->state_log != NULL)
+ {
+ mctx->state_log[cur_str_idx] = cur_state;
+
+ /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
+ later. E.g. Processing back references. */
+ if (BE (dfa->nbackref, 0))
+ {
+ at_init_state = 0;
+ err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ if (cur_state->has_backref)
+ {
+ err = transit_state_bkref (mctx, &cur_state->nodes);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+ }
+
+ /* If the RE accepts NULL string. */
+ if (BE (cur_state->halt, 0))
+ {
+ if (!cur_state->has_constraint
+ || check_halt_state_context (mctx, cur_state, cur_str_idx))
+ {
+ if (!fl_longest_match)
+ return cur_str_idx;
+ else
+ {
+ match_last = cur_str_idx;
+ match = 1;
+ }
+ }
+ }
+
+ while (!re_string_eoi (&mctx->input))
+ {
+ re_dfastate_t *old_state = cur_state;
+ int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
+
+ if (BE (next_char_idx >= mctx->input.bufs_len, 0)
+ || (BE (next_char_idx >= mctx->input.valid_len, 0)
+ && mctx->input.valid_len < mctx->input.len))
+ {
+ err = extend_buffers (mctx);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ assert (err == REG_ESPACE);
+ return -2;
+ }
+ }
+
+ cur_state = transit_state (&err, mctx, cur_state);
+ if (mctx->state_log != NULL)
+ cur_state = merge_state_with_log (&err, mctx, cur_state);
+
+ if (cur_state == NULL)
+ {
+ /* Reached the invalid state or an error. Try to recover a valid
+ state using the state log, if available and if we have not
+ already found a valid (even if not the longest) match. */
+ if (BE (err != REG_NOERROR, 0))
+ return -2;
+
+ if (mctx->state_log == NULL
+ || (match && !fl_longest_match)
+ || (cur_state = find_recover_state (&err, mctx)) == NULL)
+ break;
+ }
+
+ if (BE (at_init_state, 0))
+ {
+ if (old_state == cur_state)
+ next_start_idx = next_char_idx;
+ else
+ at_init_state = 0;
+ }
+
+ if (cur_state->halt)
+ {
+ /* Reached a halt state.
+ Check the halt state can satisfy the current context. */
+ if (!cur_state->has_constraint
+ || check_halt_state_context (mctx, cur_state,
+ re_string_cur_idx (&mctx->input)))
+ {
+ /* We found an appropriate halt state. */
+ match_last = re_string_cur_idx (&mctx->input);
+ match = 1;
+
+ /* We found a match, do not modify match_first below. */
+ p_match_first = NULL;
+ if (!fl_longest_match)
+ break;
+ }
+ }
+ }
+
+ if (p_match_first)
+ *p_match_first += next_start_idx;
+
+ return match_last;
+}
+
+/* Check NODE match the current context. */
+
+static int check_halt_node_context (dfa, node, context)
+ const re_dfa_t *dfa;
+ int node;
+ unsigned int context;
+{
+ re_token_type_t type = dfa->nodes[node].type;
+ unsigned int constraint = dfa->nodes[node].constraint;
+ if (type != END_OF_RE)
+ return 0;
+ if (!constraint)
+ return 1;
+ if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
+ return 0;
+ return 1;
+}
+
+/* Check the halt state STATE match the current context.
+ Return 0 if not match, if the node, STATE has, is a halt node and
+ match the context, return the node. */
+
+static int
+check_halt_state_context (mctx, state, idx)
+ const re_match_context_t *mctx;
+ const re_dfastate_t *state;
+ int idx;
+{
+ int i;
+ unsigned int context;
+#ifdef DEBUG
+ assert (state->halt);
+#endif
+ context = re_string_context_at (&mctx->input, idx, mctx->eflags);
+ for (i = 0; i < state->nodes.nelem; ++i)
+ if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
+ return state->nodes.elems[i];
+ return 0;
+}
+
+/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+ corresponding to the DFA).
+ Return the destination node, and update EPS_VIA_NODES, return -1 in case
+ of errors. */
+
+static int
+proceed_next_node (mctx, nregs, regs, pidx, node, eps_via_nodes, fs)
+ const re_match_context_t *mctx;
+ regmatch_t *regs;
+ int nregs, *pidx, node;
+ re_node_set *eps_via_nodes;
+ struct re_fail_stack_t *fs;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int i, err, dest_node;
+ dest_node = -1;
+ if (IS_EPSILON_NODE (dfa->nodes[node].type))
+ {
+ re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+ re_node_set *edests = &dfa->edests[node];
+ int dest_node;
+ err = re_node_set_insert (eps_via_nodes, node);
+ if (BE (err < 0, 0))
+ return -2;
+ /* Pick up a valid destination, or return -1 if none is found. */
+ for (dest_node = -1, i = 0; i < edests->nelem; ++i)
+ {
+ int candidate = edests->elems[i];
+ if (!re_node_set_contains (cur_nodes, candidate))
+ continue;
+ if (dest_node == -1)
+ dest_node = candidate;
+
+ else
+ {
+ /* In order to avoid infinite loop like "(a*)*", return the second
+ epsilon-transition if the first was already considered. */
+ if (re_node_set_contains (eps_via_nodes, dest_node))
+ return candidate;
+
+ /* Otherwise, push the second epsilon-transition on the fail stack. */
+ else if (fs != NULL
+ && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+ eps_via_nodes) != REG_NOERROR)
+ return -2;
+
+ /* We know we are going to exit. */
+ break;
+ }
+ }
+ return dest_node;
+ }
+ else
+ {
+ int naccepted = 0;
+ re_token_type_t type = dfa->nodes[node].type;
+
+#ifdef RE_ENABLE_I18N
+ if (dfa->nodes[node].accept_mb)
+ naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
+ else
+#endif /* RE_ENABLE_I18N */
+ if (type == OP_BACK_REF)
+ {
+ int subexp_idx = dfa->nodes[node].opr.idx + 1;
+ naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
+ if (fs != NULL)
+ {
+ if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
+ return -1;
+ else if (naccepted)
+ {
+ char *buf = (char *) re_string_get_buffer (&mctx->input);
+ if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+ naccepted) != 0)
+ return -1;
+ }
+ }
+
+ if (naccepted == 0)
+ {
+ err = re_node_set_insert (eps_via_nodes, node);
+ if (BE (err < 0, 0))
+ return -2;
+ dest_node = dfa->edests[node].elems[0];
+ if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+ dest_node))
+ return dest_node;
+ }
+ }
+
+ if (naccepted != 0
+ || check_node_accept (mctx, dfa->nodes + node, *pidx))
+ {
+ dest_node = dfa->nexts[node];
+ *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
+ if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
+ || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+ dest_node)))
+ return -1;
+ re_node_set_empty (eps_via_nodes);
+ return dest_node;
+ }
+ }
+ return -1;
+}
+
+static reg_errcode_t
+push_fail_stack (fs, str_idx, dest_node, nregs, regs, eps_via_nodes)
+ struct re_fail_stack_t *fs;
+ int str_idx, dest_node, nregs;
+ regmatch_t *regs;
+ re_node_set *eps_via_nodes;
+{
+ reg_errcode_t err;
+ int num = fs->num++;
+ if (fs->num == fs->alloc)
+ {
+ struct re_fail_stack_ent_t *new_array;
+ new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
+ * fs->alloc * 2));
+ if (new_array == NULL)
+ return REG_ESPACE;
+ fs->alloc *= 2;
+ fs->stack = new_array;
+ }
+ fs->stack[num].idx = str_idx;
+ fs->stack[num].node = dest_node;
+ fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+ if (fs->stack[num].regs == NULL)
+ return REG_ESPACE;
+ memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+ err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+ return err;
+}
+
+static int
+pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)
+ struct re_fail_stack_t *fs;
+ int *pidx, nregs;
+ regmatch_t *regs;
+ re_node_set *eps_via_nodes;
+{
+ int num = --fs->num;
+ assert (num >= 0);
+ *pidx = fs->stack[num].idx;
+ memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+ re_node_set_free (eps_via_nodes);
+ re_free (fs->stack[num].regs);
+ *eps_via_nodes = fs->stack[num].eps_via_nodes;
+ return fs->stack[num].node;
+}
+
+/* Set the positions where the subexpressions are starts/ends to registers
+ PMATCH.
+ Note: We assume that pmatch[0] is already set, and
+ pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */
+
+static reg_errcode_t
+set_regs (preg, mctx, nmatch, pmatch, fl_backtrack)
+ const regex_t *preg;
+ const re_match_context_t *mctx;
+ size_t nmatch;
+ regmatch_t *pmatch;
+ int fl_backtrack;
+{
+ re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ int idx, cur_node;
+ re_node_set eps_via_nodes;
+ struct re_fail_stack_t *fs;
+ struct re_fail_stack_t fs_body = { 0, 2, NULL };
+ regmatch_t *prev_idx_match;
+
+#ifdef DEBUG
+ assert (nmatch > 1);
+ assert (mctx->state_log != NULL);
+#endif
+ if (fl_backtrack)
+ {
+ fs = &fs_body;
+ fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+ if (fs->stack == NULL)
+ return REG_ESPACE;
+ }
+ else
+ fs = NULL;
+
+ cur_node = dfa->init_node;
+ re_node_set_init_empty (&eps_via_nodes);
+
+ prev_idx_match = re_malloc (regmatch_t, nmatch);
+ memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+
+ for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
+ {
+ update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+
+ if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+ {
+ int reg_idx;
+ if (fs)
+ {
+ for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+ if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+ break;
+ if (reg_idx == nmatch)
+ {
+ re_node_set_free (&eps_via_nodes);
+ re_free (prev_idx_match);
+ return free_fail_stack_return (fs);
+ }
+ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+ &eps_via_nodes);
+ }
+ else
+ {
+ re_node_set_free (&eps_via_nodes);
+ re_free (prev_idx_match);
+ return REG_NOERROR;
+ }
+ }
+
+ /* Proceed to next node. */
+ cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+ &eps_via_nodes, fs);
+
+ if (BE (cur_node < 0, 0))
+ {
+ if (BE (cur_node == -2, 0))
+ {
+ re_node_set_free (&eps_via_nodes);
+ free_fail_stack_return (fs);
+ re_free (prev_idx_match);
+ return REG_ESPACE;
+ }
+ if (fs)
+ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+ &eps_via_nodes);
+ else
+ {
+ re_node_set_free (&eps_via_nodes);
+ re_free (prev_idx_match);
+ return REG_NOMATCH;
+ }
+ }
+ }
+ re_node_set_free (&eps_via_nodes);
+ re_free (prev_idx_match);
+ return free_fail_stack_return (fs);
+}
+
+static reg_errcode_t
+free_fail_stack_return (fs)
+ struct re_fail_stack_t *fs;
+{
+ if (fs)
+ {
+ int fs_idx;
+ for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
+ {
+ re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
+ re_free (fs->stack[fs_idx].regs);
+ }
+ re_free (fs->stack);
+ }
+ return REG_NOERROR;
+}
+
+static void
+update_regs (dfa, pmatch, prev_idx_match, cur_node, cur_idx, nmatch)
+ re_dfa_t *dfa;
+ regmatch_t *pmatch, *prev_idx_match;
+ int cur_node, cur_idx, nmatch;
+{
+ int type = dfa->nodes[cur_node].type;
+ if (type == OP_OPEN_SUBEXP)
+ {
+ int reg_num = dfa->nodes[cur_node].opr.idx + 1;
+
+ /* We are at the first node of this sub expression. */
+ if (reg_num < nmatch)
+ {
+ pmatch[reg_num].rm_so = cur_idx;
+ pmatch[reg_num].rm_eo = -1;
+ }
+ }
+ else if (type == OP_CLOSE_SUBEXP)
+ {
+ int reg_num = dfa->nodes[cur_node].opr.idx + 1;
+ if (reg_num < nmatch)
+ {
+ /* We are at the last node of this sub expression. */
+ if (pmatch[reg_num].rm_so < cur_idx)
+ {
+ pmatch[reg_num].rm_eo = cur_idx;
+ /* This is a non-empty match or we are not inside an optional
+ subexpression. Accept this right away. */
+ memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+ }
+ else
+ {
+ if (dfa->nodes[cur_node].opt_subexp
+ && prev_idx_match[reg_num].rm_so != -1)
+ /* We transited through an empty match for an optional
+ subexpression, like (a?)*, and this is not the subexp's
+ first match. Copy back the old content of the registers
+ so that matches of an inner subexpression are undone as
+ well, like in ((a?))*. */
+ memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
+ else
+ /* We completed a subexpression, but it may be part of
+ an optional one, so do not update PREV_IDX_MATCH. */
+ pmatch[reg_num].rm_eo = cur_idx;
+ }
+ }
+ }
+}
+
+/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
+ and sift the nodes in each states according to the following rules.
+ Updated state_log will be wrote to STATE_LOG.
+
+ Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
+ 1. When STR_IDX == MATCH_LAST(the last index in the state_log):
+ If `a' isn't the LAST_NODE and `a' can't epsilon transit to
+ the LAST_NODE, we throw away the node `a'.
+ 2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
+ string `s' and transit to `b':
+ i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
+ away the node `a'.
+ ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
+ thrown away, we throw away the node `a'.
+ 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
+ i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
+ node `a'.
+ ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
+ we throw away the node `a'. */
+
+#define STATE_NODE_CONTAINS(state,node) \
+ ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
+
+static reg_errcode_t
+sift_states_backward (mctx, sctx)
+ re_match_context_t *mctx;
+ re_sift_context_t *sctx;
+{
+ reg_errcode_t err;
+ int null_cnt = 0;
+ int str_idx = sctx->last_str_idx;
+ re_node_set cur_dest;
+
+#ifdef DEBUG
+ assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
+#endif
+
+ /* Build sifted state_log[str_idx]. It has the nodes which can epsilon
+ transit to the last_node and the last_node itself. */
+ err = re_node_set_init_1 (&cur_dest, sctx->last_node);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+
+ /* Then check each states in the state_log. */
+ while (str_idx > 0)
+ {
+ /* Update counters. */
+ null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
+ if (null_cnt > mctx->max_mb_elem_len)
+ {
+ memset (sctx->sifted_states, '\0',
+ sizeof (re_dfastate_t *) * str_idx);
+ re_node_set_free (&cur_dest);
+ return REG_NOERROR;
+ }
+ re_node_set_empty (&cur_dest);
+ --str_idx;
+
+ if (mctx->state_log[str_idx])
+ {
+ err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+
+ /* Add all the nodes which satisfy the following conditions:
+ - It can epsilon transit to a node in CUR_DEST.
+ - It is in CUR_SRC.
+ And update state_log. */
+ err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ err = REG_NOERROR;
+ free_return:
+ re_node_set_free (&cur_dest);
+ return err;
+}
+
+static reg_errcode_t
+build_sifted_states (mctx, sctx, str_idx, cur_dest)
+ re_match_context_t *mctx;
+ re_sift_context_t *sctx;
+ int str_idx;
+ re_node_set *cur_dest;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
+ int i;
+
+ /* Then build the next sifted state.
+ We build the next sifted state on `cur_dest', and update
+ `sifted_states[str_idx]' with `cur_dest'.
+ Note:
+ `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
+ `cur_src' points the node_set of the old `state_log[str_idx]'
+ (with the epsilon nodes pre-filtered out). */
+ for (i = 0; i < cur_src->nelem; i++)
+ {
+ int prev_node = cur_src->elems[i];
+ int naccepted = 0;
+ int ret;
+
+#ifdef DEBUG
+ re_token_type_t type = dfa->nodes[prev_node].type;
+ assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+ /* If the node may accept `multi byte'. */
+ if (dfa->nodes[prev_node].accept_mb)
+ naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
+ str_idx, sctx->last_str_idx);
+#endif /* RE_ENABLE_I18N */
+
+ /* We don't check backreferences here.
+ See update_cur_sifted_state(). */
+ if (!naccepted
+ && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+ && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+ dfa->nexts[prev_node]))
+ naccepted = 1;
+
+ if (naccepted == 0)
+ continue;
+
+ if (sctx->limits.nelem)
+ {
+ int to_idx = str_idx + naccepted;
+ if (check_dst_limits (mctx, &sctx->limits,
+ dfa->nexts[prev_node], to_idx,
+ prev_node, str_idx))
+ continue;
+ }
+ ret = re_node_set_insert (cur_dest, prev_node);
+ if (BE (ret == -1, 0))
+ return REG_ESPACE;
+ }
+
+ return REG_NOERROR;
+}
+
+/* Helper functions. */
+
+static reg_errcode_t
+clean_state_log_if_needed (mctx, next_state_log_idx)
+ re_match_context_t *mctx;
+ int next_state_log_idx;
+{
+ int top = mctx->state_log_top;
+
+ if (next_state_log_idx >= mctx->input.bufs_len
+ || (next_state_log_idx >= mctx->input.valid_len
+ && mctx->input.valid_len < mctx->input.len))
+ {
+ reg_errcode_t err;
+ err = extend_buffers (mctx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+
+ if (top < next_state_log_idx)
+ {
+ memset (mctx->state_log + top + 1, '\0',
+ sizeof (re_dfastate_t *) * (next_state_log_idx - top));
+ mctx->state_log_top = next_state_log_idx;
+ }
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+merge_state_array (dfa, dst, src, num)
+ re_dfa_t *dfa;
+ re_dfastate_t **dst;
+ re_dfastate_t **src;
+ int num;
+{
+ int st_idx;
+ reg_errcode_t err;
+ for (st_idx = 0; st_idx < num; ++st_idx)
+ {
+ if (dst[st_idx] == NULL)
+ dst[st_idx] = src[st_idx];
+ else if (src[st_idx] != NULL)
+ {
+ re_node_set merged_set;
+ err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
+ &src[st_idx]->nodes);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+ re_node_set_free (&merged_set);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+update_cur_sifted_state (mctx, sctx, str_idx, dest_nodes)
+ re_match_context_t *mctx;
+ re_sift_context_t *sctx;
+ int str_idx;
+ re_node_set *dest_nodes;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ const re_node_set *candidates;
+ candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
+ : &mctx->state_log[str_idx]->nodes);
+
+ if (dest_nodes->nelem == 0)
+ sctx->sifted_states[str_idx] = NULL;
+ else
+ {
+ if (candidates)
+ {
+ /* At first, add the nodes which can epsilon transit to a node in
+ DEST_NODE. */
+ err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ /* Then, check the limitations in the current sift_context. */
+ if (sctx->limits.nelem)
+ {
+ err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+ mctx->bkref_ents, str_idx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+
+ sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+
+ if (candidates && mctx->state_log[str_idx]->has_backref)
+ {
+ err = sift_states_bkref (mctx, sctx, str_idx, candidates);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+add_epsilon_src_nodes (dfa, dest_nodes, candidates)
+ re_dfa_t *dfa;
+ re_node_set *dest_nodes;
+ const re_node_set *candidates;
+{
+ reg_errcode_t err = REG_NOERROR;
+ int i;
+
+ re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ if (!state->inveclosure.alloc)
+ {
+ err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
+ if (BE (err != REG_NOERROR, 0))
+ return REG_ESPACE;
+ for (i = 0; i < dest_nodes->nelem; i++)
+ re_node_set_merge (&state->inveclosure,
+ dfa->inveclosures + dest_nodes->elems[i]);
+ }
+ return re_node_set_add_intersect (dest_nodes, candidates,
+ &state->inveclosure);
+}
+
+static reg_errcode_t
+sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates)
+ re_dfa_t *dfa;
+ int node;
+ re_node_set *dest_nodes;
+ const re_node_set *candidates;
+{
+ int ecl_idx;
+ reg_errcode_t err;
+ re_node_set *inv_eclosure = dfa->inveclosures + node;
+ re_node_set except_nodes;
+ re_node_set_init_empty (&except_nodes);
+ for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+ {
+ int cur_node = inv_eclosure->elems[ecl_idx];
+ if (cur_node == node)
+ continue;
+ if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
+ {
+ int edst1 = dfa->edests[cur_node].elems[0];
+ int edst2 = ((dfa->edests[cur_node].nelem > 1)
+ ? dfa->edests[cur_node].elems[1] : -1);
+ if ((!re_node_set_contains (inv_eclosure, edst1)
+ && re_node_set_contains (dest_nodes, edst1))
+ || (edst2 > 0
+ && !re_node_set_contains (inv_eclosure, edst2)
+ && re_node_set_contains (dest_nodes, edst2)))
+ {
+ err = re_node_set_add_intersect (&except_nodes, candidates,
+ dfa->inveclosures + cur_node);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&except_nodes);
+ return err;
+ }
+ }
+ }
+ }
+ for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+ {
+ int cur_node = inv_eclosure->elems[ecl_idx];
+ if (!re_node_set_contains (&except_nodes, cur_node))
+ {
+ int idx = re_node_set_contains (dest_nodes, cur_node) - 1;
+ re_node_set_remove_at (dest_nodes, idx);
+ }
+ }
+ re_node_set_free (&except_nodes);
+ return REG_NOERROR;
+}
+
+static int
+check_dst_limits (mctx, limits, dst_node, dst_idx, src_node, src_idx)
+ re_match_context_t *mctx;
+ re_node_set *limits;
+ int dst_node, dst_idx, src_node, src_idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int lim_idx, src_pos, dst_pos;
+
+ int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+ int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
+ for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+ {
+ int subexp_idx;
+ struct re_backref_cache_entry *ent;
+ ent = mctx->bkref_ents + limits->elems[lim_idx];
+ subexp_idx = dfa->nodes[ent->node].opr.idx;
+
+ dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+ subexp_idx, dst_node, dst_idx,
+ dst_bkref_idx);
+ src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+ subexp_idx, src_node, src_idx,
+ src_bkref_idx);
+
+ /* In case of:
+ <src> <dst> ( <subexp> )
+ ( <subexp> ) <src> <dst>
+ ( <subexp1> <src> <subexp2> <dst> <subexp3> ) */
+ if (src_pos == dst_pos)
+ continue; /* This is unrelated limitation. */
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int
+check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, from_node, bkref_idx)
+ re_match_context_t *mctx;
+ int boundaries, subexp_idx, from_node, bkref_idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ re_node_set *eclosures = dfa->eclosures + from_node;
+ int node_idx;
+
+ /* Else, we are on the boundary: examine the nodes on the epsilon
+ closure. */
+ for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
+ {
+ int node = eclosures->elems[node_idx];
+ switch (dfa->nodes[node].type)
+ {
+ case OP_BACK_REF:
+ if (bkref_idx != -1)
+ {
+ struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+ do
+ {
+ int dst, cpos;
+
+ if (ent->node != node)
+ continue;
+
+ if (subexp_idx <= 8 * sizeof (ent->eps_reachable_subexps_map)
+ && !(ent->eps_reachable_subexps_map & (1 << subexp_idx)))
+ continue;
+
+ /* Recurse trying to reach the OP_OPEN_SUBEXP and
+ OP_CLOSE_SUBEXP cases below. But, if the
+ destination node is the same node as the source
+ node, don't recurse because it would cause an
+ infinite loop: a regex that exhibits this behavior
+ is ()\1*\1* */
+ dst = dfa->edests[node].elems[0];
+ if (dst == from_node)
+ {
+ if (boundaries & 1)
+ return -1;
+ else /* if (boundaries & 2) */
+ return 0;
+ }
+
+ cpos =
+ check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+ dst, bkref_idx);
+ if (cpos == -1 /* && (boundaries & 1) */)
+ return -1;
+ if (cpos == 0 && (boundaries & 2))
+ return 0;
+
+ ent->eps_reachable_subexps_map &= ~(1 << subexp_idx);
+ }
+ while (ent++->more);
+ }
+ break;
+
+ case OP_OPEN_SUBEXP:
+ if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
+ return -1;
+ break;
+
+ case OP_CLOSE_SUBEXP:
+ if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
+ return 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+check_dst_limits_calc_pos (mctx, limit, subexp_idx, from_node, str_idx, bkref_idx)
+ re_match_context_t *mctx;
+ int limit, subexp_idx, from_node, str_idx, bkref_idx;
+{
+ struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+ int boundaries;
+
+ /* If we are outside the range of the subexpression, return -1 or 1. */
+ if (str_idx < lim->subexp_from)
+ return -1;
+
+ if (lim->subexp_to < str_idx)
+ return 1;
+
+ /* If we are within the subexpression, return 0. */
+ boundaries = (str_idx == lim->subexp_from);
+ boundaries |= (str_idx == lim->subexp_to) << 1;
+ if (boundaries == 0)
+ return 0;
+
+ /* Else, examine epsilon closure. */
+ return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+ from_node, bkref_idx);
+}
+
+/* Check the limitations of sub expressions LIMITS, and remove the nodes
+ which are against limitations from DEST_NODES. */
+
+static reg_errcode_t
+check_subexp_limits (dfa, dest_nodes, candidates, limits, bkref_ents, str_idx)
+ re_dfa_t *dfa;
+ re_node_set *dest_nodes;
+ const re_node_set *candidates;
+ re_node_set *limits;
+ struct re_backref_cache_entry *bkref_ents;
+ int str_idx;
+{
+ reg_errcode_t err;
+ int node_idx, lim_idx;
+
+ for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+ {
+ int subexp_idx;
+ struct re_backref_cache_entry *ent;
+ ent = bkref_ents + limits->elems[lim_idx];
+
+ if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
+ continue; /* This is unrelated limitation. */
+
+ subexp_idx = dfa->nodes[ent->node].opr.idx;
+ if (ent->subexp_to == str_idx)
+ {
+ int ops_node = -1;
+ int cls_node = -1;
+ for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+ {
+ int node = dest_nodes->elems[node_idx];
+ re_token_type_t type = dfa->nodes[node].type;
+ if (type == OP_OPEN_SUBEXP
+ && subexp_idx == dfa->nodes[node].opr.idx)
+ ops_node = node;
+ else if (type == OP_CLOSE_SUBEXP
+ && subexp_idx == dfa->nodes[node].opr.idx)
+ cls_node = node;
+ }
+
+ /* Check the limitation of the open subexpression. */
+ /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */
+ if (ops_node >= 0)
+ {
+ err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
+ candidates);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+
+ /* Check the limitation of the close subexpression. */
+ if (cls_node >= 0)
+ for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+ {
+ int node = dest_nodes->elems[node_idx];
+ if (!re_node_set_contains (dfa->inveclosures + node,
+ cls_node)
+ && !re_node_set_contains (dfa->eclosures + node,
+ cls_node))
+ {
+ /* It is against this limitation.
+ Remove it form the current sifted state. */
+ err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+ candidates);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ --node_idx;
+ }
+ }
+ }
+ else /* (ent->subexp_to != str_idx) */
+ {
+ for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+ {
+ int node = dest_nodes->elems[node_idx];
+ re_token_type_t type = dfa->nodes[node].type;
+ if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
+ {
+ if (subexp_idx != dfa->nodes[node].opr.idx)
+ continue;
+ /* It is against this limitation.
+ Remove it form the current sifted state. */
+ err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+ candidates);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+ }
+ }
+ return REG_NOERROR;
+}
+
+static reg_errcode_t
+sift_states_bkref (mctx, sctx, str_idx, candidates)
+ re_match_context_t *mctx;
+ re_sift_context_t *sctx;
+ int str_idx;
+ const re_node_set *candidates;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int node_idx, node;
+ re_sift_context_t local_sctx;
+ int first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+ if (first_idx == -1)
+ return REG_NOERROR;
+
+ local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */
+
+ for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
+ {
+ int enabled_idx;
+ re_token_type_t type;
+ struct re_backref_cache_entry *entry;
+ node = candidates->elems[node_idx];
+ type = dfa->nodes[node].type;
+ /* Avoid infinite loop for the REs like "()\1+". */
+ if (node == sctx->last_node && str_idx == sctx->last_str_idx)
+ continue;
+ if (type != OP_BACK_REF)
+ continue;
+
+ entry = mctx->bkref_ents + first_idx;
+ enabled_idx = first_idx;
+ do
+ {
+ int subexp_len, to_idx, dst_node;
+ re_dfastate_t *cur_state;
+
+ if (entry->node != node)
+ continue;
+ subexp_len = entry->subexp_to - entry->subexp_from;
+ to_idx = str_idx + subexp_len;
+ dst_node = (subexp_len ? dfa->nexts[node]
+ : dfa->edests[node].elems[0]);
+
+ if (to_idx > sctx->last_str_idx
+ || sctx->sifted_states[to_idx] == NULL
+ || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+ || check_dst_limits (mctx, &sctx->limits, node,
+ str_idx, dst_node, to_idx))
+ continue;
+
+ if (local_sctx.sifted_states == NULL)
+ {
+ local_sctx = *sctx;
+ err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ local_sctx.last_node = node;
+ local_sctx.last_str_idx = str_idx;
+ err = re_node_set_insert (&local_sctx.limits, enabled_idx);
+ if (BE (err < 0, 0))
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
+ cur_state = local_sctx.sifted_states[str_idx];
+ err = sift_states_backward (mctx, &local_sctx);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ if (sctx->limited_states != NULL)
+ {
+ err = merge_state_array (dfa, sctx->limited_states,
+ local_sctx.sifted_states,
+ str_idx + 1);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ local_sctx.sifted_states[str_idx] = cur_state;
+ re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+ /* mctx->bkref_ents may have changed, reload the pointer. */
+ entry = mctx->bkref_ents + enabled_idx;
+ }
+ while (enabled_idx++, entry++->more);
+ }
+ err = REG_NOERROR;
+ free_return:
+ if (local_sctx.sifted_states != NULL)
+ {
+ re_node_set_free (&local_sctx.limits);
+ }
+
+ return err;
+}
+
+
+#ifdef RE_ENABLE_I18N
+static int
+sift_states_iter_mb (mctx, sctx, node_idx, str_idx, max_str_idx)
+ const re_match_context_t *mctx;
+ re_sift_context_t *sctx;
+ int node_idx, str_idx, max_str_idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int naccepted;
+ /* Check the node can accept `multi byte'. */
+ naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
+ if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
+ !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
+ dfa->nexts[node_idx]))
+ /* The node can't accept the `multi byte', or the
+ destination was already thrown away, then the node
+ could't accept the current input `multi byte'. */
+ naccepted = 0;
+ /* Otherwise, it is sure that the node could accept
+ `naccepted' bytes input. */
+ return naccepted;
+}
+#endif /* RE_ENABLE_I18N */
+
+\f
+/* Functions for state transition. */
+
+/* Return the next state to which the current state STATE will transit by
+ accepting the current input byte, and update STATE_LOG if necessary.
+ If STATE can accept a multibyte char/collating element/back reference
+ update the destination of STATE_LOG. */
+
+static re_dfastate_t *
+transit_state (err, mctx, state)
+ reg_errcode_t *err;
+ re_match_context_t *mctx;
+ re_dfastate_t *state;
+{
+ re_dfastate_t **trtable;
+ unsigned char ch;
+
+#ifdef RE_ENABLE_I18N
+ /* If the current state can accept multibyte. */
+ if (BE (state->accept_mb, 0))
+ {
+ *err = transit_state_mb (mctx, state);
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+ }
+#endif /* RE_ENABLE_I18N */
+
+ /* Then decide the next state with the single byte. */
+#if 0
+ if (0)
+ /* don't use transition table */
+ return transit_state_sb (err, mctx, state);
+#endif
+
+ /* Use transition table */
+ ch = re_string_fetch_byte (&mctx->input);
+ for (;;)
+ {
+ trtable = state->trtable;
+ if (BE (trtable != NULL, 1))
+ return trtable[ch];
+
+ trtable = state->word_trtable;
+ if (BE (trtable != NULL, 1))
+ {
+ unsigned int context;
+ context
+ = re_string_context_at (&mctx->input,
+ re_string_cur_idx (&mctx->input) - 1,
+ mctx->eflags);
+ if (IS_WORD_CONTEXT (context))
+ return trtable[ch + SBC_MAX];
+ else
+ return trtable[ch];
+ }
+
+ if (!build_trtable (mctx->dfa, state))
+ {
+ *err = REG_ESPACE;
+ return NULL;
+ }
+
+ /* Retry, we now have a transition table. */
+ }
+}
+
+/* Update the state_log if we need */
+re_dfastate_t *
+merge_state_with_log (err, mctx, next_state)
+ reg_errcode_t *err;
+ re_match_context_t *mctx;
+ re_dfastate_t *next_state;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int cur_idx = re_string_cur_idx (&mctx->input);
+
+ if (cur_idx > mctx->state_log_top)
+ {
+ mctx->state_log[cur_idx] = next_state;
+ mctx->state_log_top = cur_idx;
+ }
+ else if (mctx->state_log[cur_idx] == 0)
+ {
+ mctx->state_log[cur_idx] = next_state;
+ }
+ else
+ {
+ re_dfastate_t *pstate;
+ unsigned int context;
+ re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
+ /* If (state_log[cur_idx] != 0), it implies that cur_idx is
+ the destination of a multibyte char/collating element/
+ back reference. Then the next state is the union set of
+ these destinations and the results of the transition table. */
+ pstate = mctx->state_log[cur_idx];
+ log_nodes = pstate->entrance_nodes;
+ if (next_state != NULL)
+ {
+ table_nodes = next_state->entrance_nodes;
+ *err = re_node_set_init_union (&next_nodes, table_nodes,
+ log_nodes);
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+ }
+ else
+ next_nodes = *log_nodes;
+ /* Note: We already add the nodes of the initial state,
+ then we don't need to add them here. */
+
+ context = re_string_context_at (&mctx->input,
+ re_string_cur_idx (&mctx->input) - 1,
+ mctx->eflags);
+ next_state = mctx->state_log[cur_idx]
+ = re_acquire_state_context (err, dfa, &next_nodes, context);
+ /* We don't need to check errors here, since the return value of
+ this function is next_state and ERR is already set. */
+
+ if (table_nodes != NULL)
+ re_node_set_free (&next_nodes);
+ }
+
+ if (BE (dfa->nbackref, 0) && next_state != NULL)
+ {
+ /* Check OP_OPEN_SUBEXP in the current state in case that we use them
+ later. We must check them here, since the back references in the
+ next state might use them. */
+ *err = check_subexp_matching_top (mctx, &next_state->nodes,
+ cur_idx);
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+
+ /* If the next state has back references. */
+ if (next_state->has_backref)
+ {
+ *err = transit_state_bkref (mctx, &next_state->nodes);
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+ next_state = mctx->state_log[cur_idx];
+ }
+ }
+
+ return next_state;
+}
+
+/* Skip bytes in the input that correspond to part of a
+ multi-byte match, then look in the log for a state
+ from which to restart matching. */
+re_dfastate_t *
+find_recover_state (err, mctx)
+ reg_errcode_t *err;
+ re_match_context_t *mctx;
+{
+ re_dfastate_t *cur_state = NULL;
+ do
+ {
+ int max = mctx->state_log_top;
+ int cur_str_idx = re_string_cur_idx (&mctx->input);
+
+ do
+ {
+ if (++cur_str_idx > max)
+ return NULL;
+ re_string_skip_bytes (&mctx->input, 1);
+ }
+ while (mctx->state_log[cur_str_idx] == NULL);
+
+ cur_state = merge_state_with_log (err, mctx, NULL);
+ }
+ while (err == REG_NOERROR && cur_state == NULL);
+ return cur_state;
+}
+
+/* Helper functions for transit_state. */
+
+/* From the node set CUR_NODES, pick up the nodes whose types are
+ OP_OPEN_SUBEXP and which have corresponding back references in the regular
+ expression. And register them to use them later for evaluating the
+ correspoding back references. */
+
+static reg_errcode_t
+check_subexp_matching_top (mctx, cur_nodes, str_idx)
+ re_match_context_t *mctx;
+ re_node_set *cur_nodes;
+ int str_idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int node_idx;
+ reg_errcode_t err;
+
+ /* TODO: This isn't efficient.
+ Because there might be more than one nodes whose types are
+ OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+ nodes.
+ E.g. RE: (a){2} */
+ for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
+ {
+ int node = cur_nodes->elems[node_idx];
+ if (dfa->nodes[node].type == OP_OPEN_SUBEXP
+ && dfa->nodes[node].opr.idx < (8 * sizeof (dfa->used_bkref_map))
+ && dfa->used_bkref_map & (1 << dfa->nodes[node].opr.idx))
+ {
+ err = match_ctx_add_subtop (mctx, node, str_idx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+ return REG_NOERROR;
+}
+
+#if 0
+/* Return the next state to which the current state STATE will transit by
+ accepting the current input byte. */
+
+static re_dfastate_t *
+transit_state_sb (err, mctx, state)
+ reg_errcode_t *err;
+ re_match_context_t *mctx;
+ re_dfastate_t *state;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ re_node_set next_nodes;
+ re_dfastate_t *next_state;
+ int node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
+ unsigned int context;
+
+ *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
+ if (BE (*err != REG_NOERROR, 0))
+ return NULL;
+ for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
+ {
+ int cur_node = state->nodes.elems[node_cnt];
+ if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
+ {
+ *err = re_node_set_merge (&next_nodes,
+ dfa->eclosures + dfa->nexts[cur_node]);
+ if (BE (*err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return NULL;
+ }
+ }
+ }
+ context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
+ next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
+ /* We don't need to check errors here, since the return value of
+ this function is next_state and ERR is already set. */
+
+ re_node_set_free (&next_nodes);
+ re_string_skip_bytes (&mctx->input, 1);
+ return next_state;
+}
+#endif
+
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t
+transit_state_mb (mctx, pstate)
+ re_match_context_t *mctx;
+ re_dfastate_t *pstate;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int i;
+
+ for (i = 0; i < pstate->nodes.nelem; ++i)
+ {
+ re_node_set dest_nodes, *new_nodes;
+ int cur_node_idx = pstate->nodes.elems[i];
+ int naccepted, dest_idx;
+ unsigned int context;
+ re_dfastate_t *dest_state;
+
+ if (!dfa->nodes[cur_node_idx].accept_mb)
+ continue;
+
+ if (dfa->nodes[cur_node_idx].constraint)
+ {
+ context = re_string_context_at (&mctx->input,
+ re_string_cur_idx (&mctx->input),
+ mctx->eflags);
+ if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
+ context))
+ continue;
+ }
+
+ /* How many bytes the node can accept? */
+ naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
+ re_string_cur_idx (&mctx->input));
+ if (naccepted == 0)
+ continue;
+
+ /* The node can accepts `naccepted' bytes. */
+ dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
+ mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
+ : mctx->max_mb_elem_len);
+ err = clean_state_log_if_needed (mctx, dest_idx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+#ifdef DEBUG
+ assert (dfa->nexts[cur_node_idx] != -1);
+#endif
+ new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
+
+ dest_state = mctx->state_log[dest_idx];
+ if (dest_state == NULL)
+ dest_nodes = *new_nodes;
+ else
+ {
+ err = re_node_set_init_union (&dest_nodes,
+ dest_state->entrance_nodes, new_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ context = re_string_context_at (&mctx->input, dest_idx - 1, mctx->eflags);
+ mctx->state_log[dest_idx]
+ = re_acquire_state_context (&err, dfa, &dest_nodes, context);
+ if (dest_state != NULL)
+ re_node_set_free (&dest_nodes);
+ if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+ return err;
+ }
+ return REG_NOERROR;
+}
+#endif /* RE_ENABLE_I18N */
+
+static reg_errcode_t
+transit_state_bkref (mctx, nodes)
+ re_match_context_t *mctx;
+ const re_node_set *nodes;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int i;
+ int cur_str_idx = re_string_cur_idx (&mctx->input);
+
+ for (i = 0; i < nodes->nelem; ++i)
+ {
+ int dest_str_idx, prev_nelem, bkc_idx;
+ int node_idx = nodes->elems[i];
+ unsigned int context;
+ const re_token_t *node = dfa->nodes + node_idx;
+ re_node_set *new_dest_nodes;
+
+ /* Check whether `node' is a backreference or not. */
+ if (node->type != OP_BACK_REF)
+ continue;
+
+ if (node->constraint)
+ {
+ context = re_string_context_at (&mctx->input, cur_str_idx,
+ mctx->eflags);
+ if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+ continue;
+ }
+
+ /* `node' is a backreference.
+ Check the substring which the substring matched. */
+ bkc_idx = mctx->nbkref_ents;
+ err = get_subexp (mctx, node_idx, cur_str_idx);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+
+ /* And add the epsilon closures (which is `new_dest_nodes') of
+ the backreference to appropriate state_log. */
+#ifdef DEBUG
+ assert (dfa->nexts[node_idx] != -1);
+#endif
+ for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
+ {
+ int subexp_len;
+ re_dfastate_t *dest_state;
+ struct re_backref_cache_entry *bkref_ent;
+ bkref_ent = mctx->bkref_ents + bkc_idx;
+ if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
+ continue;
+ subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
+ new_dest_nodes = (subexp_len == 0
+ ? dfa->eclosures + dfa->edests[node_idx].elems[0]
+ : dfa->eclosures + dfa->nexts[node_idx]);
+ dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
+ - bkref_ent->subexp_from);
+ context = re_string_context_at (&mctx->input, dest_str_idx - 1,
+ mctx->eflags);
+ dest_state = mctx->state_log[dest_str_idx];
+ prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
+ : mctx->state_log[cur_str_idx]->nodes.nelem);
+ /* Add `new_dest_node' to state_log. */
+ if (dest_state == NULL)
+ {
+ mctx->state_log[dest_str_idx]
+ = re_acquire_state_context (&err, dfa, new_dest_nodes,
+ context);
+ if (BE (mctx->state_log[dest_str_idx] == NULL
+ && err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ else
+ {
+ re_node_set dest_nodes;
+ err = re_node_set_init_union (&dest_nodes,
+ dest_state->entrance_nodes,
+ new_dest_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&dest_nodes);
+ goto free_return;
+ }
+ mctx->state_log[dest_str_idx]
+ = re_acquire_state_context (&err, dfa, &dest_nodes, context);
+ re_node_set_free (&dest_nodes);
+ if (BE (mctx->state_log[dest_str_idx] == NULL
+ && err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ /* We need to check recursively if the backreference can epsilon
+ transit. */
+ if (subexp_len == 0
+ && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
+ {
+ err = check_subexp_matching_top (mctx, new_dest_nodes,
+ cur_str_idx);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ err = transit_state_bkref (mctx, new_dest_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ }
+ }
+ err = REG_NOERROR;
+ free_return:
+ return err;
+}
+
+/* Enumerate all the candidates which the backreference BKREF_NODE can match
+ at BKREF_STR_IDX, and register them by match_ctx_add_entry().
+ Note that we might collect inappropriate candidates here.
+ However, the cost of checking them strictly here is too high, then we
+ delay these checking for prune_impossible_nodes(). */
+
+static reg_errcode_t
+get_subexp (mctx, bkref_node, bkref_str_idx)
+ re_match_context_t *mctx;
+ int bkref_node, bkref_str_idx;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int subexp_num, sub_top_idx;
+ const char *buf = (const char *) re_string_get_buffer (&mctx->input);
+ /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */
+ int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
+ if (cache_idx != -1)
+ {
+ const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx;
+ do
+ if (entry->node == bkref_node)
+ return REG_NOERROR; /* We already checked it. */
+ while (entry++->more);
+ }
+
+ subexp_num = dfa->nodes[bkref_node].opr.idx;
+
+ /* For each sub expression */
+ for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
+ {
+ reg_errcode_t err;
+ re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
+ re_sub_match_last_t *sub_last;
+ int sub_last_idx, sl_str, bkref_str_off;
+
+ if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
+ continue; /* It isn't related. */
+
+ sl_str = sub_top->str_idx;
+ bkref_str_off = bkref_str_idx;
+ /* At first, check the last node of sub expressions we already
+ evaluated. */
+ for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
+ {
+ int sl_str_diff;
+ sub_last = sub_top->lasts[sub_last_idx];
+ sl_str_diff = sub_last->str_idx - sl_str;
+ /* The matched string by the sub expression match with the substring
+ at the back reference? */
+ if (sl_str_diff > 0)
+ {
+ if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+ {
+ /* Not enough chars for a successful match. */
+ if (bkref_str_off + sl_str_diff > mctx->input.len)
+ break;
+
+ err = clean_state_log_if_needed (mctx,
+ bkref_str_off
+ + sl_str_diff);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ buf = (const char *) re_string_get_buffer (&mctx->input);
+ }
+ if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+ break; /* We don't need to search this sub expression any more. */
+ }
+ bkref_str_off += sl_str_diff;
+ sl_str += sl_str_diff;
+ err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+ bkref_str_idx);
+
+ /* Reload buf, since the preceding call might have reallocated
+ the buffer. */
+ buf = (const char *) re_string_get_buffer (&mctx->input);
+
+ if (err == REG_NOMATCH)
+ continue;
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+
+ if (sub_last_idx < sub_top->nlasts)
+ continue;
+ if (sub_last_idx > 0)
+ ++sl_str;
+ /* Then, search for the other last nodes of the sub expression. */
+ for (; sl_str <= bkref_str_idx; ++sl_str)
+ {
+ int cls_node, sl_str_off;
+ const re_node_set *nodes;
+ sl_str_off = sl_str - sub_top->str_idx;
+ /* The matched string by the sub expression match with the substring
+ at the back reference? */
+ if (sl_str_off > 0)
+ {
+ if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+ {
+ /* If we are at the end of the input, we cannot match. */
+ if (bkref_str_off >= mctx->input.len)
+ break;
+
+ err = extend_buffers (mctx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ buf = (const char *) re_string_get_buffer (&mctx->input);
+ }
+ if (buf [bkref_str_off++] != buf[sl_str - 1])
+ break; /* We don't need to search this sub expression
+ any more. */
+ }
+ if (mctx->state_log[sl_str] == NULL)
+ continue;
+ /* Does this state have a ')' of the sub expression? */
+ nodes = &mctx->state_log[sl_str]->nodes;
+ cls_node = find_subexp_node (dfa, nodes, subexp_num, OP_CLOSE_SUBEXP);
+ if (cls_node == -1)
+ continue; /* No. */
+ if (sub_top->path == NULL)
+ {
+ sub_top->path = calloc (sizeof (state_array_t),
+ sl_str - sub_top->str_idx + 1);
+ if (sub_top->path == NULL)
+ return REG_ESPACE;
+ }
+ /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
+ in the current context? */
+ err = check_arrival (mctx, sub_top->path, sub_top->node,
+ sub_top->str_idx, cls_node, sl_str, OP_CLOSE_SUBEXP);
+ if (err == REG_NOMATCH)
+ continue;
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
+ if (BE (sub_last == NULL, 0))
+ return REG_ESPACE;
+ err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+ bkref_str_idx);
+ if (err == REG_NOMATCH)
+ continue;
+ }
+ }
+ return REG_NOERROR;
+}
+
+/* Helper functions for get_subexp(). */
+
+/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
+ If it can arrive, register the sub expression expressed with SUB_TOP
+ and SUB_LAST. */
+
+static reg_errcode_t
+get_subexp_sub (mctx, sub_top, sub_last, bkref_node, bkref_str)
+ re_match_context_t *mctx;
+ const re_sub_match_top_t *sub_top;
+ re_sub_match_last_t *sub_last;
+ int bkref_node, bkref_str;
+{
+ reg_errcode_t err;
+ int to_idx;
+ /* Can the subexpression arrive the back reference? */
+ err = check_arrival (mctx, &sub_last->path, sub_last->node,
+ sub_last->str_idx, bkref_node, bkref_str, OP_OPEN_SUBEXP);
+ if (err != REG_NOERROR)
+ return err;
+ err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
+ sub_last->str_idx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
+ return clean_state_log_if_needed (mctx, to_idx);
+}
+
+/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
+ Search '(' if FL_OPEN, or search ')' otherwise.
+ TODO: This function isn't efficient...
+ Because there might be more than one nodes whose types are
+ OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+ nodes.
+ E.g. RE: (a){2} */
+
+static int
+find_subexp_node (dfa, nodes, subexp_idx, type)
+ const re_dfa_t *dfa;
+ const re_node_set *nodes;
+ int subexp_idx, type;
+{
+ int cls_idx;
+ for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
+ {
+ int cls_node = nodes->elems[cls_idx];
+ const re_token_t *node = dfa->nodes + cls_node;
+ if (node->type == type
+ && node->opr.idx == subexp_idx)
+ return cls_node;
+ }
+ return -1;
+}
+
+/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+ LAST_NODE at LAST_STR. We record the path onto PATH since it will be
+ heavily reused.
+ Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
+
+static reg_errcode_t
+check_arrival (mctx, path, top_node, top_str, last_node, last_str,
+ type)
+ re_match_context_t *mctx;
+ state_array_t *path;
+ int top_node, top_str, last_node, last_str, type;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int subexp_num, backup_cur_idx, str_idx, null_cnt;
+ re_dfastate_t *cur_state = NULL;
+ re_node_set *cur_nodes, next_nodes;
+ re_dfastate_t **backup_state_log;
+ unsigned int context;
+
+ subexp_num = dfa->nodes[top_node].opr.idx;
+ /* Extend the buffer if we need. */
+ if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
+ {
+ re_dfastate_t **new_array;
+ int old_alloc = path->alloc;
+ path->alloc += last_str + mctx->max_mb_elem_len + 1;
+ new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);
+ if (new_array == NULL)
+ {
+ path->alloc = old_alloc;
+ return REG_ESPACE;
+ }
+ path->array = new_array;
+ memset (new_array + old_alloc, '\0',
+ sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
+ }
+
+ str_idx = path->next_idx == 0 ? top_str : path->next_idx;
+
+ /* Temporary modify MCTX. */
+ backup_state_log = mctx->state_log;
+ backup_cur_idx = mctx->input.cur_idx;
+ mctx->state_log = path->array;
+ mctx->input.cur_idx = str_idx;
+
+ /* Setup initial node set. */
+ context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+ if (str_idx == top_str)
+ {
+ err = re_node_set_init_1 (&next_nodes, top_node);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ }
+ else
+ {
+ cur_state = mctx->state_log[str_idx];
+ if (cur_state && cur_state->has_backref)
+ {
+ err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
+ if (BE ( err != REG_NOERROR, 0))
+ return err;
+ }
+ else
+ re_node_set_init_empty (&next_nodes);
+ }
+ if (str_idx == top_str || (cur_state && cur_state->has_backref))
+ {
+ if (next_nodes.nelem)
+ {
+ err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+ subexp_num, type);
+ if (BE ( err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ }
+ cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+ if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ mctx->state_log[str_idx] = cur_state;
+ }
+
+ for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
+ {
+ re_node_set_empty (&next_nodes);
+ if (mctx->state_log[str_idx + 1])
+ {
+ err = re_node_set_merge (&next_nodes,
+ &mctx->state_log[str_idx + 1]->nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ }
+ if (cur_state)
+ {
+ err = check_arrival_add_next_nodes (mctx, str_idx,
+ &cur_state->non_eps_nodes, &next_nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ }
+ ++str_idx;
+ if (next_nodes.nelem)
+ {
+ err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+ subexp_num, type);
+ if (BE ( err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ }
+ context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+ cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+ if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&next_nodes);
+ return err;
+ }
+ mctx->state_log[str_idx] = cur_state;
+ null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
+ }
+ re_node_set_free (&next_nodes);
+ cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
+ : &mctx->state_log[last_str]->nodes);
+ path->next_idx = str_idx;
+
+ /* Fix MCTX. */
+ mctx->state_log = backup_state_log;
+ mctx->input.cur_idx = backup_cur_idx;
+
+ /* Then check the current node set has the node LAST_NODE. */
+ if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
+ return REG_NOERROR;
+
+ return REG_NOMATCH;
+}
+
+/* Helper functions for check_arrival. */
+
+/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
+ to NEXT_NODES.
+ TODO: This function is similar to the functions transit_state*(),
+ however this function has many additional works.
+ Can't we unify them? */
+
+static reg_errcode_t
+check_arrival_add_next_nodes (mctx, str_idx, cur_nodes, next_nodes)
+ re_match_context_t *mctx;
+ int str_idx;
+ re_node_set *cur_nodes, *next_nodes;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ int result;
+ int cur_idx;
+ re_node_set union_set;
+ re_node_set_init_empty (&union_set);
+ for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
+ {
+ int naccepted = 0;
+ int cur_node = cur_nodes->elems[cur_idx];
+#ifdef DEBUG
+ re_token_type_t type = dfa->nodes[cur_node].type;
+ assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+ /* If the node may accept `multi byte'. */
+ if (dfa->nodes[cur_node].accept_mb)
+ {
+ reg_errcode_t err;
+
+ naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
+ str_idx);
+ if (naccepted > 1)
+ {
+ re_dfastate_t *dest_state;
+ int next_node = dfa->nexts[cur_node];
+ int next_idx = str_idx + naccepted;
+ dest_state = mctx->state_log[next_idx];
+ re_node_set_empty (&union_set);
+ if (dest_state)
+ {
+ err = re_node_set_merge (&union_set, &dest_state->nodes);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&union_set);
+ return err;
+ }
+ }
+ result = re_node_set_insert (&union_set, next_node);
+ if (BE (result < 0, 0))
+ {
+ re_node_set_free (&union_set);
+ return REG_ESPACE;
+ }
+ mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
+ &union_set);
+ if (BE (mctx->state_log[next_idx] == NULL
+ && err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&union_set);
+ return err;
+ }
+ }
+ }
+#endif /* RE_ENABLE_I18N */
+ if (naccepted
+ || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
+ {
+ result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
+ if (BE (result < 0, 0))
+ {
+ re_node_set_free (&union_set);
+ return REG_ESPACE;
+ }
+ }
+ }
+ re_node_set_free (&union_set);
+ return REG_NOERROR;
+}
+
+/* For all the nodes in CUR_NODES, add the epsilon closures of them to
+ CUR_NODES, however exclude the nodes which are:
+ - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
+ - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
+*/
+
+static reg_errcode_t
+check_arrival_expand_ecl (dfa, cur_nodes, ex_subexp, type)
+ re_dfa_t *dfa;
+ re_node_set *cur_nodes;
+ int ex_subexp, type;
+{
+ reg_errcode_t err;
+ int idx, outside_node;
+ re_node_set new_nodes;
+#ifdef DEBUG
+ assert (cur_nodes->nelem);
+#endif
+ err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ /* Create a new node set NEW_NODES with the nodes which are epsilon
+ closures of the node in CUR_NODES. */
+
+ for (idx = 0; idx < cur_nodes->nelem; ++idx)
+ {
+ int cur_node = cur_nodes->elems[idx];
+ re_node_set *eclosure = dfa->eclosures + cur_node;
+ outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
+ if (outside_node == -1)
+ {
+ /* There are no problematic nodes, just merge them. */
+ err = re_node_set_merge (&new_nodes, eclosure);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&new_nodes);
+ return err;
+ }
+ }
+ else
+ {
+ /* There are problematic nodes, re-calculate incrementally. */
+ err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
+ ex_subexp, type);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_node_set_free (&new_nodes);
+ return err;
+ }
+ }
+ }
+ re_node_set_free (cur_nodes);
+ *cur_nodes = new_nodes;
+ return REG_NOERROR;
+}
+
+/* Helper function for check_arrival_expand_ecl.
+ Check incrementally the epsilon closure of TARGET, and if it isn't
+ problematic append it to DST_NODES. */
+
+static reg_errcode_t
+check_arrival_expand_ecl_sub (dfa, dst_nodes, target, ex_subexp, type)
+ re_dfa_t *dfa;
+ int target, ex_subexp, type;
+ re_node_set *dst_nodes;
+{
+ int cur_node;
+ for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
+ {
+ int err;
+
+ if (dfa->nodes[cur_node].type == type
+ && dfa->nodes[cur_node].opr.idx == ex_subexp)
+ {
+ if (type == OP_CLOSE_SUBEXP)
+ {
+ err = re_node_set_insert (dst_nodes, cur_node);
+ if (BE (err == -1, 0))
+ return REG_ESPACE;
+ }
+ break;
+ }
+ err = re_node_set_insert (dst_nodes, cur_node);
+ if (BE (err == -1, 0))
+ return REG_ESPACE;
+ if (dfa->edests[cur_node].nelem == 0)
+ break;
+ if (dfa->edests[cur_node].nelem == 2)
+ {
+ err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
+ dfa->edests[cur_node].elems[1],
+ ex_subexp, type);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ cur_node = dfa->edests[cur_node].elems[0];
+ }
+ return REG_NOERROR;
+}
+
+
+/* For all the back references in the current state, calculate the
+ destination of the back references by the appropriate entry
+ in MCTX->BKREF_ENTS. */
+
+static reg_errcode_t
+expand_bkref_cache (mctx, cur_nodes, cur_str, subexp_num,
+ type)
+ re_match_context_t *mctx;
+ int cur_str, subexp_num, type;
+ re_node_set *cur_nodes;
+{
+ re_dfa_t *const dfa = mctx->dfa;
+ reg_errcode_t err;
+ int cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
+ struct re_backref_cache_entry *ent;
+
+ if (cache_idx_start == -1)
+ return REG_NOERROR;
+
+ restart:
+ ent = mctx->bkref_ents + cache_idx_start;
+ do
+ {
+ int to_idx, next_node;
+
+ /* Is this entry ENT is appropriate? */
+ if (!re_node_set_contains (cur_nodes, ent->node))
+ continue; /* No. */
+
+ to_idx = cur_str + ent->subexp_to - ent->subexp_from;
+ /* Calculate the destination of the back reference, and append it
+ to MCTX->STATE_LOG. */
+ if (to_idx == cur_str)
+ {
+ /* The backreference did epsilon transit, we must re-check all the
+ node in the current state. */
+ re_node_set new_dests;
+ reg_errcode_t err2, err3;
+ next_node = dfa->edests[ent->node].elems[0];
+ if (re_node_set_contains (cur_nodes, next_node))
+ continue;
+ err = re_node_set_init_1 (&new_dests, next_node);
+ err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
+ err3 = re_node_set_merge (cur_nodes, &new_dests);
+ re_node_set_free (&new_dests);
+ if (BE (err != REG_NOERROR || err2 != REG_NOERROR
+ || err3 != REG_NOERROR, 0))
+ {
+ err = (err != REG_NOERROR ? err
+ : (err2 != REG_NOERROR ? err2 : err3));
+ return err;
+ }
+ /* TODO: It is still inefficient... */
+ goto restart;
+ }
+ else
+ {
+ re_node_set union_set;
+ next_node = dfa->nexts[ent->node];
+ if (mctx->state_log[to_idx])
+ {
+ int ret;
+ if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
+ next_node))
+ continue;
+ err = re_node_set_init_copy (&union_set,
+ &mctx->state_log[to_idx]->nodes);
+ ret = re_node_set_insert (&union_set, next_node);
+ if (BE (err != REG_NOERROR || ret < 0, 0))
+ {
+ re_node_set_free (&union_set);
+ err = err != REG_NOERROR ? err : REG_ESPACE;
+ return err;
+ }
+ }
+ else
+ {
+ err = re_node_set_init_1 (&union_set, next_node);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ }
+ mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
+ re_node_set_free (&union_set);
+ if (BE (mctx->state_log[to_idx] == NULL
+ && err != REG_NOERROR, 0))
+ return err;
+ }
+ }
+ while (ent++->more);
+ return REG_NOERROR;
+}
+
+/* Build transition table for the state.
+ Return 1 if succeeded, otherwise return NULL. */
+
+static int
+build_trtable (dfa, state)
+ re_dfa_t *dfa;
+ re_dfastate_t *state;
+{
+ reg_errcode_t err;
+ int i, j, ch, need_word_trtable = 0;
+ unsigned int elem, mask;
+ int dests_node_malloced = 0, dest_states_malloced = 0;
+ int ndests; /* Number of the destination states from `state'. */
+ re_dfastate_t **trtable;
+ re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
+ re_node_set follows, *dests_node;
+ bitset *dests_ch;
+ bitset acceptable;
+
+ /* We build DFA states which corresponds to the destination nodes
+ from `state'. `dests_node[i]' represents the nodes which i-th
+ destination state contains, and `dests_ch[i]' represents the
+ characters which i-th destination state accepts. */
+#ifdef _LIBC
+ if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))
+ dests_node = (re_node_set *)
+ alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
+ else
+#endif
+ {
+ dests_node = (re_node_set *)
+ malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
+ if (BE (dests_node == NULL, 0))
+ return 0;
+ dests_node_malloced = 1;
+ }
+ dests_ch = (bitset *) (dests_node + SBC_MAX);
+
+ /* Initialize transiton table. */
+ state->word_trtable = state->trtable = NULL;
+
+ /* At first, group all nodes belonging to `state' into several
+ destinations. */
+ ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
+ if (BE (ndests <= 0, 0))
+ {
+ if (dests_node_malloced)
+ free (dests_node);
+ /* Return 0 in case of an error, 1 otherwise. */
+ if (ndests == 0)
+ {
+ state->trtable = (re_dfastate_t **)
+ calloc (sizeof (re_dfastate_t *), SBC_MAX);
+ return 1;
+ }
+ return 0;
+ }
+
+ err = re_node_set_alloc (&follows, ndests + 1);
+ if (BE (err != REG_NOERROR, 0))
+ goto out_free;
+
+#ifdef _LIBC
+ if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
+ + ndests * 3 * sizeof (re_dfastate_t *)))
+ dest_states = (re_dfastate_t **)
+ alloca (ndests * 3 * sizeof (re_dfastate_t *));
+ else
+#endif
+ {
+ dest_states = (re_dfastate_t **)
+ malloc (ndests * 3 * sizeof (re_dfastate_t *));
+ if (BE (dest_states == NULL, 0))
+ {
+out_free:
+ if (dest_states_malloced)
+ free (dest_states);
+ re_node_set_free (&follows);
+ for (i = 0; i < ndests; ++i)
+ re_node_set_free (dests_node + i);
+ if (dests_node_malloced)
+ free (dests_node);
+ return 0;
+ }
+ dest_states_malloced = 1;
+ }
+ dest_states_word = dest_states + ndests;
+ dest_states_nl = dest_states_word + ndests;
+ bitset_empty (acceptable);
+
+ /* Then build the states for all destinations. */
+ for (i = 0; i < ndests; ++i)
+ {
+ int next_node;
+ re_node_set_empty (&follows);
+ /* Merge the follows of this destination states. */
+ for (j = 0; j < dests_node[i].nelem; ++j)
+ {
+ next_node = dfa->nexts[dests_node[i].elems[j]];
+ if (next_node != -1)
+ {
+ err = re_node_set_merge (&follows, dfa->eclosures + next_node);
+ if (BE (err != REG_NOERROR, 0))
+ goto out_free;
+ }
+ }
+ dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
+ if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
+ goto out_free;
+ /* If the new state has context constraint,
+ build appropriate states for these contexts. */
+ if (dest_states[i]->has_constraint)
+ {
+ dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
+ CONTEXT_WORD);
+ if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+ goto out_free;
+
+ if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
+ need_word_trtable = 1;
+
+ dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+ CONTEXT_NEWLINE);
+ if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
+ goto out_free;
+ }
+ else
+ {
+ dest_states_word[i] = dest_states[i];
+ dest_states_nl[i] = dest_states[i];
+ }
+ bitset_merge (acceptable, dests_ch[i]);
+ }
+
+ if (!BE (need_word_trtable, 0))
+ {
+ /* We don't care about whether the following character is a word
+ character, or we are in a single-byte character set so we can
+ discern by looking at the character code: allocate a
+ 256-entry transition table. */
+ trtable = state->trtable =
+ (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+ if (BE (trtable == NULL, 0))
+ goto out_free;
+
+ /* For all characters ch...: */
+ for (i = 0; i < BITSET_UINTS; ++i)
+ for (ch = i * UINT_BITS, elem = acceptable[i], mask = 1;
+ elem;
+ mask <<= 1, elem >>= 1, ++ch)
+ if (BE (elem & 1, 0))
+ {
+ /* There must be exactly one destination which accepts
+ character ch. See group_nodes_into_DFAstates. */
+ for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+ ;
+
+ /* j-th destination accepts the word character ch. */
+ if (dfa->word_char[i] & mask)
+ trtable[ch] = dest_states_word[j];
+ else
+ trtable[ch] = dest_states[j];
+ }
+ }
+ else
+ {
+ /* We care about whether the following character is a word
+ character, and we are in a multi-byte character set: discern
+ by looking at the character code: build two 256-entry
+ transition tables, one starting at trtable[0] and one
+ starting at trtable[SBC_MAX]. */
+ trtable = state->word_trtable =
+ (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+ if (BE (trtable == NULL, 0))
+ goto out_free;
+
+ /* For all characters ch...: */
+ for (i = 0; i < BITSET_UINTS; ++i)
+ for (ch = i * UINT_BITS, elem = acceptable[i], mask = 1;
+ elem;
+ mask <<= 1, elem >>= 1, ++ch)
+ if (BE (elem & 1, 0))
+ {
+ /* There must be exactly one destination which accepts
+ character ch. See group_nodes_into_DFAstates. */
+ for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+ ;
+
+ /* j-th destination accepts the word character ch. */
+ trtable[ch] = dest_states[j];
+ trtable[ch + SBC_MAX] = dest_states_word[j];
+ }
+ }
+
+ /* new line */
+ if (bitset_contain (acceptable, NEWLINE_CHAR))
+ {
+ /* The current state accepts newline character. */
+ for (j = 0; j < ndests; ++j)
+ if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
+ {
+ /* k-th destination accepts newline character. */
+ trtable[NEWLINE_CHAR] = dest_states_nl[j];
+ if (need_word_trtable)
+ trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
+ /* There must be only one destination which accepts
+ newline. See group_nodes_into_DFAstates. */
+ break;
+ }
+ }
+
+ if (dest_states_malloced)
+ free (dest_states);
+
+ re_node_set_free (&follows);
+ for (i = 0; i < ndests; ++i)
+ re_node_set_free (dests_node + i);
+
+ if (dests_node_malloced)
+ free (dests_node);
+
+ return 1;
+}
+
+/* Group all nodes belonging to STATE into several destinations.
+ Then for all destinations, set the nodes belonging to the destination
+ to DESTS_NODE[i] and set the characters accepted by the destination
+ to DEST_CH[i]. This function return the number of destinations. */
+
+static int
+group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch)
+ re_dfa_t *dfa;
+ const re_dfastate_t *state;
+ re_node_set *dests_node;
+ bitset *dests_ch;
+{
+ reg_errcode_t err;
+ int result;
+ int i, j, k;
+ int ndests; /* Number of the destinations from `state'. */
+ bitset accepts; /* Characters a node can accept. */
+ const re_node_set *cur_nodes = &state->nodes;
+ bitset_empty (accepts);
+ ndests = 0;
+
+ /* For all the nodes belonging to `state', */
+ for (i = 0; i < cur_nodes->nelem; ++i)
+ {
+ re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
+ re_token_type_t type = node->type;
+ unsigned int constraint = node->constraint;
+
+ /* Enumerate all single byte character this node can accept. */
+ if (type == CHARACTER)
+ bitset_set (accepts, node->opr.c);
+ else if (type == SIMPLE_BRACKET)
+ {
+ bitset_merge (accepts, node->opr.sbcset);
+ }
+ else if (type == OP_PERIOD)
+ {
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ bitset_merge (accepts, dfa->sb_char);
+ else
+#endif
+ bitset_set_all (accepts);
+ if (!(dfa->syntax & RE_DOT_NEWLINE))
+ bitset_clear (accepts, '\n');
+ if (dfa->syntax & RE_DOT_NOT_NULL)
+ bitset_clear (accepts, '\0');
+ }
+#ifdef RE_ENABLE_I18N
+ else if (type == OP_UTF8_PERIOD)
+ {
+ memset (accepts, 255, sizeof (unsigned int) * BITSET_UINTS / 2);
+ if (!(dfa->syntax & RE_DOT_NEWLINE))
+ bitset_clear (accepts, '\n');
+ if (dfa->syntax & RE_DOT_NOT_NULL)
+ bitset_clear (accepts, '\0');
+ }
+#endif
+ else
+ continue;
+
+ /* Check the `accepts' and sift the characters which are not
+ match it the context. */
+ if (constraint)
+ {
+ if (constraint & NEXT_NEWLINE_CONSTRAINT)
+ {
+ int accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
+ bitset_empty (accepts);
+ if (accepts_newline)
+ bitset_set (accepts, NEWLINE_CHAR);
+ else
+ continue;
+ }
+ if (constraint & NEXT_ENDBUF_CONSTRAINT)
+ {
+ bitset_empty (accepts);
+ continue;
+ }
+
+ if (constraint & NEXT_WORD_CONSTRAINT)
+ {
+ unsigned int any_set = 0;
+ if (type == CHARACTER && !node->word_char)
+ {
+ bitset_empty (accepts);
+ continue;
+ }
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ for (j = 0; j < BITSET_UINTS; ++j)
+ any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+ else
+#endif
+ for (j = 0; j < BITSET_UINTS; ++j)
+ any_set |= (accepts[j] &= dfa->word_char[j]);
+ if (!any_set)
+ continue;
+ }
+ if (constraint & NEXT_NOTWORD_CONSTRAINT)
+ {
+ unsigned int any_set = 0;
+ if (type == CHARACTER && node->word_char)
+ {
+ bitset_empty (accepts);
+ continue;
+ }
+#ifdef RE_ENABLE_I18N
+ if (dfa->mb_cur_max > 1)
+ for (j = 0; j < BITSET_UINTS; ++j)
+ any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+ else
+#endif
+ for (j = 0; j < BITSET_UINTS; ++j)
+ any_set |= (accepts[j] &= ~dfa->word_char[j]);
+ if (!any_set)
+ continue;
+ }
+ }
+
+ /* Then divide `accepts' into DFA states, or create a new
+ state. Above, we make sure that accepts is not empty. */
+ for (j = 0; j < ndests; ++j)
+ {
+ bitset intersec; /* Intersection sets, see below. */
+ bitset remains;
+ /* Flags, see below. */
+ int has_intersec, not_subset, not_consumed;
+
+ /* Optimization, skip if this state doesn't accept the character. */
+ if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
+ continue;
+
+ /* Enumerate the intersection set of this state and `accepts'. */
+ has_intersec = 0;
+ for (k = 0; k < BITSET_UINTS; ++k)
+ has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
+ /* And skip if the intersection set is empty. */
+ if (!has_intersec)
+ continue;
+
+ /* Then check if this state is a subset of `accepts'. */
+ not_subset = not_consumed = 0;
+ for (k = 0; k < BITSET_UINTS; ++k)
+ {
+ not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
+ not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
+ }
+
+ /* If this state isn't a subset of `accepts', create a
+ new group state, which has the `remains'. */
+ if (not_subset)
+ {
+ bitset_copy (dests_ch[ndests], remains);
+ bitset_copy (dests_ch[j], intersec);
+ err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
+ if (BE (err != REG_NOERROR, 0))
+ goto error_return;
+ ++ndests;
+ }
+
+ /* Put the position in the current group. */
+ result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+ if (BE (result < 0, 0))
+ goto error_return;
+
+ /* If all characters are consumed, go to next node. */
+ if (!not_consumed)
+ break;
+ }
+ /* Some characters remain, create a new group. */
+ if (j == ndests)
+ {
+ bitset_copy (dests_ch[ndests], accepts);
+ err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
+ if (BE (err != REG_NOERROR, 0))
+ goto error_return;
+ ++ndests;
+ bitset_empty (accepts);
+ }
+ }
+ return ndests;
+ error_return:
+ for (j = 0; j < ndests; ++j)
+ re_node_set_free (dests_node + j);
+ return -1;
+}
+
+#ifdef RE_ENABLE_I18N
+/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
+ Return the number of the bytes the node accepts.
+ STR_IDX is the current index of the input string.
+
+ This function handles the nodes which can accept one character, or
+ one collating element like '.', '[a-z]', opposite to the other nodes
+ can only accept one byte. */
+
+static int
+check_node_accept_bytes (dfa, node_idx, input, str_idx)
+ re_dfa_t *dfa;
+ int node_idx, str_idx;
+ const re_string_t *input;
+{
+ const re_token_t *node = dfa->nodes + node_idx;
+ int char_len, elem_len;
+ int i;
+
+ if (BE (node->type == OP_UTF8_PERIOD, 0))
+ {
+ unsigned char c = re_string_byte_at (input, str_idx), d;
+ if (BE (c < 0xc2, 1))
+ return 0;
+
+ if (str_idx + 2 > input->len)
+ return 0;
+
+ d = re_string_byte_at (input, str_idx + 1);
+ if (c < 0xe0)
+ return (d < 0x80 || d > 0xbf) ? 0 : 2;
+ else if (c < 0xf0)
+ {
+ char_len = 3;
+ if (c == 0xe0 && d < 0xa0)
+ return 0;
+ }
+ else if (c < 0xf8)
+ {
+ char_len = 4;
+ if (c == 0xf0 && d < 0x90)
+ return 0;
+ }
+ else if (c < 0xfc)
+ {
+ char_len = 5;
+ if (c == 0xf8 && d < 0x88)
+ return 0;
+ }
+ else if (c < 0xfe)
+ {
+ char_len = 6;
+ if (c == 0xfc && d < 0x84)
+ return 0;
+ }
+ else
+ return 0;
+
+ if (str_idx + char_len > input->len)
+ return 0;
+
+ for (i = 1; i < char_len; ++i)
+ {
+ d = re_string_byte_at (input, str_idx + i);
+ if (d < 0x80 || d > 0xbf)
+ return 0;
+ }
+ return char_len;
+ }
+
+ char_len = re_string_char_size_at (input, str_idx);
+ if (node->type == OP_PERIOD)
+ {
+ if (char_len <= 1)
+ return 0;
+ /* FIXME: I don't think this if is needed, as both '\n'
+ and '\0' are char_len == 1. */
+ /* '.' accepts any one character except the following two cases. */
+ if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
+ re_string_byte_at (input, str_idx) == '\n') ||
+ ((dfa->syntax & RE_DOT_NOT_NULL) &&
+ re_string_byte_at (input, str_idx) == '\0'))
+ return 0;
+ return char_len;
+ }
+
+ elem_len = re_string_elem_size_at (input, str_idx);
+ if ((elem_len <= 1 && char_len <= 1) || char_len == 0)
+ return 0;
+
+ if (node->type == COMPLEX_BRACKET)
+ {
+ const re_charset_t *cset = node->opr.mbcset;
+# ifdef _LIBC
+ const unsigned char *pin = ((char *) re_string_get_buffer (input)
+ + str_idx);
+ int j;
+ uint32_t nrules;
+# endif /* _LIBC */
+ int match_len = 0;
+ wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+ ? re_string_wchar_at (input, str_idx) : 0);
+
+ /* match with multibyte character? */
+ for (i = 0; i < cset->nmbchars; ++i)
+ if (wc == cset->mbchars[i])
+ {
+ match_len = char_len;
+ goto check_node_accept_bytes_match;
+ }
+ /* match with character_class? */
+ for (i = 0; i < cset->nchar_classes; ++i)
+ {
+ wctype_t wt = cset->char_classes[i];
+ if (__iswctype (wc, wt))
+ {
+ match_len = char_len;
+ goto check_node_accept_bytes_match;
+ }
+ }
+
+# ifdef _LIBC
+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+ if (nrules != 0)
+ {
+ unsigned int in_collseq = 0;
+ const int32_t *table, *indirect;
+ const unsigned char *weights, *extra;
+ const char *collseqwc;
+ int32_t idx;
+ /* This #include defines a local function! */
+# include <locale/weight.h>
+
+ /* match with collating_symbol? */
+ if (cset->ncoll_syms)
+ extra = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+ for (i = 0; i < cset->ncoll_syms; ++i)
+ {
+ const unsigned char *coll_sym = extra + cset->coll_syms[i];
+ /* Compare the length of input collating element and
+ the length of current collating element. */
+ if (*coll_sym != elem_len)
+ continue;
+ /* Compare each bytes. */
+ for (j = 0; j < *coll_sym; j++)
+ if (pin[j] != coll_sym[1 + j])
+ break;
+ if (j == *coll_sym)
+ {
+ /* Match if every bytes is equal. */
+ match_len = j;
+ goto check_node_accept_bytes_match;
+ }
+ }
+
+ if (cset->nranges)
+ {
+ if (elem_len <= char_len)
+ {
+ collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+ in_collseq = __collseq_table_lookup (collseqwc, wc);
+ }
+ else
+ in_collseq = find_collation_sequence_value (pin, elem_len);
+ }
+ /* match with range expression? */
+ for (i = 0; i < cset->nranges; ++i)
+ if (cset->range_starts[i] <= in_collseq
+ && in_collseq <= cset->range_ends[i])
+ {
+ match_len = elem_len;
+ goto check_node_accept_bytes_match;
+ }
+
+ /* match with equivalence_class? */
+ if (cset->nequiv_classes)
+ {
+ const unsigned char *cp = pin;
+ table = (const int32_t *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+ weights = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
+ extra = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+ indirect = (const int32_t *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
+ idx = findidx (&cp);
+ if (idx > 0)
+ for (i = 0; i < cset->nequiv_classes; ++i)
+ {
+ int32_t equiv_class_idx = cset->equiv_classes[i];
+ size_t weight_len = weights[idx];
+ if (weight_len == weights[equiv_class_idx])
+ {
+ int cnt = 0;
+ while (cnt <= weight_len
+ && (weights[equiv_class_idx + 1 + cnt]
+ == weights[idx + 1 + cnt]))
+ ++cnt;
+ if (cnt > weight_len)
+ {
+ match_len = elem_len;
+ goto check_node_accept_bytes_match;
+ }
+ }
+ }
+ }
+ }
+ else
+# endif /* _LIBC */
+ {
+ /* match with range expression? */
+#if __GNUC__ >= 2
+ wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+#else
+ wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+ cmp_buf[2] = wc;
+#endif
+ for (i = 0; i < cset->nranges; ++i)
+ {
+ cmp_buf[0] = cset->range_starts[i];
+ cmp_buf[4] = cset->range_ends[i];
+ if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+ && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+ {
+ match_len = char_len;
+ goto check_node_accept_bytes_match;
+ }
+ }
+ }
+ check_node_accept_bytes_match:
+ if (!cset->non_match)
+ return match_len;
+ else
+ {
+ if (match_len > 0)
+ return 0;
+ else
+ return (elem_len > char_len) ? elem_len : char_len;
+ }
+ }
+ return 0;
+}
+
+# ifdef _LIBC
+static unsigned int
+find_collation_sequence_value (mbs, mbs_len)
+ const unsigned char *mbs;
+ size_t mbs_len;
+{
+ uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+ if (nrules == 0)
+ {
+ if (mbs_len == 1)
+ {
+ /* No valid character. Match it as a single byte character. */
+ const unsigned char *collseq = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+ return collseq[mbs[0]];
+ }
+ return UINT_MAX;
+ }
+ else
+ {
+ int32_t idx;
+ const unsigned char *extra = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+ int32_t extrasize = (const unsigned char *)
+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
+
+ for (idx = 0; idx < extrasize;)
+ {
+ int mbs_cnt, found = 0;
+ int32_t elem_mbs_len;
+ /* Skip the name of collating element name. */
+ idx = idx + extra[idx] + 1;
+ elem_mbs_len = extra[idx++];
+ if (mbs_len == elem_mbs_len)
+ {
+ for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
+ if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
+ break;
+ if (mbs_cnt == elem_mbs_len)
+ /* Found the entry. */
+ found = 1;
+ }
+ /* Skip the byte sequence of the collating element. */
+ idx += elem_mbs_len;
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
+ /* Skip the collation sequence value. */
+ idx += sizeof (uint32_t);
+ /* Skip the wide char sequence of the collating element. */
+ idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
+ /* If we found the entry, return the sequence value. */
+ if (found)
+ return *(uint32_t *) (extra + idx);
+ /* Skip the collation sequence value. */
+ idx += sizeof (uint32_t);
+ }
+ return UINT_MAX;
+ }
+}
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+
+/* Check whether the node accepts the byte which is IDX-th
+ byte of the INPUT. */
+
+static int
+check_node_accept (mctx, node, idx)
+ const re_match_context_t *mctx;
+ const re_token_t *node;
+ int idx;
+{
+ unsigned char ch;
+ ch = re_string_byte_at (&mctx->input, idx);
+ switch (node->type)
+ {
+ case CHARACTER:
+ if (node->opr.c != ch)
+ return 0;
+ break;
+
+ case SIMPLE_BRACKET:
+ if (!bitset_contain (node->opr.sbcset, ch))
+ return 0;
+ break;
+
+#ifdef RE_ENABLE_I18N
+ case OP_UTF8_PERIOD:
+ if (ch >= 0x80)
+ return 0;
+ /* FALLTHROUGH */
+#endif
+ case OP_PERIOD:
+ if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
+ || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (node->constraint)
+ {
+ /* The node has constraints. Check whether the current context
+ satisfies the constraints. */
+ unsigned int context = re_string_context_at (&mctx->input, idx,
+ mctx->eflags);
+ if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Extend the buffers, if the buffers have run out. */
+
+static reg_errcode_t
+extend_buffers (mctx)
+ re_match_context_t *mctx;
+{
+ reg_errcode_t ret;
+ re_string_t *pstr = &mctx->input;
+
+ /* Double the lengthes of the buffers. */
+ ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+
+ if (mctx->state_log != NULL)
+ {
+ /* And double the length of state_log. */
+ /* XXX We have no indication of the size of this buffer. If this
+ allocation fail we have no indication that the state_log array
+ does not have the right size. */
+ re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
+ pstr->bufs_len + 1);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ mctx->state_log = new_array;
+ }
+
+ /* Then reconstruct the buffers. */
+ if (pstr->icase)
+ {
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ {
+ ret = build_wcs_upper_buffer (pstr);
+ if (BE (ret != REG_NOERROR, 0))
+ return ret;
+ }
+ else
+#endif /* RE_ENABLE_I18N */
+ build_upper_buffer (pstr);
+ }
+ else
+ {
+#ifdef RE_ENABLE_I18N
+ if (pstr->mb_cur_max > 1)
+ build_wcs_buffer (pstr);
+ else
+#endif /* RE_ENABLE_I18N */
+ {
+ if (pstr->trans != NULL)
+ re_string_translate_buffer (pstr);
+ }
+ }
+ return REG_NOERROR;
+}
+
+\f
+/* Functions for matching context. */
+
+/* Initialize MCTX. */
+
+static reg_errcode_t
+match_ctx_init (mctx, eflags, n)
+ re_match_context_t *mctx;
+ int eflags, n;
+{
+ mctx->eflags = eflags;
+ mctx->match_last = -1;
+ if (n > 0)
+ {
+ mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
+ mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
+ if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
+ return REG_ESPACE;
+ }
+ /* Already zero-ed by the caller.
+ else
+ mctx->bkref_ents = NULL;
+ mctx->nbkref_ents = 0;
+ mctx->nsub_tops = 0; */
+ mctx->abkref_ents = n;
+ mctx->max_mb_elem_len = 1;
+ mctx->asub_tops = n;
+ return REG_NOERROR;
+}
+
+/* Clean the entries which depend on the current input in MCTX.
+ This function must be invoked when the matcher changes the start index
+ of the input, or changes the input string. */
+
+static void
+match_ctx_clean (mctx)
+ re_match_context_t *mctx;
+{
+ int st_idx;
+ for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
+ {
+ int sl_idx;
+ re_sub_match_top_t *top = mctx->sub_tops[st_idx];
+ for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
+ {
+ re_sub_match_last_t *last = top->lasts[sl_idx];
+ re_free (last->path.array);
+ re_free (last);
+ }
+ re_free (top->lasts);
+ if (top->path)
+ {
+ re_free (top->path->array);
+ re_free (top->path);
+ }
+ free (top);
+ }
+
+ mctx->nsub_tops = 0;
+ mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX. */
+
+static void
+match_ctx_free (mctx)
+ re_match_context_t *mctx;
+{
+ /* First, free all the memory associated with MCTX->SUB_TOPS. */
+ match_ctx_clean (mctx);
+ re_free (mctx->sub_tops);
+ re_free (mctx->bkref_ents);
+}
+
+/* Add a new backreference entry to MCTX.
+ Note that we assume that caller never call this function with duplicate
+ entry, and call with STR_IDX which isn't smaller than any existing entry.
+*/
+
+static reg_errcode_t
+match_ctx_add_entry (mctx, node, str_idx, from, to)
+ re_match_context_t *mctx;
+ int node, str_idx, from, to;
+{
+ if (mctx->nbkref_ents >= mctx->abkref_ents)
+ {
+ struct re_backref_cache_entry* new_entry;
+ new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+ mctx->abkref_ents * 2);
+ if (BE (new_entry == NULL, 0))
+ {
+ re_free (mctx->bkref_ents);
+ return REG_ESPACE;
+ }
+ mctx->bkref_ents = new_entry;
+ memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
+ sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
+ mctx->abkref_ents *= 2;
+ }
+ if (mctx->nbkref_ents > 0
+ && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+ mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
+ mctx->bkref_ents[mctx->nbkref_ents].node = node;
+ mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
+ mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
+ mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
+
+ /* This is a cache that saves negative results of check_dst_limits_calc_pos.
+ If bit N is clear, means that this entry won't epsilon-transition to
+ an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If
+ it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+ such node.
+
+ A backreference does not epsilon-transition unless it is empty, so set
+ to all zeros if FROM != TO. */
+ mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+ = (from == to ? ~0 : 0);
+
+ mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
+ if (mctx->max_mb_elem_len < to - from)
+ mctx->max_mb_elem_len = to - from;
+ return REG_NOERROR;
+}
+
+/* Search for the first entry which has the same str_idx, or -1 if none is
+ found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */
+
+static int
+search_cur_bkref_entry (mctx, str_idx)
+ re_match_context_t *mctx;
+ int str_idx;
+{
+ int left, right, mid, last;
+ last = right = mctx->nbkref_ents;
+ for (left = 0; left < right;)
+ {
+ mid = (left + right) / 2;
+ if (mctx->bkref_ents[mid].str_idx < str_idx)
+ left = mid + 1;
+ else
+ right = mid;
+ }
+ if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+ return left;
+ else
+ return -1;
+}
+
+/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
+ at STR_IDX. */
+
+static reg_errcode_t
+match_ctx_add_subtop (mctx, node, str_idx)
+ re_match_context_t *mctx;
+ int node, str_idx;
+{
+#ifdef DEBUG
+ assert (mctx->sub_tops != NULL);
+ assert (mctx->asub_tops > 0);
+#endif
+ if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
+ {
+ int new_asub_tops = mctx->asub_tops * 2;
+ re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
+ re_sub_match_top_t *,
+ new_asub_tops);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
+ mctx->sub_tops = new_array;
+ mctx->asub_tops = new_asub_tops;
+ }
+ mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
+ if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
+ return REG_ESPACE;
+ mctx->sub_tops[mctx->nsub_tops]->node = node;
+ mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
+ return REG_NOERROR;
+}
+
+/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+ at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */
+
+static re_sub_match_last_t *
+match_ctx_add_sublast (subtop, node, str_idx)
+ re_sub_match_top_t *subtop;
+ int node, str_idx;
+{
+ re_sub_match_last_t *new_entry;
+ if (BE (subtop->nlasts == subtop->alasts, 0))
+ {
+ int new_alasts = 2 * subtop->alasts + 1;
+ re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
+ re_sub_match_last_t *,
+ new_alasts);
+ if (BE (new_array == NULL, 0))
+ return NULL;
+ subtop->lasts = new_array;
+ subtop->alasts = new_alasts;
+ }
+ new_entry = calloc (1, sizeof (re_sub_match_last_t));
+ if (BE (new_entry != NULL, 1))
+ {
+ subtop->lasts[subtop->nlasts] = new_entry;
+ new_entry->node = node;
+ new_entry->str_idx = str_idx;
+ ++subtop->nlasts;
+ }
+ return new_entry;
+}
+
+static void
+sift_ctx_init (sctx, sifted_sts, limited_sts, last_node, last_str_idx)
+ re_sift_context_t *sctx;
+ re_dfastate_t **sifted_sts, **limited_sts;
+ int last_node, last_str_idx;
+{
+ sctx->sifted_states = sifted_sts;
+ sctx->limited_states = limited_sts;
+ sctx->last_node = last_node;
+ sctx->last_str_idx = last_str_idx;
+ re_node_set_init_empty (&sctx->limits);
+}
--- /dev/null
+/*
+ * Do all necessary includes here, so that we don't have to worry about
+ * overlapping includes in the files in missing.d.
+ */
+#include "config.h"
+#include "awk.h"
+
+
+#ifdef atarist
+/*
+ * this will work with gcc compiler - for other compilers you may
+ * have to replace path separators in this file into backslashes
+ */
+#include "unsupported/atari/stack.c"
+#include "unsupported/atari/tmpnam.c"
+#endif /* atarist */
+
+#ifndef HAVE_SYSTEM
+#ifdef atarist
+#include "unsupported/atari/system.c"
+#else
+#include "missing_d/system.c"
+#endif
+#endif /* HAVE_SYSTEM */
+
+#ifndef HAVE_MEMCMP
+#include "missing_d/memcmp.c"
+#endif /* HAVE_MEMCMP */
+
+#ifndef HAVE_MEMCPY
+#include "missing_d/memcpy.c"
+#endif /* HAVE_MEMCPY */
+
+#ifndef HAVE_MEMSET
+#include "missing_d/memset.c"
+#endif /* HAVE_MEMSET */
+
+#ifndef HAVE_MEMMOVE
+#include "missing_d/memmove.c"
+#endif /* HAVE_MEMMOVE */
+
+#ifndef HAVE_STRNCASECMP
+#include "missing_d/strncasecmp.c"
+#endif /* HAVE_STRCASE */
+
+#ifndef HAVE_STRERROR
+#include "missing_d/strerror.c"
+#endif /* HAVE_STRERROR */
+
+#ifndef HAVE_STRFTIME
+#include "missing_d/strftime.c"
+#endif /* HAVE_STRFTIME */
+
+#ifndef HAVE_STRCHR
+#include "missing_d/strchr.c"
+#endif /* HAVE_STRCHR */
+
+#if !defined(HAVE_STRTOD) || defined(STRTOD_NOT_C89)
+#include "missing_d/strtod.c"
+#endif /* HAVE_STRTOD */
+
+#ifndef HAVE_STRTOUL
+#include "missing_d/strtoul.c"
+#endif /* HAVE_STRTOUL */
+
+#ifndef HAVE_TZSET
+#include "missing_d/tzset.c"
+#endif /* HAVE_TZSET */
+
+#if defined TANDEM
+#include "strdupc"
+#include "getidc"
+#include "strnchkc"
+#endif /* TANDEM */
+
+#ifndef HAVE_MKTIME
+/* mktime.c defines main() if DEBUG is set */
+#undef DEBUG
+#include "missing_d/mktime.c"
+#endif /* HAVE_MKTIME */
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Sun Jul 10 18:31:45 2005 Scott Deifik <scottd@amgen.com>
+
+ * regtest.sh: Changed to use diff instead of cmp for djgpp.
+ This addresses DOS vs. UNIX end-of-line issues.
+
+Thu Jun 9 23:40:14 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (Maketests): Don't use $< in rule, it breaks
+ on some non-GNU versions of make. Sigh.
+
+Wed Apr 27 22:22:05 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (longdbl): new test.
+ * longdbl.awk, longdbl.in, longdbl.ok: new files.
+
+Wed Feb 2 16:44:41 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (exitval2): new test.
+ * exitval2.awk, exitval2.ok: new files.
+
+Mon Jan 31 10:00:52 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gnuops3): new test.
+ * gnuops3.awk, gnuops3.ok: new files.
+
+Wed Jan 19 18:04:40 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (hex): new test.
+ * hex.awk, hex.ok: new files.
+
+Sun Jan 9 11:53:09 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (strftime, igncras2, subamp): Use `GAWKLOCALE',
+ not `GAWK_LOCALE'. Grrr!
+
+Mon Jan 3 12:20:08 2005 William J. Poser <wjposer@ldc.upenn.edu>
+
+ * Makefile.am (wjposer1): new test.
+ * wjposer1.awk, wjposer1.in, wjposer1.ok: new files.
+
+Mon Jan 3 11:55:48 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rsstart1, rsstart2, rsstart3): new tests.
+ * rsstart1.in, rsstart1.awk, rsstart1.ok, rsstart2.awk,
+ rsstart2.ok, rsstart3.ok: new files.
+
+Sun Dec 19 17:31:48 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gensub2): new test.
+ * gensub2.awk, gensub2.ok: new files.
+
+ Thanks to "John H. DuBois III" <spcecdt@armory.com>.
+
+Thu Dec 9 15:22:58 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fsspcoln): new test.
+ * fsspcoln.awk, fsspcoln.in, fsspcoln.ok: new files.
+
+Mon Nov 29 18:41:33 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (iobug1): new test.
+ * iobug1.awk, iobug1.ok: new files.
+
+Tue Sep 28 18:39:53 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * nondec.awk, nondec.ok: Add 00.34 as value to print, it should
+ not be treated as octal.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Wed Jul 14 16:04:46 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rstest6): new test.
+ * rstest6.awk, rstest6.in, rstest6.ok: new files.
+
+Tue Jul 13 10:53:32 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strftlng: Use `$(CMP) ... >/dev/null 2>&1' instead of `-s'
+ for OS/2 and other systems that use `CMP = diff -a'.
+
+Mon Jun 14 18:44:39 2004 Pat Rankin <rankin@pactechdata.com>
+
+ * longwrds.awk: allow caller the means to override SORT command.
+
+Tue Jun 8 14:12:52 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fordel, printfbad1): new tests.
+ * fordel.awk, fordel.ok: new files.
+ * printfbad1.awk, printfbad1.ok: new files.
+
+Mon Apr 19 20:29:52 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (manglprm): new test.
+ * manglprm.awk, manglprm.in, manglprm.ok: new files.
+
+Mon Feb 23 18:39:24 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * inftest.awk: Add loop limit per Nelson H.F. Beebe.
+ * Makefile.am (strftime): Use LC_ALL=C for `date' invocation.
+
+Thu Feb 12 02:08:15 2004 Stepan Kasal <kasal@ucw.cz>
+
+ * Makefile.am (diffout): Use $(srcdir), when we are not building
+ in the source tree.
+
+Wed Feb 11 10:23:39 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (strcat1): new test.
+ * strcat1.awk, strcat1.ok: new files.
+
+Fri Feb 6 12:09:55 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (CLEANFILES): Added.
+
+Thu Feb 5 15:34:14 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (exitval1): new test.
+ * exitval1.awk, exitval1.ok: new files.
+
+Mon Feb 2 10:29:19 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (subamp): new test.
+ * subamp.awk, subamp.in, subamp.ok: new files.
+
+ * subamp, ignrcas2, strftime: Set GAWK_LOCALE, not LC_ALL.
+
+Wed Jan 14 15:28:34 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (backw): new test.
+ * backw.awk, backw.in, backw.ok: new files.
+
+Mon Dec 1 10:29:22 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (concat3): new test.
+ * concat3.awk, concat3.ok: new files.
+
+Sun Nov 2 16:05:21 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (concat2): new test.
+ * concat2.awk, concat2.ok: new files.
+
+Wed Oct 29 13:35:37 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (subsepnm): new test.
+ * subsepnm.awk, subsepnm.ok: new files.
+
+Mon Sep 15 16:05:37 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (ignrcas2): new test.
+ * ignrcas2.awk, ignrcas2.ok: new files.
+
+Tue Sep 9 16:03:34 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (unterm): new test.
+ * unterm.awk, unterm.ok: new files.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Fri Jul 4 11:12:07 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (poundbang2): Removed.
+ (poundbang): Added env var settings.
+
+Thu Jun 26 15:44:33 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (match2, whiny): new tests.
+ * match2.awk, match2.ok: new files.
+ * whiny.awk, whiny.ok: new files.
+
+Thu Jun 26 14:51:40 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Use double quotes for sed invocation to make
+ life easier (eventually) for DOS version of Makefile.
+ * pipeio2.awk, pipio2.ok: Ditto.
+
+Wed Jun 18 12:32:14 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (AWK): Use LC_ALL=$${GAWKLOCALE:-C} and
+ same for LANG when running awk. Provides sane locale for
+ tests with ability to override it if need be.
+ (all tests): Removed explicit setting of LC_ALL and LANG.
+ * Gentests: Ditto.
+
+Wed May 28 08:02:33 CEST 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (uninit4): new test.
+ * uninit4.awk, uninit4.ok: new files.
+
+Wed May 28 06:30:23 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (aryprm4 aryprm5 aryprm6 aryprm7 aryprm8 scalar uninit3):
+ new tests.
+ * aryprm4.awk aryprm4.ok aryprm5.awk aryprm5.ok aryprm6.awk aryprm6.ok:
+ aryprm7.awk aryprm7.ok aryprm8.awk aryprm8.ok scalar.awk scalar.ok:
+ uninit3.awk uninit3.ok: new files.
+
+Tue May 27 14:27:50 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (aryprm1, aryprm2, aryprm3, sortempty): New tests.
+ * aryprm1.awk, aryprm1.ok, aryprm2.awk, aryprm2.ok: New files.
+ * aryprm3.awk, aryprm3.ok, sortempty.awk, sortempty.ok: dtto
+ * prmarscl.ok: The actual error message has changed.
+
+Tue May 27 08:23:51 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * arrayref3.ok, arrayref4.ok, fnaryscl.ok: Error messages reformatted.
+
+Sun Jun 8 17:18:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fmttest, strtonum, nested, gsubtst5, delarpm2): New tests.
+ * fmttest.awk, fmttest.ok: New files. From Nelson Beebe,
+ <beebe@math.utah.edu>.
+ * strtonum.awk, strtonum.ok: New files.
+ * nested.awk, nested.in, nested.ok: New files.
+ * gsubtst5.awk, gsubtst5.in, gsubtst5.ok: New files.
+ * delarpm2.awk, delarpm2.ok: New files. (Also from Nelson Beebe.)
+
+ * switch2.awk: Currently unused test for switch code.
+
+Wed May 14 16:49:53 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Gentests: Add LC_ALL=C LANG=C to generated tests.
+ * Makefile.am: All other manual tests: ditto.
+
+Sun May 11 15:27:55 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (rsnulbig, rsnulbig2): New tests.
+ * rsnulbig.ok, rsnulbig2.ok: New files.
+
+Sun May 11 15:00:20 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (arrayprm2, arrayprm3, arryref2, arryref3, arryref4,
+ arryref5, rstest3, rstest4, rstest5): New tests.
+ * arrayprm2.awk, arrayprm2.ok, arrayprm3.awk, arrayprm3.ok, arryref2.ok,
+ arryref3.ok, arryref4.ok, arryref5.ok, rstest3.awk, rstest3.ok, rstest4.awk,
+ rstest4.ok, rstest5.awk, rstest5.ok: New files.
+
+Sun May 11 12:20:59 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strftime.awk: Remove seconds from input and strftime output,
+ to decrease chance of failing on second boundary.
+ * Makefile.am (strftime): Tweak message appropriately.
+
+Tue Mar 25 08:35:42 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fnarray2): New test.
+ * fnarray2.awk, fnarray2.ok: New files.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Wed Mar 19 14:00:00 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (synerr1): New test.
+ * synerr1.awk, synerr1.ok: New files.
+
+Tue Mar 4 10:32:23 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clean): Remove `core*' for modern Linux which
+ drops core in `core.PID' files.
+
+2003-02-17 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (check): Don't depend on the pass-fail rule that
+ reports any failures. Otherwise, for `make -j' that rule's commands
+ could run before all tests had completed, resulting in spurious
+ failures or potentially, even unreported failures. Instead, just
+ `$(MAKE) pass-fail'.
+
+Sun Feb 9 11:48:32 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Moved `space' into UNIX_TESTS. Breaks in
+ MS environments.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Tue Feb 4 12:22:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fnmisc): New test case.
+ * fnmisc.awk, fnmisc.ok: New files.
+
+Sun Feb 2 15:33:33 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * getline3.awk, getline3.ok: Renamed from getline2.awk, getline2.ok
+ * Makefile.am (getline, getline2): getline renamed to getline2,
+ new test under the name getline.
+ * getline.awk, getline.ok, getline2.awk, getline2.ok:
+ rename getline.* getline2.*; new files getline.* .
+ * getline.awk, getline.ok: add tests for ``cmd | getline ''
+ * Makefile.am (printf0): New test.
+ * printf0.awk, printf0.ok: New files.
+ * fnarray.ok: The error message has changed.
+
+Thu Jan 30 15:32:56 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (splitarr, getline2, inputred, prec): New tests.
+ * splitarr.awk, splitarr.ok: New files.
+ * getline2.awk, getline2.ok: New files.
+ * inputred.awk, inputred.ok: New files.
+ * prec.awk, prec.ok: New files.
+ * noeffect.awk: add second no-effect command; two error messages
+ should be generated. Add some empty statements, to check that --lint
+ doesn't abort on them.
+
+Tue Jan 28 18:34:22 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * arrymem1.awk: Enhanced test.
+ * arrayme1.ok: Updated for new output
+
+Mon Jan 27 14:07:16 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * nfldstr.awk: Add tests for automatic number conversion.
+
+Mon Jan 27 12:25:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (asort, asorti, match1): New tests.
+ * match1.awk, match1.in: New files.
+ * asort.awk, asort.in: New files.
+ * asorti.awk, asorti.in: New files.
+
+Mon Jan 27 12:10:16 2003 Stepan Kasal <kasal@math.cas.cz>
+
+ * strtod.awk, strtod.in, strtod.ok: Added test for 0e0 and similar.
+
+Sun Jan 26 16:49:41 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (zeroe0): New test.
+ * zeroe0.awk, zeroe0.in: New files.
+
+Thu Jan 2 11:09:12 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * parseme.ok, noparms.ok: Revised for bison 1.875.
+
+Tue Dec 31 16:54:44 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: (poundbang): Fix code.
+ (efence): New target to remove _* files run with Electric Fence
+ but that are otherwise OK.
+
+Thu Dec 26 16:44:37 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (poundbang): Add code to handle systems with limits on
+ paths for #! files.
+
+Mon Dec 9 14:20:44 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (space): New test: ``gawk -f " " file'' should try
+ to include file ` '.
+
+Sun Nov 17 21:47:11 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (manyfiles): Reference $(srcdir)/$@.ok so can build
+ and test in a different directory.
+
+Sun Nov 3 14:47:59 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ Move tests with inline input and/or programs into separate files so can let
+ Gentests do more work. Per Nelson Beebe, just print the name of each test.
+
+ * Makefile.am (fstabplus, longwrds, fieldwdth, ignrcase, posix, rs, fsbs):
+ removed targets so will be generated by Gentests.
+ (negexp, resplit, childin, back89, nfldstr, nondec): ditto.
+ * Gentests: print name of test, make cmp not echo by prefixing with @.
+ * fstabplus.in: new file.
+ * fieldwdth.awk, fieldwdth.in: new files.
+ * ignrcase.awk, ignrcase.in: new files.
+ * longwrds.awk: send output to sort instead of letting makefile do it.
+ * longwrds.in: renamed from manpage.
+ * posix.in: new file.
+ * manyfiles.ok: new file.
+ * rs.awk: new file.
+ * fsbs.awk: new file.
+ * negexp.awk: new file.
+ * resplit.awk, resplit.in: new files.
+ * childin.awk, childin.in: new files.
+ * back89.awk: new file.
+ * nfldstr.awk, nfldstr.in: new files.
+
+Sun Nov 3 14:37:39 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (uninit2): new test case, requires lint.
+ * uninit2.awk, uninit2.ok: new files.
+
+Fri Nov 1 11:34:45 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (nondec): Always run this test.
+
+Tue Oct 29 10:40:47 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Added Gentests to list of files
+ to distribute.
+
+Mon Oct 28 15:36:42 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (icasers, icasefs, rstest1, rstest2): new test cases.
+ (argarray): Remove argarray.in if not in srcdir.
+ * icasers.awk, icasers.in, icasers.ok: new files.
+ * icasefs.awk, icasefs.ok: new files.
+ * rstest1.awk, rstest1.ok: new files.
+ * rstest2.awk, rstest2.ok: new files.
+
+Mon Oct 28 12:25:25 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (uninitialized): New test.
+ * uninitialized.awk, uninitialized.ok: New files.
+
+Mon Oct 28 11:24:16 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * Gentests: new script
+ * Maketests: new file, generated automatically by Gentests
+ * Makefile.am: new rules and variables to make use of Gentests;
+ Most targets removed, Gentests will take care
+
+Sun Oct 13 16:58:07 2002 Stepan Kasal <kasal@math.cas.cz>
+
+ * Makefile.am (nfneg): new test case.
+ * nfneg.awk, nfneg.ok: new files.
+
+Mon Oct 7 09:38:07 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (noloop1, noloop2): new test cases.
+ * noloop.awk, noloop1.in, noloop1.ok, noloop2.in, noloop2.ok:
+ new files.
+
+Tue Oct 1 18:28:40 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (poundbang): Rewrote rule to avoid problems
+ with hardcoding of /tmp pathname.
+ (poundbang.awk): Changed the way it works.
+ (poundbang.ok): Removed.
+
+Thu Sep 5 13:31:28 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rebuf): new test case.
+ * rebuf.awk, rebuf.in, rebuf.ok: new files.
+
+Wed Aug 21 15:31:57 2002 Andreas Buening <andreas.buening@nexgo.de>
+
+ * Makefile.am (AWKPROG): Add $(EXEEXT) macro.
+ (PATH_SEPERATOR): Removed.
+ (poundbag): Added $(EXEEXT) and use of ${TMPDIR-/tmp}.
+
+Wed Aug 7 13:47:09 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (nulrsend): new test case.
+ * nulrsend.awk, nulrsend.in, nulrsend.ok: new files.
+
+Sun Aug 4 00:25:23 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gsubtst3, gsubtst4): new test cases.
+ * gsubtst3.awk, gsubtst3.ok, gsubtst4.awk, gsubtst4.ok: new files.
+
+Thu May 9 22:31:36 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gsubtst2): new test case.
+ * gsubtest.awk, gsubtest.ok: Added new test.
+ * gsubtst2.awk, gsubtst2.ok: new files.
+
+Sun May 5 12:38:55 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Minor mods to use LC_ALL=C so that checks will
+ use the English messages, not any translations.
+ (manyfiles): Fixed (hopefully) to leave a file around if the
+ test fails, so that we don't get a spurious "ALL TESTS PASSED"
+ message.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Tue Apr 16 17:07:25 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pass-fail): New target that prints an
+ `all passed' or `x tests failed' message, for use in
+ grep-ing build logs.
+ (check): Add pass-fail as last dependency.
+
+ Thanks to Nelson Beebe for the thought, beebe@math.utah.edu.
+
+Sun Mar 10 17:00:51 2002 Scott Deifik <scottd@amgen.com>
+
+ * Makefile.am (strftime): Add TZ=GMT0 into environment, to
+ regularize things, esp. for some DJGPP systems.
+
+Mon Feb 18 14:55:19 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (longsub): new test case.
+ * longsub.awk, longsub.in, longsub.ok: new files.
+
+Wed Jan 23 15:03:36 2002 Andreas Buening <andreas.buening@nexgo.de>
+
+ * Makefile.am (PATH_SEPARATOR): Added.
+ (awkpath): Make use of PATH_SEPARATOR.
+
+Wed Jan 23 14:50:38 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (concat1): new test case.
+ * concat1.awk, concat1.in, concat1.ok: new files.
+
+Mon Jan 7 22:21:25 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (forsimp): new test case.
+ * forsimp.awk, forsimp.ok: new files.
+
+Wed Dec 26 22:01:52 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (inftest): Add sed to fix case issues between
+ different libc versions. Ugh.
+
+Wed Dec 19 16:01:58 2001 Peter J. Farley III <pjfarley@dorsai.org>
+
+ * Makefile.am (manyfiles): Also delete \15 in tr.
+
+Tue Dec 18 20:56:07 2001 Andreas Buening <andreas.buening@nexgo.de>
+
+ * Makefile.am (nors): Add \15 to list of chars to delete so
+ test will run on OS/2 also.
+
+Thu Oct 4 18:34:49 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (membug1): new test case.
+ * membug1.awk, membug1.in, membug1.ok: new files.
+
+Thu Aug 23 14:04:10 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (minusstr): new test case.
+ * minusstr.awk, minusstr.ok: new files.
+
+Sat Aug 4 23:42:37 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (arrymem1): new test case.
+ (compare2): new test case.
+ (regtest): Make test work, use regtest.sh, not .awk.
+ * arrymem1.awk, arrymem1.ok: new files.
+ * compare2.awk, compare2.ok: new files.
+
+Mon Jul 23 17:32:03 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (onlynl): new test case.
+ * onlynl.awk, onlynl.in, onlynl.ok: new files.
+
+Wed Jun 13 18:12:43 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (ofmtfidl): new test case.
+ * ofmtfidl.awk, ofmtfidl.in, ofmtfidl.ok: new files.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Sun May 6 13:30:20 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * inftest.awk: Changed test to use < so that it will
+ work for MSC and DJGPP combination, per Scott Deifik.
+
+Tue Mar 20 11:09:51 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (funsemnl): new test case.
+ * funsemnl.awk, funsemnl.ok: new files.
+
+Wed Mar 7 11:31:41 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (leadnl): new test case.
+ * leadnl.awk, leadnl.in, leadnl.ok: new files.
+
+Tue Feb 6 18:08:15 2001 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rebt8b1, rebt8b2): new test case.
+ * rebt8b1.awk, rebt8b1.ok: new files.
+ * rebt8b2.awk, rebt8b2.ok: new files.
+
+Sun Dec 3 15:36:41 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gnuops2): New test case.
+ * gnuops2.awk, gnuops2.ok: New files, based on bug report from
+ Servatius.Brandt@fujitsu-siemens.com.
+
+Mon Nov 27 15:52:46 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * regx8bit.awk, regx8bit.ok: Updated to what should
+ work on all systems.
+
+Wed Nov 22 13:27:59 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (poundbang): Added some smarts for /tmp mounted
+ noexec. Hopefully it'll even work.
+
+Tue Nov 14 17:45:02 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Added - to all cmp calls for consistency.
+
+Sun Nov 12 17:50:18 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (addcomma): new test case.
+ * addcomma.awk, addcomma.in, addcomma.ok: new files.
+
+Tue Nov 7 16:03:06 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (regx8bit, psx96sub): new test cases.
+ * regx8bit.awk, regx8bit.ok, psx96sub.awk, psx96sub.ok: new files.
+
+Sun Oct 22 12:09:43 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (shadow): new test case.
+ * shadow.awk, shadow.ok: new files.
+
+Tue Oct 17 10:51:09 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (arynasty): new test case.
+ * arynasty.awk, arynasty.ok: new files.
+
+Mon Oct 2 10:17:13 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clsflnam): Add redirect of stderr.
+ * clsflnam.awk, clsflnam.ok: modified to reflect changed
+ semantics of close() for a non-open file. See ../ChangeLog.
+
+Sun Sep 24 16:46:29 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (nasty2): new test case.
+ * nasty2.awk, nasty2.ok: new files.
+
+Wed Sep 13 11:09:49 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (check): Added calls to new targets that
+ print messages.
+ (clos1way, basic-msg-start, basic-msg-end, unix-msg-start,
+ unix-msg-end, extend-msg-start, extend-msg-end): new targets.
+ * clos1way.awk, clos1way.ok: new files.
+
+Tue Sep 12 16:29:54 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (leaddig): new test case.
+ * leaddig.awk, leaddig.ok: new files.
+
+Wed Sep 6 14:09:15 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (strtod): new test case.
+ * strtod.awk, strtod.in, strtod.ok: new files.
+
+Mon Sep 4 09:33:28 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (octsub): new test case.
+ * octsub.awk, octsub.ok: new files.
+
+Sun Aug 13 12:37:16 2000 Arnold Robbins <arnold@skeeve.com>
+
+ * Makefile.am (sort1, diffout): new test cases.
+ * sort1.awk, sort1.ok: new files.
+
+2000-02-15 Arnold Robbins <arnold@skeeve.com>
+
+ * MOVED TO AUTOMAKE AND GETTEXT.
+ Just about every file touched. Work done by Arno Peters.
+
+Wed May 19 15:41:41 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (datanonl,regeq,redfilnm): new test cases.
+ * datanonl.awk, datanonl.in, datanonl.ok: new files.
+ * regeq.awk, regeq.in, regeq.ok: new files.
+ * redfilnm.awk, redfilnm.in, redfilnm.ok: new files.
+
+Mon May 10 17:11:30 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (rsnul1nl): new test case.
+ * rsnul1nl.awk, rsnul1nl.in, rsnul1nl.ok: new files.
+
+Sun Apr 25 13:02:35 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (inetechu,inetecht,inetdayu,inetdayt,inet): new
+ tests, courtesy of Juergen Khars.
+ (paramtyp): new test for bug from Juergen.
+ * paramtyp.awk, paramtyp.in: new files.
+
+Sun Oct 25 23:11:46 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (ofmtbig,procinfs): new test cases.
+ * procinfs.awk, procinfs.ok: new files.
+ * ofmtbig.awk, ofmtbig.in, ofmtbig.ok: new files.
+
+Tue Oct 20 22:07:10 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (lint): new test case.
+ * lint.awk, lint.ok: new files.
+ * badargs.ok: updated output corresponding to change made to
+ main.c (see main ChangeLog).
+
+Tue May 26 20:39:07 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * pipeio2.awk: change "\'" to "'" to avoid new warning.
+
+Mon Mar 23 21:53:36 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (fnasgnm): new test case.
+ * fnasgnm.awk, fnasgnm.in, fnasgnm.ok: new files.
+
+Fri Mar 20 11:01:38 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (fnaryscl): new test case.
+ * fnaryscl.awk, fnaryscl.ok: new files.
+
+Mon Mar 16 15:23:22 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (splitdef): new test case.
+ * splitdef.awk, splitdef.ok: new files.
+
+Fri Sep 26 01:10:14 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (parseme): new test case.
+ * parseme.awk, parseme.ok: new files.
+
+Sun Sep 14 23:25:10 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (ofmts): new test case.
+ * ofmts.awk, ofmts.in, ofmts.ok: new files.
+
+Sun Aug 17 07:17:35 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (fsfwfs): new test case.
+ * fsfwfs.awk, fsfwfs.in, fsfwfs.ok: new files.
+
+Sun Jul 27 23:08:53 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (hsprint): new test case.
+ * hsprint.awk, hsprint.ok, printfloat.awk: new files.
+
+Thu Jul 17 20:07:31 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (ofmt): new test case.
+ * ofmt.awk, ofmt.in, ofmt.ok: new files.
+
+Sun Jun 22 16:17:35 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (nlinstr): new test case.
+ * nlinstr.awk, nlinstr.in, nlinstr.ok: new files.
+
+Wed Jun 4 13:18:21 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * pid.sh: send errors to /dev/null to toss warning about
+ using PROCINFO["pid"] etc. This test explicitly tests
+ the special files. It'll need changing in 3.2.
+
+Thu Apr 24 23:24:59 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (messages): remove special case if /dev/fd exists.
+ Finally.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Thu Aug 3 17:51:56 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (nlstrina): new test case.
+ * nlstrina.awk, nlstrina.ok: new files.
+
+Tue Jul 11 14:22:55 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (fnparydl): new test case.
+ * fnparydl.awk, fnparydl.ok: new files.
+
+Fri Jun 30 22:00:03 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (arysubnm): new test case.
+ * arysubnm.awk, arysubnm.ok: new files.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 14 13:17:59 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (getlnbuf): new test case.
+ * getlnbuf.awk, gtlnbufv.awk, getlnbuf.in, getlnbuf.ok: new files.
+
+Mon Jun 5 15:51:39 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * pipeio2.awk: Change use of tr to sed, fixes problems
+ on SCO OS5.
+ * pipeio2.ok: Updated to reflect use of sed.
+
+Tue May 2 13:28:04 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (strftime): moved test code into a separate
+ file for the PC guys.
+ * strftime.awk: new file.
+
+Mon Apr 10 15:58:13 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (longwrds): Add setting LC_ALL=C to sort
+ call to preserve traditional output. (Theme from the
+ Twilight Zone plays eerily in the background...)
+
+Sun Apr 2 17:51:40 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (igncdym): new test case.
+ * igncdym.awk, igncdym.in, igncdym.ok: new files.
+
+Wed Mar 8 13:43:44 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (arynocls): new test case.
+ * arynocls.awk, arynocls.in, arynocls.ok: new files.
+
+Sun Feb 6 11:45:15 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (opasnidx): new test case.
+ * opasnidx.awk, opasnidx.ok: new files.
+
+Tue Feb 1 18:40:45 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (opasnslf): new test case.
+ * opasnslf.awk, opasnslf.ok: new files.
+
+Thu Jan 27 18:09:18 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (subslash): new test case.
+ * subslash.awk, subslash.ok: new files.
+
+Fri Nov 26 11:03:07 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (numindex): new test case.
+ * numindex.awk, numindex.in, numindex.ok: new files.
+
+Sun Oct 24 08:46:16 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (strftime): Add tweak for $NF that should
+ hopefully avoid cygwin problems with lack of timezone.
+
+Thu Jul 29 19:25:02 1999 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.in (fsmnam, fnamedat): new test cases.
+ * fsmnam.awk, fsmnam.ok: new files.
+ * fnamedat.awk, fnamedat.in, fnamedat.ok: new files.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Tue May 25 16:37:50 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (printf1): new test case.
+ * printf1.awk, printf1.ok: new files.
+
+Wed May 19 15:32:09 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * reg/*: moved exp and log tests to new `Obsolete' directory; they
+ would only succeed under SunOS 4.x.
+
+Mon May 3 11:53:33 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (gawk.extensions): removed `nondec' until the
+ associated features get documented in 3.1.
+
+Tue Nov 3 16:46:39 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (getnr2tm, getnr2tb): new test cases.
+ * getnr2tm.awk, getnr2tm.in, getnr2tm.ok: new files.
+ * getnr2tb.awk, getnr2tb.in, getnr2tb.ok: new files.
+
+Sun Nov 1 13:20:08 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (zeroflag): new test case.
+ * zeroflag.awk, zeroflag.ok: new files
+
+Wed Oct 28 18:44:19 1998 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (nasty): new test case.
+ * nasty.awk, nasty.ok: new files
+
+Sun Nov 16 20:08:59 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * gsubtest.awk, gsubtest.ok: fix for count of matches in gsub
+ from Geert.Debyser@esat.kuleuven.ac.be.
+
+Sun Nov 16 19:54:50 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Makefile.in (strftime): fix a typo (LANC -> LANG).
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Tue May 13 12:53:46 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (messages): more testing for OK failure on Linux.
+
+Sun May 11 14:57:11 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (nondec): new test case.
+ * nondec.awk, nondec.ok: new files.
+
+Sun May 11 07:07:05 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (prdupval): new test case.
+ * prdupval.awk, prdupval.in, prdupval.ok: new files.
+
+Wed May 7 21:54:34 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (delarprm): new test case.
+ * delarprm.awk, delarprm.ok: new files.
+
+Wed May 7 17:54:00 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pid): several fixes from ghazi@caip.rutgers.edu.
+
+Tue May 6 20:28:30 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (strftime): Use the right locale stuff.
+ (clobber): don't need an input file.
+
+Thu Apr 24 22:24:42 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pid): new test case, from jco@convex.com.
+ (specfile): removed test case, pid does it better.
+ * pid.awk, pid.ok, pid.sh: new files.
+ * specfile.awk: removed.
+
+Wed Apr 23 23:37:10 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pipeio2): new test case.
+ * pipeio2.awk, pipeio2.ok, pipeio2.in: new files.
+
+Sun Apr 20 12:22:52 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clobber): new test case.
+ * clobber.awk, clobber.ok: new files.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Tue Apr 15 05:57:29 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (strftlng): More wizardry for bizarre Unix systems.
+ (nlfldsep): use program and input file, not shell script
+ (basic, unix-tests, gawk.extensions): moved specfile, pipeio1
+ and strftlng into unix-tests per Pat Rankin.
+ * nlfldsep.awk, nlfldsep.in: new files.
+ * nlfldsep.sh: removed.
+
+Wed Apr 9 23:32:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (funstack): new test case.
+ * funstack.awk, funstack.in, funstack.ok: new files.
+ * substr.awk: added many more tests.
+ * substr.ok: updated
+
+Wed Mar 19 20:10:21 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pipeio1): new test case.
+ * pipeio1.awk, pipeio1.ok: new files.
+
+Tue Mar 18 06:38:36 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (noparm): new test case.
+ * noparm.awk, noparm.ok: new files.
+
+Fri Feb 21 06:30:18 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (reint): new test case.
+ * reint.awk, reint.in, reint.ok: new files.
+
+Wed Feb 5 18:17:51 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (fnarydel): new test case.
+ * fnarydel.awk, fnarydel.ok: new files.
+
+Sun Jan 19 17:06:18 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (nors): new test case.
+ * nors.ok: new file.
+
+Sun Jan 19 17:06:18 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (specfile, strftlng, nfldstr): new test cases.
+ * specfile.awk, strftlng.awk, strftlng.ok, nfldstr.ok: new files.
+
+Fri Dec 27 11:27:13 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (intest): new test case.
+ * intest.awk, intest.ok: new files.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Thu Nov 7 09:12:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (splitvar): new test case.
+ * splitvar.awk, splitvar.in, splitvar.ok: new files.
+
+Sun Nov 3 10:55:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (nlfldsep): new test case.
+ * nlfldsep.sh, nlfldsep.ok: new files.
+
+Fri Oct 25 10:29:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * rand.awk: call srand with fixed seed.
+ * rand.ok: new file.
+ * Makefile.in (rand): changed to compare output with rand.ok.
+
+Sat Oct 19 21:52:04 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (tradanch): new test case.
+ * tradanch.awk, tradanch.in, tradanch.ok: new files.
+
+Thu Oct 17 21:22:05 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * tweakfld.awk: move `rm' out into Makefile.in.
+ * eofsplit.awk: fixed buggy code so won't loop forever.
+ * Makefile.in (all): add unix-tests.
+ (unix-tests): new target, has pound-bang, fflush, getlnhd.
+ (basic): removed fflush, getlnhd.
+ (tweakfld): added rm from tweakfld.awk.
+
+Sun Oct 6 22:00:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (back89): new test case.
+ * back89.in, back89.ok: new files.
+
+Sun Oct 6 20:45:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (splitwht): new test case.
+ * splitwht.awk, splitwht.ok: new files.
+
+Sun Sep 29 23:14:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gsubtest): new test case.
+ * gsubtest.awk, gsubtest.ok: new files.
+
+Fri Sep 20 11:58:40 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (prtoeval): new test case.
+ * prtoeval.awk, prtoeval.ok: new files.
+
+Tue Sep 10 06:26:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gsubasgn): new test case.
+ * gsubasgn.awk, gsubasgn.ok: new files.
+
+Wed Aug 28 22:06:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * badargs.ok: updated output corresponding to change made to
+ main.c (see main ChangeLog).
+
+Thu Aug 1 07:20:28 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): remove out[123] files from `messages' test.
+ Thanks to Pat Rankin (rankin@eql.caltech.edu).
+
+Sat Jul 27 23:56:57 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (prt1eval): new test case.
+ * prt1eval.awk, prt1eval.ok: new files.
+
+Mon Jul 22 22:06:10 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (eofsplit): new test case.
+ * eofsplit.awk, eofsplit.ok: new files.
+
+Sun Jul 14 07:07:45 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (fldchgnf): new test case.
+ * fldchgnf.awk, fldchgnf.ok: new files.
+
+Tue May 21 23:23:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (substr): new test case.
+ * substr.awk, substr.ok: new files.
+
+Tue May 14 15:05:23 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dynlj): new test case.
+ * dynlj.awk, dynlj.ok: new files.
+
+Sun May 12 20:45:34 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (fnarray): new test case.
+ * fnarray.awk, fnarray.ok: new files.
+
+Fri Mar 15 06:46:48 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): added `*~' to list of files to be removed.
+ * tweakfld.awk (END): added to do clean up action.
+
+Thu Mar 14 16:41:32 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (mmap8k): new test case.
+ * mmap8k.in, mmap8k.ok: new files.
+
+Sun Mar 10 22:58:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clsflnam): new test case.
+ * clsflnam.in, clsflnam.awk, clsflnam.ok: new files.
+ * tweakfld.awk: changed to have a fixed date.
+
+Thu Mar 7 09:56:09 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (tweakfld): new test case.
+ * tweakfld.in, tweakfld.awk, tweakfld.ok: new files.
+
+Sun Mar 3 06:51:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (getlnhd, backgsub) : new test cases.
+ * getlnhd.awk, getlnhd.ok: new files.
+ * backgsub.in, backgsub.awk, backgsub.ok: new files.
+
+Mon Feb 26 22:30:02 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (sprintfc): new test case.
+ * sprintfc.in, sprintfc.awk, sprintfc.ok: new files.
+ * gensub.awk: updated for case of no match of regex.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (distclean, maintainer-clean): new targets.
+ (reindops): added test from Rick Adams (rick@uunet.uu.net).
+ (arrayparm, paramdup, defref, strftime, prmarscl, sclforin,
+ sclifin): Fix from Larry Schwimmer (schwim@cyclone.stanford.edu)
+ so that tests that are supposed to fail use `... || exit 0' to
+ cause a clean `make clean'.
+
+Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * ChangeLog created.
--- /dev/null
+#!/usr/bin/gawk -f
+
+# This program should generate Maketests
+
+BEGIN {
+ # read the list of files
+ for (i = 2; i < ARGC; i++)
+ files[ARGV[i]]
+
+ # throw it away
+ ARGC = 2
+
+ ntests = 0
+}
+
+# process the file Makefile.am:
+
+/^[A-Z_]*_TESTS *=/,/[^\\]$/ {
+ gsub(/(^[A-Z_]*_TESTS *=|\\$)/,"")
+ for (i = 1; i <= NF; i++)
+ tests[++ntests] = $i
+ next
+}
+
+/^NEED_LINT *=/,/[^\\]$/ {
+ gsub(/(^NEED_LINT *=|\\$)/,"")
+ for (i = 1; i <= NF; i++)
+ lint[$i]
+ next
+}
+
+/^GENTESTS_UNUSED *=/,/[^\\]$/ {
+ gsub(/(^GENTESTS_UNUSED *=|\\$)/,"")
+ for (i = 1; i <= NF; i++)
+ unused[$i]
+ next
+}
+
+/^[a-zA-Z][a-zA-Z0-9]*:/ {
+ # remember all targets from Makefile.am
+ sub(/:.*/,"")
+ targets[$0]
+}
+
+# Now write the output file:
+END {
+ # this line tells automake to keep the comment with the rules:
+ print "Gt-dummy:"
+ print "# file Maketests, generated from Makefile.am by the Gentests program"
+
+ for (i = 1; i <= ntests; i++) {
+ x = tests[i]
+ if (!(x in targets))
+ generate(x)
+ }
+
+ print "# end of file Maketests"
+}
+
+function generate(x, s)
+{
+ if (!(x".awk" in files))
+ printf "WARNING: file `%s.awk' not found.\n", x > "/dev/stderr"
+ else
+ delete files[x".awk"]
+
+ print x ":"
+
+ s = ""
+ if (x in lint) {
+ s = s " --lint"
+ delete lint[x]
+ }
+ if (x".in" in files) {
+ s = s " < $(srcdir)/$@.in"
+ delete files[x".in"]
+ }
+
+ printf "\t@echo %s\n", x
+ printf "\t@AWKPATH=$(srcdir) $(AWK) -f $@.awk %s >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@\n", s
+ printf "\t@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@\n\n"
+}
+
+END {
+ for (x in lint)
+ if (!(x in targets))
+ printf "WARNING: --lint target `%s' is missing.\n", x > "/dev/stderr"
+ for (x in files)
+ if (!(x in unused) && \
+ !(gensub(/\.(awk|in)$/,"","",x) in targets))
+ printf "WARNING: unused file `%s'.\n", x > "/dev/stderr"
+}
--- /dev/null
+#
+# test/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1988-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+## process this file with automake to produce Makefile.in
+
+EXTRA_DIST = \
+ reg \
+ lib \
+ Gentests \
+ Maketests \
+ README \
+ addcomma.awk \
+ addcomma.in \
+ addcomma.ok \
+ anchgsub.awk \
+ anchgsub.in \
+ anchgsub.ok \
+ argarray.awk \
+ argarray.in \
+ argarray.ok \
+ argtest.awk \
+ argtest.ok \
+ arrayparm.awk \
+ arrayparm.ok \
+ arrayprm2.awk \
+ arrayprm2.ok \
+ arrayprm3.awk \
+ arrayprm3.ok \
+ arrayref.awk \
+ arrayref.ok \
+ arrymem1.awk \
+ arrymem1.ok \
+ arryref2.awk \
+ arryref2.ok \
+ arryref3.awk \
+ arryref3.ok \
+ arryref4.awk \
+ arryref4.ok \
+ arryref5.awk \
+ arryref5.ok \
+ arynasty.awk \
+ arynasty.ok \
+ arynocls.awk \
+ arynocls.in \
+ arynocls.ok \
+ aryprm1.awk \
+ aryprm1.ok \
+ aryprm2.awk \
+ aryprm2.ok \
+ aryprm3.awk \
+ aryprm3.ok \
+ aryprm4.awk \
+ aryprm4.ok \
+ aryprm5.awk \
+ aryprm5.ok \
+ aryprm6.awk \
+ aryprm6.ok \
+ aryprm7.awk \
+ aryprm7.ok \
+ aryprm8.awk \
+ aryprm8.ok \
+ arysubnm.awk \
+ arysubnm.ok \
+ asgext.awk \
+ asgext.in \
+ asgext.ok \
+ asort.awk \
+ asort.ok \
+ asorti.awk \
+ asorti.ok \
+ awkpath.ok \
+ back89.awk \
+ back89.in \
+ back89.ok \
+ backgsub.awk \
+ backgsub.in \
+ backgsub.ok \
+ backw.awk \
+ backw.in \
+ backw.ok \
+ badargs.ok \
+ childin.awk \
+ childin.in \
+ childin.ok \
+ clobber.awk \
+ clobber.ok \
+ clos1way.awk \
+ clos1way.ok \
+ clsflnam.awk \
+ clsflnam.in \
+ clsflnam.ok \
+ compare.awk \
+ compare.in \
+ compare.ok \
+ compare2.awk \
+ compare2.ok \
+ concat1.awk \
+ concat1.in \
+ concat1.ok \
+ concat2.awk \
+ concat2.ok \
+ concat3.awk \
+ concat3.ok \
+ convfmt.awk \
+ convfmt.ok \
+ datanonl.awk \
+ datanonl.in \
+ datanonl.ok \
+ defref.awk \
+ defref.ok \
+ delarprm.awk \
+ delarprm.ok \
+ delarpm2.awk \
+ delarpm2.ok \
+ delfunc.awk \
+ delfunc.ok \
+ dynlj.awk \
+ dynlj.ok \
+ eofsplit.awk \
+ eofsplit.ok \
+ exitval1.awk \
+ exitval1.ok \
+ exitval2.awk \
+ exitval2.ok \
+ fflush.ok \
+ fflush.sh \
+ fieldwdth.awk \
+ fieldwdth.in \
+ fieldwdth.ok \
+ fldchg.awk \
+ fldchg.in \
+ fldchg.ok \
+ fldchgnf.awk \
+ fldchgnf.in \
+ fldchgnf.ok \
+ fmttest.awk \
+ fmttest.ok \
+ fnamedat.awk \
+ fnamedat.in \
+ fnamedat.ok \
+ fnarray.awk \
+ fnarray.ok \
+ fnarray2.awk \
+ fnarray2.ok \
+ fnarydel.awk \
+ fnarydel.ok \
+ fnaryscl.awk \
+ fnaryscl.ok \
+ fnasgnm.awk \
+ fnasgnm.in \
+ fnasgnm.ok \
+ fnmisc.awk \
+ fnmisc.ok \
+ fnparydl.awk \
+ fnparydl.ok \
+ fordel.awk \
+ fordel.ok \
+ forsimp.awk \
+ forsimp.ok \
+ fsbs.awk \
+ fsbs.in \
+ fsbs.ok \
+ fsfwfs.awk \
+ fsfwfs.in \
+ fsfwfs.ok \
+ fsrs.awk \
+ fsrs.in \
+ fsrs.ok \
+ fsspcoln.awk \
+ fsspcoln.in \
+ fsspcoln.ok \
+ fstabplus.awk \
+ fstabplus.in \
+ fstabplus.ok \
+ funsemnl.awk \
+ funsemnl.ok \
+ funsmnam.awk \
+ funsmnam.ok \
+ funstack.awk \
+ funstack.in \
+ funstack.ok \
+ gensub.awk \
+ gensub.in \
+ gensub.ok \
+ gensub2.awk \
+ gensub2.ok \
+ getline.awk \
+ getline.in \
+ getline.ok \
+ getline2.awk \
+ getline2.ok \
+ getline3.awk \
+ getline3.ok \
+ getlnbuf.awk \
+ getlnbuf.in \
+ getlnbuf.ok \
+ getlnhd.awk \
+ getlnhd.ok \
+ getnr2tb.awk \
+ getnr2tb.in \
+ getnr2tb.ok \
+ getnr2tm.awk \
+ getnr2tm.in \
+ getnr2tm.ok \
+ gnuops2.awk \
+ gnuops2.ok \
+ gnuops3.awk \
+ gnuops3.ok \
+ gnureops.awk \
+ gnureops.ok \
+ gsubasgn.awk \
+ gsubasgn.ok \
+ gsubtest.awk \
+ gsubtest.ok \
+ gsubtst2.awk \
+ gsubtst2.ok \
+ gsubtst3.awk \
+ gsubtst3.in \
+ gsubtst3.ok \
+ gsubtst4.awk \
+ gsubtst4.ok \
+ gsubtst5.awk \
+ gsubtst5.in \
+ gsubtst5.ok \
+ gtlnbufv.awk \
+ hex.awk \
+ hex.ok \
+ hsprint.awk \
+ hsprint.ok \
+ icasefs.awk \
+ icasefs.ok \
+ icasers.awk \
+ icasers.in \
+ icasers.ok \
+ igncdym.awk \
+ igncdym.in \
+ igncdym.ok \
+ igncfs.awk \
+ igncfs.in \
+ igncfs.ok \
+ ignrcase.awk \
+ ignrcase.in \
+ ignrcase.ok \
+ ignrcas2.awk \
+ ignrcas2.ok \
+ inftest.awk \
+ inftest.ok \
+ inputred.awk \
+ inputred.ok \
+ intest.awk \
+ intest.ok \
+ intprec.awk \
+ intprec.ok \
+ iobug1.awk \
+ iobug1.ok \
+ leaddig.awk \
+ leaddig.ok \
+ leadnl.awk \
+ leadnl.in \
+ leadnl.ok \
+ lint.awk \
+ lint.ok \
+ litoct.awk \
+ litoct.ok \
+ longdbl.awk \
+ longdbl.in \
+ longdbl.ok \
+ longsub.awk \
+ longsub.in \
+ longsub.ok \
+ longwrds.awk \
+ longwrds.ok \
+ longwrds.in \
+ manglprm.awk \
+ manglprm.in \
+ manglprm.ok \
+ manyfiles.awk \
+ manyfiles.ok \
+ match1.awk \
+ match1.ok \
+ match2.awk \
+ match2.ok \
+ math.awk \
+ math.ok \
+ membug1.awk \
+ membug1.in \
+ membug1.ok \
+ messages.awk \
+ minusstr.awk \
+ minusstr.ok \
+ mmap8k.in \
+ nasty.awk \
+ nasty.ok \
+ nasty2.awk \
+ nasty2.ok \
+ negexp.awk \
+ negexp.ok \
+ nested.awk \
+ nested.in \
+ nested.ok \
+ nfldstr.awk \
+ nfldstr.in \
+ nfldstr.ok \
+ nfneg.awk \
+ nfneg.ok \
+ nfset.awk \
+ nfset.in \
+ nfset.ok \
+ nlfldsep.awk \
+ nlfldsep.in \
+ nlfldsep.ok \
+ nlinstr.awk \
+ nlinstr.in \
+ nlinstr.ok \
+ nlstrina.awk \
+ nlstrina.ok \
+ noeffect.awk \
+ noeffect.ok \
+ nofmtch.awk \
+ nofmtch.ok \
+ noloop1.awk \
+ noloop1.in \
+ noloop1.ok \
+ noloop2.awk \
+ noloop2.in \
+ noloop2.ok \
+ nondec.awk \
+ nondec.ok \
+ nondec2.awk \
+ nondec2.ok \
+ nonl.awk \
+ nonl.ok \
+ noparms.awk \
+ noparms.ok \
+ nors.in \
+ nors.ok \
+ nulrsend.awk \
+ nulrsend.in \
+ nulrsend.ok \
+ numindex.awk \
+ numindex.in \
+ numindex.ok \
+ numsubstr.awk \
+ numsubstr.in \
+ numsubstr.ok \
+ octsub.awk \
+ octsub.ok \
+ ofmt.awk \
+ ofmt.in \
+ ofmt.ok \
+ ofmtbig.awk \
+ ofmtbig.in \
+ ofmtbig.ok \
+ ofmtfidl.awk \
+ ofmtfidl.in \
+ ofmtfidl.ok \
+ ofmts.awk \
+ ofmts.in \
+ ofmts.ok \
+ onlynl.awk \
+ onlynl.in \
+ onlynl.ok \
+ opasnidx.awk \
+ opasnidx.ok \
+ opasnslf.awk \
+ opasnslf.ok \
+ out1.ok \
+ out2.ok \
+ out3.ok \
+ paramdup.awk \
+ paramdup.ok \
+ paramtyp.awk \
+ paramtyp.ok \
+ parseme.awk \
+ parseme.ok \
+ pcntplus.awk \
+ pcntplus.ok \
+ pid.awk \
+ pid.ok \
+ pid.sh \
+ pipeio1.awk \
+ pipeio1.ok \
+ pipeio2.awk \
+ pipeio2.in \
+ pipeio2.ok \
+ posix.awk \
+ posix.in \
+ posix.ok \
+ poundbang.awk \
+ prdupval.awk \
+ prdupval.in \
+ prdupval.ok \
+ prec.awk \
+ prec.ok \
+ printf0.awk \
+ printf0.ok \
+ printf1.awk \
+ printf1.ok \
+ printfbad1.awk \
+ printfbad1.ok \
+ printfloat.awk \
+ printlang.awk \
+ prmarscl.awk \
+ prmarscl.ok \
+ prmreuse.awk \
+ prmreuse.ok \
+ procinfs.awk \
+ procinfs.ok \
+ prt1eval.awk \
+ prt1eval.ok \
+ prtoeval.awk \
+ prtoeval.ok \
+ psx96sub.awk \
+ psx96sub.ok \
+ rand.awk \
+ rand.ok \
+ rebt8b1.awk \
+ rebt8b1.ok \
+ rebt8b2.awk \
+ rebt8b2.ok \
+ redfilnm.awk \
+ redfilnm.in \
+ redfilnm.ok \
+ regeq.awk \
+ regeq.in \
+ regeq.ok \
+ regtest.sh \
+ regx8bit.awk \
+ regx8bit.ok \
+ rebuf.awk \
+ rebuf.in \
+ rebuf.ok \
+ reindops.awk \
+ reindops.in \
+ reindops.ok \
+ reint.awk \
+ reint.in \
+ reint.ok \
+ reparse.awk \
+ reparse.in \
+ reparse.ok \
+ resplit.awk \
+ resplit.in \
+ resplit.ok \
+ rs.awk \
+ rs.in \
+ rs.ok \
+ rsnul1nl.awk \
+ rsnul1nl.in \
+ rsnul1nl.ok \
+ rsnulbig.ok \
+ rsnulbig2.ok \
+ rsstart1.awk \
+ rsstart1.in \
+ rsstart1.ok \
+ rsstart2.awk \
+ rsstart2.ok \
+ rsstart3.ok \
+ rstest1.awk \
+ rstest1.ok \
+ rstest2.awk \
+ rstest2.ok \
+ rstest3.awk \
+ rstest3.ok \
+ rstest4.awk \
+ rstest4.ok \
+ rstest5.awk \
+ rstest5.ok \
+ rstest6.awk \
+ rstest6.in \
+ rstest6.ok \
+ rswhite.awk \
+ rswhite.in \
+ rswhite.ok \
+ scalar.awk \
+ scalar.ok \
+ sclforin.awk \
+ sclforin.ok \
+ sclifin.awk \
+ sclifin.ok \
+ shadow.awk \
+ shadow.ok \
+ sort1.awk \
+ sort1.ok \
+ sortempty.awk \
+ sortempty.ok \
+ space.ok \
+ splitargv.awk \
+ splitargv.in \
+ splitargv.ok \
+ splitarr.awk \
+ splitarr.ok \
+ splitdef.awk \
+ splitdef.ok \
+ splitvar.awk \
+ splitvar.in \
+ splitvar.ok \
+ splitwht.awk \
+ splitwht.ok \
+ sprintfc.awk \
+ sprintfc.in \
+ sprintfc.ok \
+ strcat1.awk \
+ strcat1.ok \
+ strtod.awk \
+ strtod.in \
+ strtod.ok \
+ strtonum.awk \
+ strtonum.ok \
+ strftime.awk \
+ strftlng.awk \
+ strftlng.ok \
+ subamp.awk \
+ subamp.in \
+ subamp.ok \
+ subsepnm.awk \
+ subsepnm.ok \
+ subslash.awk \
+ subslash.ok \
+ substr.awk \
+ substr.ok \
+ swaplns.awk \
+ swaplns.in \
+ swaplns.ok \
+ switch2.awk \
+ synerr1.awk \
+ synerr1.ok \
+ tradanch.awk \
+ tradanch.in \
+ tradanch.ok \
+ tweakfld.awk \
+ tweakfld.in \
+ tweakfld.ok \
+ uninit2.awk \
+ uninit2.ok \
+ uninit3.awk \
+ uninit3.ok \
+ uninit4.awk \
+ uninit4.ok \
+ uninitialized.awk \
+ uninitialized.ok \
+ unterm.awk \
+ unterm.ok \
+ whiny.awk \
+ whiny.in \
+ whiny.ok \
+ wjposer1.awk \
+ wjposer1.in \
+ wjposer1.ok \
+ zeroe0.awk \
+ zeroe0.ok \
+ zeroflag.awk \
+ zeroflag.ok
+
+TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl
+
+# Get rid of core files when cleaning
+CLEANFILES = core core.*
+
+# try to keep these sorted
+BASIC_TESTS = addcomma anchgsub argarray arrayparm arrayref arrymem1 \
+ arrayprm2 arrayprm3 arryref2 arryref3 arryref4 arryref5 arynasty \
+ arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
+ aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
+ clsflnam compare compare2 concat1 concat2 concat3 convfmt datanonl defref \
+ delarprm delarpm2 delfunc dynlj eofsplit exitval1 exitval2 fldchg fldchgnf fmttest fnamedat \
+ fnarray fnarray2 fnarydel fnaryscl fnasgnm fnmisc fnparydl \
+ fordel forsimp fsbs fsspcoln fsrs fstabplus funsemnl funsmnam funstack getline \
+ getline2 getline3 getlnbuf getnr2tb getnr2tm gsubasgn gsubtest \
+ gsubtst2 gsubtst3 gsubtst4 gsubtst5 hex hsprint inputred intest \
+ intprec iobug1 leaddig leadnl litoct longsub longwrds manglprm math membug1 \
+ messages minusstr mmap8k nasty nasty2 negexp nested nfldstr \
+ nfneg nfset nlfldsep nlinstr nlstrina noeffect nofmtch noloop1 \
+ noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
+ ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup paramtyp \
+ parseme pcntplus prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval psx96sub rand rebt8b1 rebt8b2 redfilnm regeq \
+ reindops reparse resplit rs rsnul1nl rsnulbig rsnulbig2 rstest1 \
+ rstest2 rstest3 rstest4 rstest5 rswhite scalar sclforin sclifin \
+ sortempty splitargv splitarr splitdef splitvar splitwht sprintfc \
+ strcat1 strtod subamp subsepnm subslash substr swaplns synerr1 tradanch \
+ tweakfld uninit2 uninit3 uninit4 uninitialized unterm wjposer1 \
+ zeroe0 zeroflag
+
+UNIX_TESTS = fflush getlnhd pid pipeio1 pipeio2 poundbang space strftlng
+
+GAWK_EXT_TESTS = argtest asort asorti backw badargs clos1way fieldwdth fsfwfs \
+ gensub gensub2 gnuops2 gnuops3 gnureops icasefs icasers igncdym igncfs ignrcase \
+ ignrcas2 lint match1 match2 manyfiles nondec nondec2 posix procinfs \
+ printfbad1 regx8bit rebuf reint rsstart1 rsstart2 rsstart3 \
+ rstest6 shadow sort1 strtonum strftime whiny
+
+EXTRA_TESTS = regtest inftest
+
+INET_TESTS = inetechu inetecht inetdayu inetdayt
+
+# List of the tests which should be run with --lint option:
+NEED_LINT = defref noeffect nofmtch shadow uninit2 uninit3 uninit4 uninitialized
+
+# List of the files that appear in manual tests or are for reserve testing:
+GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk switch2.awk
+
+CMP = cmp
+AWKPROG = ../gawk$(EXEEXT)
+
+# This business forces the locale to be C for running the tests,
+# unless we override it to something else for testing.
+#
+# This can also be done in individual tests where we wish to
+# check things specifically not in the C locale.
+AWK = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} $(AWKPROG)
+
+# Message stuff is to make it a little easier to follow.
+# Make the pass-fail last and dependent on others to avoid
+# spurious errors if `make -j' in effect.
+check: msg \
+ printlang \
+ basic-msg-start basic basic-msg-end \
+ unix-msg-start unix-tests unix-msg-end \
+ extend-msg-start gawk-extensions extend-msg-end
+ @$(MAKE) pass-fail
+
+basic: $(BASIC_TESTS)
+
+unix-tests: $(UNIX_TESTS)
+
+gawk-extensions: $(GAWK_EXT_TESTS)
+
+extra: $(EXTRA_TESTS) inet
+
+inet: inetmesg $(INET_TESTS)
+
+msg::
+ @echo ''
+ @echo 'Any output from "cmp" is bad news, although some differences'
+ @echo 'in floating point values are probably benign -- in particular,'
+ @echo 'some systems may omit a leading zero and the floating point'
+ @echo 'precision may lead to slightly different output in a few cases.'
+
+printlang::
+ @$(AWK) -f $(srcdir)/printlang.awk
+
+basic-msg-start:
+ @echo "======== Starting basic tests ========"
+
+basic-msg-end:
+ @echo "======== Done with basic tests ========"
+
+unix-msg-start:
+ @echo "======== Starting Unix tests ========"
+
+unix-msg-end:
+ @echo "======== Done with Unix tests ========"
+
+extend-msg-start:
+ @echo "======== Starting gawk extension tests ========"
+
+extend-msg-end:
+ @echo "======== Done with gawk extension tests ========"
+
+
+# This test is a PITA because increasingly, /tmp is getting
+# mounted noexec. So, we'll test it locally. Sigh.
+#
+# More PITA; some systems have medium short limits on #! paths,
+# so this can still fail
+poundbang::
+ @echo $@
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @chmod +x ./_pbd.awk
+ @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ then : ; \
+ else \
+ sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ chmod +x ./_pbd.awk ; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@`; \
+ fi
+ @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+
+messages::
+ @echo $@
+ @$(AWK) -f $(srcdir)/messages.awk >out2 2>out3
+ @-$(CMP) $(srcdir)/out1.ok out1 && $(CMP) $(srcdir)/out2.ok out2 && $(CMP) $(srcdir)/out3.ok out3 && rm -f out1 out2 out3
+
+argarray::
+ @echo $@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) cp $(srcdir)/argarray.in . ;; \
+ esac
+ @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) rm -f ./argarray.in ;; \
+ esac
+ @-$(CMP) $(srcdir)/argarray.ok _$@ && rm -f _$@
+
+regtest::
+ @echo 'Some of the output from regtest is very system specific, do not'
+ @echo 'be distressed if your output differs from that distributed.'
+ @echo 'Manual inspection is called for.'
+ AWK=`pwd`/$(AWK) $(srcdir)/regtest.sh
+
+manyfiles::
+ @echo manyfiles
+ @rm -rf junk
+ @mkdir junk
+ @$(AWK) 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >_$@
+ @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
+ @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare::
+ @echo $@
+ @$(AWK) -f $(srcdir)/compare.awk 0 1 $(srcdir)/compare.in >_$@
+ @-$(CMP) $(srcdir)/compare.ok _$@ && rm -f _$@
+
+inftest::
+ @echo $@
+ @echo This test is very machine specific...
+ @$(AWK) -f $(srcdir)/inftest.awk | sed "s/inf/Inf/g" >_$@
+ @-$(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@
+
+getline2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
+ @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+
+awkpath::
+ @echo $@
+ @AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
+ @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+
+argtest::
+ @echo $@
+ @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
+ @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+
+badargs::
+ @echo $@
+ @-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
+ @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+
+nonl::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+
+strftime::
+ @echo This test could fail on slow machines or on a minute boundary,
+ @echo so if it does, double check the actual results:
+ @echo $@
+ @GAWKLOCALE=C; export GAWKLOCALE; \
+ TZ=GMT0; export TZ; \
+ (LC_ALL=C date) | $(AWK) -v OUTPUT=_$@ -f $(srcdir)/strftime.awk
+ @-$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0
+
+litoct::
+ @echo $@
+ @echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
+ @-$(CMP) $(srcdir)/litoct.ok _$@ && rm -f _$@
+
+fflush::
+ @echo $@
+ @$(srcdir)/fflush.sh >_$@
+ @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+
+tweakfld::
+ @echo $@
+ @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @rm -f errors.cleanup
+ @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+
+mmap8k::
+ @echo $@
+ @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
+ @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+
+tradanch::
+ @echo $@
+ @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
+ @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+
+# AIX /bin/sh exec's the last command in a list, therefore issue a ":"
+# command so that pid.sh is fork'ed as a child before being exec'ed.
+pid::
+ @echo pid
+ @AWKPATH=$(srcdir) AWK=$(AWKPROG) $(SHELL) $(srcdir)/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) $(srcdir)/pid.ok _`basename $@` && rm -f _`basename $@` _`basename $@`.in
+
+strftlng::
+ @echo $@
+ @TZ=UTC; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@
+ @if $(CMP) $(srcdir)/strftlng.ok _$@ >/dev/null 2>&1 ; then : ; else \
+ TZ=UTC0; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@ ; \
+ fi
+ @-$(CMP) $(srcdir)/strftlng.ok _$@ && rm -f _$@
+
+nors::
+ @echo $@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - $(srcdir)/nors.in > _$@
+ @-$(CMP) $(srcdir)/nors.ok _$@ && rm -f _$@
+
+reint::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
+ @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+
+pipeio1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @rm -f test1 test2
+ @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+
+pipeio2::
+ @echo $@
+ @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
+ @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+
+clobber::
+ @echo $@
+ @$(AWK) -f $(srcdir)/clobber.awk >_$@
+ @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @rm -f seq
+
+arynocls::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -v INPUT=$(srcdir)/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) $(srcdir)/arynocls.ok _$@ && rm -f _$@
+
+getlnbuf::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -f getlnbuf.awk $(srcdir)/getlnbuf.in > _$@
+ @-AWKPATH=$(srcdir) $(AWK) -f gtlnbufv.awk $(srcdir)/getlnbuf.in > _2$@
+ @-$(CMP) $(srcdir)/getlnbuf.ok _$@ && $(CMP) $(srcdir)/getlnbuf.ok _2$@ && rm -f _$@ _2$@
+
+inetmesg::
+ @echo These tests only work if your system supports the services
+ @echo "'discard'" at port 9 and "'daytimed'" at port 13. Check your
+ @echo file /etc/services and do "'netstat -a'".
+
+inetechu::
+ @echo This test is for establishing UDP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/udp/0/127.0.0.1/9"}'
+
+inetecht::
+ @echo This test is for establishing TCP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
+
+inetdayu::
+ @echo This test is for bidirectional UDP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/udp/0/127.0.0.1/13"; \
+ "/inet/udp/0/127.0.0.1/13" |& getline; print $0}'
+
+inetdayt::
+ @echo This test is for bidirectional TCP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13"; \
+ "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}'
+
+redfilnm::
+ @echo $@
+ @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
+ @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+
+leaddig::
+ @echo $@
+ @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
+ @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+
+gsubtst3::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+space::
+ @echo $@
+ @$(AWK) -f ' ' $(srcdir)/space.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf0::
+ @echo $@
+ @$(AWK) --posix -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig::
+ @echo $@
+ @ : Suppose that block size for pipe is at most 128kB:
+ @$(AWK) 'BEGIN { for (i = 1; i <= 128*64+1; i++) print "abcdefgh123456\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" }; { print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END{ print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig2::
+ @echo $@
+ @$(AWK) 'BEGIN { ORS = ""; n = "\n"; for (i = 1; i <= 10; i++) n = (n n); \
+ for (i = 1; i <= 128; i++) print n; print "abc\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" };{ print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END { print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+whiny::
+ @echo $@
+ @WHINY_USERS=1 $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcas2::
+ @echo $@
+ @GAWKLOCALE=en_US ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subamp::
+ @echo $@
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# This test makes sure gawk exits with a zero code.
+# Thus, unconditionally generate the exit code.
+exitval1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/exitval1.awk >_$@ 2>&1; echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsspcoln::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk 'FS=[ :]+' $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart3::
+ @echo $@
+ @head $(srcdir)/rsstart1.in | $(AWK) -f $(srcdir)/rsstart2.awk >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nondec2::
+ @echo $@
+ @$(AWK) --non-decimal-data -v a=0x1 -f $(srcdir)/$@.awk >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# Targets generated for other tests:
+include Maketests
+
+$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
+ $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" *.awk *.in > $(srcdir)/Maketests
+
+clean:
+ rm -fr _* core core.* junk out1 out2 out3 strftime.ok test1 test2 seq *~
+
+# An attempt to print something that can be grepped for in build logs
+pass-fail:
+ @COUNT=`ls _* 2>/dev/null | wc -l` ; \
+ if test $$COUNT = 0 ; \
+ then echo ALL TESTS PASSED ; \
+ else echo $$COUNT TESTS FAILED ; \
+ fi
+
+# This target for my convenience to look at all the results
+diffout:
+ for i in _* ; \
+ do \
+ echo ============== $$i ============= ; \
+ diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ done | more
+
+# This target is for testing with electric fence.
+efence:
+ for i in $$(ls _* | sed 's;_\(.*\);\1;') ; \
+ do \
+ bad=$$(wc -l < _$$i) \
+ ok=$$(wc -l < $$i.ok) ; \
+ if (( $$bad == $$ok + 2 )) ; \
+ then \
+ rm _$$i ; \
+ fi ; \
+ done
--- /dev/null
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# test/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1988-2005 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/Maketests ChangeLog
+subdir = test
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/socket.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/strtod.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+
+# This business forces the locale to be C for running the tests,
+# unless we override it to something else for testing.
+#
+# This can also be done in individual tests where we wish to
+# check things specifically not in the C locale.
+AWK = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} $(AWKPROG)
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMSGFMT = @GMSGFMT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+STRIP = @STRIP@
+U = @U@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+EXTRA_DIST = \
+ reg \
+ lib \
+ Gentests \
+ Maketests \
+ README \
+ addcomma.awk \
+ addcomma.in \
+ addcomma.ok \
+ anchgsub.awk \
+ anchgsub.in \
+ anchgsub.ok \
+ argarray.awk \
+ argarray.in \
+ argarray.ok \
+ argtest.awk \
+ argtest.ok \
+ arrayparm.awk \
+ arrayparm.ok \
+ arrayprm2.awk \
+ arrayprm2.ok \
+ arrayprm3.awk \
+ arrayprm3.ok \
+ arrayref.awk \
+ arrayref.ok \
+ arrymem1.awk \
+ arrymem1.ok \
+ arryref2.awk \
+ arryref2.ok \
+ arryref3.awk \
+ arryref3.ok \
+ arryref4.awk \
+ arryref4.ok \
+ arryref5.awk \
+ arryref5.ok \
+ arynasty.awk \
+ arynasty.ok \
+ arynocls.awk \
+ arynocls.in \
+ arynocls.ok \
+ aryprm1.awk \
+ aryprm1.ok \
+ aryprm2.awk \
+ aryprm2.ok \
+ aryprm3.awk \
+ aryprm3.ok \
+ aryprm4.awk \
+ aryprm4.ok \
+ aryprm5.awk \
+ aryprm5.ok \
+ aryprm6.awk \
+ aryprm6.ok \
+ aryprm7.awk \
+ aryprm7.ok \
+ aryprm8.awk \
+ aryprm8.ok \
+ arysubnm.awk \
+ arysubnm.ok \
+ asgext.awk \
+ asgext.in \
+ asgext.ok \
+ asort.awk \
+ asort.ok \
+ asorti.awk \
+ asorti.ok \
+ awkpath.ok \
+ back89.awk \
+ back89.in \
+ back89.ok \
+ backgsub.awk \
+ backgsub.in \
+ backgsub.ok \
+ backw.awk \
+ backw.in \
+ backw.ok \
+ badargs.ok \
+ childin.awk \
+ childin.in \
+ childin.ok \
+ clobber.awk \
+ clobber.ok \
+ clos1way.awk \
+ clos1way.ok \
+ clsflnam.awk \
+ clsflnam.in \
+ clsflnam.ok \
+ compare.awk \
+ compare.in \
+ compare.ok \
+ compare2.awk \
+ compare2.ok \
+ concat1.awk \
+ concat1.in \
+ concat1.ok \
+ concat2.awk \
+ concat2.ok \
+ concat3.awk \
+ concat3.ok \
+ convfmt.awk \
+ convfmt.ok \
+ datanonl.awk \
+ datanonl.in \
+ datanonl.ok \
+ defref.awk \
+ defref.ok \
+ delarprm.awk \
+ delarprm.ok \
+ delarpm2.awk \
+ delarpm2.ok \
+ delfunc.awk \
+ delfunc.ok \
+ dynlj.awk \
+ dynlj.ok \
+ eofsplit.awk \
+ eofsplit.ok \
+ exitval1.awk \
+ exitval1.ok \
+ exitval2.awk \
+ exitval2.ok \
+ fflush.ok \
+ fflush.sh \
+ fieldwdth.awk \
+ fieldwdth.in \
+ fieldwdth.ok \
+ fldchg.awk \
+ fldchg.in \
+ fldchg.ok \
+ fldchgnf.awk \
+ fldchgnf.in \
+ fldchgnf.ok \
+ fmttest.awk \
+ fmttest.ok \
+ fnamedat.awk \
+ fnamedat.in \
+ fnamedat.ok \
+ fnarray.awk \
+ fnarray.ok \
+ fnarray2.awk \
+ fnarray2.ok \
+ fnarydel.awk \
+ fnarydel.ok \
+ fnaryscl.awk \
+ fnaryscl.ok \
+ fnasgnm.awk \
+ fnasgnm.in \
+ fnasgnm.ok \
+ fnmisc.awk \
+ fnmisc.ok \
+ fnparydl.awk \
+ fnparydl.ok \
+ fordel.awk \
+ fordel.ok \
+ forsimp.awk \
+ forsimp.ok \
+ fsbs.awk \
+ fsbs.in \
+ fsbs.ok \
+ fsfwfs.awk \
+ fsfwfs.in \
+ fsfwfs.ok \
+ fsrs.awk \
+ fsrs.in \
+ fsrs.ok \
+ fsspcoln.awk \
+ fsspcoln.in \
+ fsspcoln.ok \
+ fstabplus.awk \
+ fstabplus.in \
+ fstabplus.ok \
+ funsemnl.awk \
+ funsemnl.ok \
+ funsmnam.awk \
+ funsmnam.ok \
+ funstack.awk \
+ funstack.in \
+ funstack.ok \
+ gensub.awk \
+ gensub.in \
+ gensub.ok \
+ gensub2.awk \
+ gensub2.ok \
+ getline.awk \
+ getline.in \
+ getline.ok \
+ getline2.awk \
+ getline2.ok \
+ getline3.awk \
+ getline3.ok \
+ getlnbuf.awk \
+ getlnbuf.in \
+ getlnbuf.ok \
+ getlnhd.awk \
+ getlnhd.ok \
+ getnr2tb.awk \
+ getnr2tb.in \
+ getnr2tb.ok \
+ getnr2tm.awk \
+ getnr2tm.in \
+ getnr2tm.ok \
+ gnuops2.awk \
+ gnuops2.ok \
+ gnuops3.awk \
+ gnuops3.ok \
+ gnureops.awk \
+ gnureops.ok \
+ gsubasgn.awk \
+ gsubasgn.ok \
+ gsubtest.awk \
+ gsubtest.ok \
+ gsubtst2.awk \
+ gsubtst2.ok \
+ gsubtst3.awk \
+ gsubtst3.in \
+ gsubtst3.ok \
+ gsubtst4.awk \
+ gsubtst4.ok \
+ gsubtst5.awk \
+ gsubtst5.in \
+ gsubtst5.ok \
+ gtlnbufv.awk \
+ hex.awk \
+ hex.ok \
+ hsprint.awk \
+ hsprint.ok \
+ icasefs.awk \
+ icasefs.ok \
+ icasers.awk \
+ icasers.in \
+ icasers.ok \
+ igncdym.awk \
+ igncdym.in \
+ igncdym.ok \
+ igncfs.awk \
+ igncfs.in \
+ igncfs.ok \
+ ignrcase.awk \
+ ignrcase.in \
+ ignrcase.ok \
+ ignrcas2.awk \
+ ignrcas2.ok \
+ inftest.awk \
+ inftest.ok \
+ inputred.awk \
+ inputred.ok \
+ intest.awk \
+ intest.ok \
+ intprec.awk \
+ intprec.ok \
+ iobug1.awk \
+ iobug1.ok \
+ leaddig.awk \
+ leaddig.ok \
+ leadnl.awk \
+ leadnl.in \
+ leadnl.ok \
+ lint.awk \
+ lint.ok \
+ litoct.awk \
+ litoct.ok \
+ longdbl.awk \
+ longdbl.in \
+ longdbl.ok \
+ longsub.awk \
+ longsub.in \
+ longsub.ok \
+ longwrds.awk \
+ longwrds.ok \
+ longwrds.in \
+ manglprm.awk \
+ manglprm.in \
+ manglprm.ok \
+ manyfiles.awk \
+ manyfiles.ok \
+ match1.awk \
+ match1.ok \
+ match2.awk \
+ match2.ok \
+ math.awk \
+ math.ok \
+ membug1.awk \
+ membug1.in \
+ membug1.ok \
+ messages.awk \
+ minusstr.awk \
+ minusstr.ok \
+ mmap8k.in \
+ nasty.awk \
+ nasty.ok \
+ nasty2.awk \
+ nasty2.ok \
+ negexp.awk \
+ negexp.ok \
+ nested.awk \
+ nested.in \
+ nested.ok \
+ nfldstr.awk \
+ nfldstr.in \
+ nfldstr.ok \
+ nfneg.awk \
+ nfneg.ok \
+ nfset.awk \
+ nfset.in \
+ nfset.ok \
+ nlfldsep.awk \
+ nlfldsep.in \
+ nlfldsep.ok \
+ nlinstr.awk \
+ nlinstr.in \
+ nlinstr.ok \
+ nlstrina.awk \
+ nlstrina.ok \
+ noeffect.awk \
+ noeffect.ok \
+ nofmtch.awk \
+ nofmtch.ok \
+ noloop1.awk \
+ noloop1.in \
+ noloop1.ok \
+ noloop2.awk \
+ noloop2.in \
+ noloop2.ok \
+ nondec.awk \
+ nondec.ok \
+ nondec2.awk \
+ nondec2.ok \
+ nonl.awk \
+ nonl.ok \
+ noparms.awk \
+ noparms.ok \
+ nors.in \
+ nors.ok \
+ nulrsend.awk \
+ nulrsend.in \
+ nulrsend.ok \
+ numindex.awk \
+ numindex.in \
+ numindex.ok \
+ numsubstr.awk \
+ numsubstr.in \
+ numsubstr.ok \
+ octsub.awk \
+ octsub.ok \
+ ofmt.awk \
+ ofmt.in \
+ ofmt.ok \
+ ofmtbig.awk \
+ ofmtbig.in \
+ ofmtbig.ok \
+ ofmtfidl.awk \
+ ofmtfidl.in \
+ ofmtfidl.ok \
+ ofmts.awk \
+ ofmts.in \
+ ofmts.ok \
+ onlynl.awk \
+ onlynl.in \
+ onlynl.ok \
+ opasnidx.awk \
+ opasnidx.ok \
+ opasnslf.awk \
+ opasnslf.ok \
+ out1.ok \
+ out2.ok \
+ out3.ok \
+ paramdup.awk \
+ paramdup.ok \
+ paramtyp.awk \
+ paramtyp.ok \
+ parseme.awk \
+ parseme.ok \
+ pcntplus.awk \
+ pcntplus.ok \
+ pid.awk \
+ pid.ok \
+ pid.sh \
+ pipeio1.awk \
+ pipeio1.ok \
+ pipeio2.awk \
+ pipeio2.in \
+ pipeio2.ok \
+ posix.awk \
+ posix.in \
+ posix.ok \
+ poundbang.awk \
+ prdupval.awk \
+ prdupval.in \
+ prdupval.ok \
+ prec.awk \
+ prec.ok \
+ printf0.awk \
+ printf0.ok \
+ printf1.awk \
+ printf1.ok \
+ printfbad1.awk \
+ printfbad1.ok \
+ printfloat.awk \
+ printlang.awk \
+ prmarscl.awk \
+ prmarscl.ok \
+ prmreuse.awk \
+ prmreuse.ok \
+ procinfs.awk \
+ procinfs.ok \
+ prt1eval.awk \
+ prt1eval.ok \
+ prtoeval.awk \
+ prtoeval.ok \
+ psx96sub.awk \
+ psx96sub.ok \
+ rand.awk \
+ rand.ok \
+ rebt8b1.awk \
+ rebt8b1.ok \
+ rebt8b2.awk \
+ rebt8b2.ok \
+ redfilnm.awk \
+ redfilnm.in \
+ redfilnm.ok \
+ regeq.awk \
+ regeq.in \
+ regeq.ok \
+ regtest.sh \
+ regx8bit.awk \
+ regx8bit.ok \
+ rebuf.awk \
+ rebuf.in \
+ rebuf.ok \
+ reindops.awk \
+ reindops.in \
+ reindops.ok \
+ reint.awk \
+ reint.in \
+ reint.ok \
+ reparse.awk \
+ reparse.in \
+ reparse.ok \
+ resplit.awk \
+ resplit.in \
+ resplit.ok \
+ rs.awk \
+ rs.in \
+ rs.ok \
+ rsnul1nl.awk \
+ rsnul1nl.in \
+ rsnul1nl.ok \
+ rsnulbig.ok \
+ rsnulbig2.ok \
+ rsstart1.awk \
+ rsstart1.in \
+ rsstart1.ok \
+ rsstart2.awk \
+ rsstart2.ok \
+ rsstart3.ok \
+ rstest1.awk \
+ rstest1.ok \
+ rstest2.awk \
+ rstest2.ok \
+ rstest3.awk \
+ rstest3.ok \
+ rstest4.awk \
+ rstest4.ok \
+ rstest5.awk \
+ rstest5.ok \
+ rstest6.awk \
+ rstest6.in \
+ rstest6.ok \
+ rswhite.awk \
+ rswhite.in \
+ rswhite.ok \
+ scalar.awk \
+ scalar.ok \
+ sclforin.awk \
+ sclforin.ok \
+ sclifin.awk \
+ sclifin.ok \
+ shadow.awk \
+ shadow.ok \
+ sort1.awk \
+ sort1.ok \
+ sortempty.awk \
+ sortempty.ok \
+ space.ok \
+ splitargv.awk \
+ splitargv.in \
+ splitargv.ok \
+ splitarr.awk \
+ splitarr.ok \
+ splitdef.awk \
+ splitdef.ok \
+ splitvar.awk \
+ splitvar.in \
+ splitvar.ok \
+ splitwht.awk \
+ splitwht.ok \
+ sprintfc.awk \
+ sprintfc.in \
+ sprintfc.ok \
+ strcat1.awk \
+ strcat1.ok \
+ strtod.awk \
+ strtod.in \
+ strtod.ok \
+ strtonum.awk \
+ strtonum.ok \
+ strftime.awk \
+ strftlng.awk \
+ strftlng.ok \
+ subamp.awk \
+ subamp.in \
+ subamp.ok \
+ subsepnm.awk \
+ subsepnm.ok \
+ subslash.awk \
+ subslash.ok \
+ substr.awk \
+ substr.ok \
+ swaplns.awk \
+ swaplns.in \
+ swaplns.ok \
+ switch2.awk \
+ synerr1.awk \
+ synerr1.ok \
+ tradanch.awk \
+ tradanch.in \
+ tradanch.ok \
+ tweakfld.awk \
+ tweakfld.in \
+ tweakfld.ok \
+ uninit2.awk \
+ uninit2.ok \
+ uninit3.awk \
+ uninit3.ok \
+ uninit4.awk \
+ uninit4.ok \
+ uninitialized.awk \
+ uninitialized.ok \
+ unterm.awk \
+ unterm.ok \
+ whiny.awk \
+ whiny.in \
+ whiny.ok \
+ wjposer1.awk \
+ wjposer1.in \
+ wjposer1.ok \
+ zeroe0.awk \
+ zeroe0.ok \
+ zeroflag.awk \
+ zeroflag.ok
+
+TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl
+
+# Get rid of core files when cleaning
+CLEANFILES = core core.*
+
+# try to keep these sorted
+BASIC_TESTS = addcomma anchgsub argarray arrayparm arrayref arrymem1 \
+ arrayprm2 arrayprm3 arryref2 arryref3 arryref4 arryref5 arynasty \
+ arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
+ aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
+ clsflnam compare compare2 concat1 concat2 concat3 convfmt datanonl defref \
+ delarprm delarpm2 delfunc dynlj eofsplit exitval1 exitval2 fldchg fldchgnf fmttest fnamedat \
+ fnarray fnarray2 fnarydel fnaryscl fnasgnm fnmisc fnparydl \
+ fordel forsimp fsbs fsspcoln fsrs fstabplus funsemnl funsmnam funstack getline \
+ getline2 getline3 getlnbuf getnr2tb getnr2tm gsubasgn gsubtest \
+ gsubtst2 gsubtst3 gsubtst4 gsubtst5 hex hsprint inputred intest \
+ intprec iobug1 leaddig leadnl litoct longsub longwrds manglprm math membug1 \
+ messages minusstr mmap8k nasty nasty2 negexp nested nfldstr \
+ nfneg nfset nlfldsep nlinstr nlstrina noeffect nofmtch noloop1 \
+ noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
+ ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup paramtyp \
+ parseme pcntplus prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval psx96sub rand rebt8b1 rebt8b2 redfilnm regeq \
+ reindops reparse resplit rs rsnul1nl rsnulbig rsnulbig2 rstest1 \
+ rstest2 rstest3 rstest4 rstest5 rswhite scalar sclforin sclifin \
+ sortempty splitargv splitarr splitdef splitvar splitwht sprintfc \
+ strcat1 strtod subamp subsepnm subslash substr swaplns synerr1 tradanch \
+ tweakfld uninit2 uninit3 uninit4 uninitialized unterm wjposer1 \
+ zeroe0 zeroflag
+
+UNIX_TESTS = fflush getlnhd pid pipeio1 pipeio2 poundbang space strftlng
+GAWK_EXT_TESTS = argtest asort asorti backw badargs clos1way fieldwdth fsfwfs \
+ gensub gensub2 gnuops2 gnuops3 gnureops icasefs icasers igncdym igncfs ignrcase \
+ ignrcas2 lint match1 match2 manyfiles nondec nondec2 posix procinfs \
+ printfbad1 regx8bit rebuf reint rsstart1 rsstart2 rsstart3 \
+ rstest6 shadow sort1 strtonum strftime whiny
+
+EXTRA_TESTS = regtest inftest
+INET_TESTS = inetechu inetecht inetdayu inetdayt
+
+# List of the tests which should be run with --lint option:
+NEED_LINT = defref noeffect nofmtch shadow uninit2 uninit3 uninit4 uninitialized
+
+# List of the files that appear in manual tests or are for reserve testing:
+GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk switch2.awk
+CMP = cmp
+AWKPROG = ../gawk$(EXEEXT)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Maketests $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-info-am
+
+
+# Message stuff is to make it a little easier to follow.
+# Make the pass-fail last and dependent on others to avoid
+# spurious errors if `make -j' in effect.
+check: msg \
+ printlang \
+ basic-msg-start basic basic-msg-end \
+ unix-msg-start unix-tests unix-msg-end \
+ extend-msg-start gawk-extensions extend-msg-end
+ @$(MAKE) pass-fail
+
+basic: $(BASIC_TESTS)
+
+unix-tests: $(UNIX_TESTS)
+
+gawk-extensions: $(GAWK_EXT_TESTS)
+
+extra: $(EXTRA_TESTS) inet
+
+inet: inetmesg $(INET_TESTS)
+
+msg::
+ @echo ''
+ @echo 'Any output from "cmp" is bad news, although some differences'
+ @echo 'in floating point values are probably benign -- in particular,'
+ @echo 'some systems may omit a leading zero and the floating point'
+ @echo 'precision may lead to slightly different output in a few cases.'
+
+printlang::
+ @$(AWK) -f $(srcdir)/printlang.awk
+
+basic-msg-start:
+ @echo "======== Starting basic tests ========"
+
+basic-msg-end:
+ @echo "======== Done with basic tests ========"
+
+unix-msg-start:
+ @echo "======== Starting Unix tests ========"
+
+unix-msg-end:
+ @echo "======== Done with Unix tests ========"
+
+extend-msg-start:
+ @echo "======== Starting gawk extension tests ========"
+
+extend-msg-end:
+ @echo "======== Done with gawk extension tests ========"
+
+# This test is a PITA because increasingly, /tmp is getting
+# mounted noexec. So, we'll test it locally. Sigh.
+#
+# More PITA; some systems have medium short limits on #! paths,
+# so this can still fail
+poundbang::
+ @echo $@
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @chmod +x ./_pbd.awk
+ @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ then : ; \
+ else \
+ sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ chmod +x ./_pbd.awk ; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@`; \
+ fi
+ @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+
+messages::
+ @echo $@
+ @$(AWK) -f $(srcdir)/messages.awk >out2 2>out3
+ @-$(CMP) $(srcdir)/out1.ok out1 && $(CMP) $(srcdir)/out2.ok out2 && $(CMP) $(srcdir)/out3.ok out3 && rm -f out1 out2 out3
+
+argarray::
+ @echo $@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) cp $(srcdir)/argarray.in . ;; \
+ esac
+ @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
+ @case $(srcdir) in \
+ .) : ;; \
+ *) rm -f ./argarray.in ;; \
+ esac
+ @-$(CMP) $(srcdir)/argarray.ok _$@ && rm -f _$@
+
+regtest::
+ @echo 'Some of the output from regtest is very system specific, do not'
+ @echo 'be distressed if your output differs from that distributed.'
+ @echo 'Manual inspection is called for.'
+ AWK=`pwd`/$(AWK) $(srcdir)/regtest.sh
+
+manyfiles::
+ @echo manyfiles
+ @rm -rf junk
+ @mkdir junk
+ @$(AWK) 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >_$@
+ @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
+ @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare::
+ @echo $@
+ @$(AWK) -f $(srcdir)/compare.awk 0 1 $(srcdir)/compare.in >_$@
+ @-$(CMP) $(srcdir)/compare.ok _$@ && rm -f _$@
+
+inftest::
+ @echo $@
+ @echo This test is very machine specific...
+ @$(AWK) -f $(srcdir)/inftest.awk | sed "s/inf/Inf/g" >_$@
+ @-$(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@
+
+getline2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
+ @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+
+awkpath::
+ @echo $@
+ @AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
+ @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+
+argtest::
+ @echo $@
+ @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
+ @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+
+badargs::
+ @echo $@
+ @-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
+ @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+
+nonl::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+
+strftime::
+ @echo This test could fail on slow machines or on a minute boundary,
+ @echo so if it does, double check the actual results:
+ @echo $@
+ @GAWKLOCALE=C; export GAWKLOCALE; \
+ TZ=GMT0; export TZ; \
+ (LC_ALL=C date) | $(AWK) -v OUTPUT=_$@ -f $(srcdir)/strftime.awk
+ @-$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0
+
+litoct::
+ @echo $@
+ @echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
+ @-$(CMP) $(srcdir)/litoct.ok _$@ && rm -f _$@
+
+fflush::
+ @echo $@
+ @$(srcdir)/fflush.sh >_$@
+ @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+
+tweakfld::
+ @echo $@
+ @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @rm -f errors.cleanup
+ @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+
+mmap8k::
+ @echo $@
+ @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
+ @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+
+tradanch::
+ @echo $@
+ @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
+ @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+
+# AIX /bin/sh exec's the last command in a list, therefore issue a ":"
+# command so that pid.sh is fork'ed as a child before being exec'ed.
+pid::
+ @echo pid
+ @AWKPATH=$(srcdir) AWK=$(AWKPROG) $(SHELL) $(srcdir)/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) $(srcdir)/pid.ok _`basename $@` && rm -f _`basename $@` _`basename $@`.in
+
+strftlng::
+ @echo $@
+ @TZ=UTC; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@
+ @if $(CMP) $(srcdir)/strftlng.ok _$@ >/dev/null 2>&1 ; then : ; else \
+ TZ=UTC0; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@ ; \
+ fi
+ @-$(CMP) $(srcdir)/strftlng.ok _$@ && rm -f _$@
+
+nors::
+ @echo $@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - $(srcdir)/nors.in > _$@
+ @-$(CMP) $(srcdir)/nors.ok _$@ && rm -f _$@
+
+reint::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
+ @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+
+pipeio1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @rm -f test1 test2
+ @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+
+pipeio2::
+ @echo $@
+ @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
+ @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+
+clobber::
+ @echo $@
+ @$(AWK) -f $(srcdir)/clobber.awk >_$@
+ @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @rm -f seq
+
+arynocls::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -v INPUT=$(srcdir)/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) $(srcdir)/arynocls.ok _$@ && rm -f _$@
+
+getlnbuf::
+ @echo $@
+ @-AWKPATH=$(srcdir) $(AWK) -f getlnbuf.awk $(srcdir)/getlnbuf.in > _$@
+ @-AWKPATH=$(srcdir) $(AWK) -f gtlnbufv.awk $(srcdir)/getlnbuf.in > _2$@
+ @-$(CMP) $(srcdir)/getlnbuf.ok _$@ && $(CMP) $(srcdir)/getlnbuf.ok _2$@ && rm -f _$@ _2$@
+
+inetmesg::
+ @echo These tests only work if your system supports the services
+ @echo "'discard'" at port 9 and "'daytimed'" at port 13. Check your
+ @echo file /etc/services and do "'netstat -a'".
+
+inetechu::
+ @echo This test is for establishing UDP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/udp/0/127.0.0.1/9"}'
+
+inetecht::
+ @echo This test is for establishing TCP connections
+ @$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
+
+inetdayu::
+ @echo This test is for bidirectional UDP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/udp/0/127.0.0.1/13"; \
+ "/inet/udp/0/127.0.0.1/13" |& getline; print $0}'
+
+inetdayt::
+ @echo This test is for bidirectional TCP transmission
+ @$(AWK) 'BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13"; \
+ "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}'
+
+redfilnm::
+ @echo $@
+ @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
+ @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+
+leaddig::
+ @echo $@
+ @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
+ @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+
+gsubtst3::
+ @echo $@
+ @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+space::
+ @echo $@
+ @$(AWK) -f ' ' $(srcdir)/space.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf0::
+ @echo $@
+ @$(AWK) --posix -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig::
+ @echo $@
+ @ : Suppose that block size for pipe is at most 128kB:
+ @$(AWK) 'BEGIN { for (i = 1; i <= 128*64+1; i++) print "abcdefgh123456\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" }; { print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END{ print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnulbig2::
+ @echo $@
+ @$(AWK) 'BEGIN { ORS = ""; n = "\n"; for (i = 1; i <= 10; i++) n = (n n); \
+ for (i = 1; i <= 128; i++) print n; print "abc\n" }' 2>&1 | \
+ $(AWK) 'BEGIN { RS = ""; ORS = "\n\n" };{ print }' 2>&1 | \
+ $(AWK) '/^[^a]/; END { print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+whiny::
+ @echo $@
+ @WHINY_USERS=1 $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcas2::
+ @echo $@
+ @GAWKLOCALE=en_US ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subamp::
+ @echo $@
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# This test makes sure gawk exits with a zero code.
+# Thus, unconditionally generate the exit code.
+exitval1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/exitval1.awk >_$@ 2>&1; echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsspcoln::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk 'FS=[ :]+' $(srcdir)/$@.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart1::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart2::
+ @echo $@
+ @$(AWK) -f $(srcdir)/$@.awk $(srcdir)/rsstart1.in >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsstart3::
+ @echo $@
+ @head $(srcdir)/rsstart1.in | $(AWK) -f $(srcdir)/rsstart2.awk >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nondec2::
+ @echo $@
+ @$(AWK) --non-decimal-data -v a=0x1 -f $(srcdir)/$@.awk >_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+Gt-dummy:
+# file Maketests, generated from Makefile.am by the Gentests program
+addcomma:
+ @echo addcomma
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+anchgsub:
+ @echo anchgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayparm:
+ @echo arrayparm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayref:
+ @echo arrayref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrymem1:
+ @echo arrymem1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm2:
+ @echo arrayprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm3:
+ @echo arrayprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref2:
+ @echo arryref2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref3:
+ @echo arryref3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref4:
+ @echo arryref4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref5:
+ @echo arryref5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arynasty:
+ @echo arynasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm1:
+ @echo aryprm1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm2:
+ @echo aryprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm3:
+ @echo aryprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm4:
+ @echo aryprm4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm5:
+ @echo aryprm5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm6:
+ @echo aryprm6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm7:
+ @echo aryprm7
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm8:
+ @echo aryprm8
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arysubnm:
+ @echo arysubnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asgext:
+ @echo asgext
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+back89:
+ @echo back89
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backgsub:
+ @echo backgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+childin:
+ @echo childin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clsflnam:
+ @echo clsflnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare2:
+ @echo compare2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat1:
+ @echo concat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat2:
+ @echo concat2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat3:
+ @echo concat3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+convfmt:
+ @echo convfmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+datanonl:
+ @echo datanonl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+defref:
+ @echo defref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarprm:
+ @echo delarprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarpm2:
+ @echo delarpm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delfunc:
+ @echo delfunc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+dynlj:
+ @echo dynlj
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+eofsplit:
+ @echo eofsplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+exitval2:
+ @echo exitval2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchg:
+ @echo fldchg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchgnf:
+ @echo fldchgnf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fmttest:
+ @echo fmttest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnamedat:
+ @echo fnamedat
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray:
+ @echo fnarray
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray2:
+ @echo fnarray2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarydel:
+ @echo fnarydel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnaryscl:
+ @echo fnaryscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnasgnm:
+ @echo fnasgnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnmisc:
+ @echo fnmisc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnparydl:
+ @echo fnparydl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fordel:
+ @echo fordel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+forsimp:
+ @echo forsimp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsbs:
+ @echo fsbs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsrs:
+ @echo fsrs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fstabplus:
+ @echo fstabplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsemnl:
+ @echo funsemnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsmnam:
+ @echo funsmnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funstack:
+ @echo funstack
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline:
+ @echo getline
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline3:
+ @echo getline3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tb:
+ @echo getnr2tb
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tm:
+ @echo getnr2tm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubasgn:
+ @echo gsubasgn
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtest:
+ @echo gsubtest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst2:
+ @echo gsubtst2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst4:
+ @echo gsubtst4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst5:
+ @echo gsubtst5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hex:
+ @echo hex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hsprint:
+ @echo hsprint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+inputred:
+ @echo inputred
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intest:
+ @echo intest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intprec:
+ @echo intprec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+iobug1:
+ @echo iobug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+leadnl:
+ @echo leadnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longsub:
+ @echo longsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longwrds:
+ @echo longwrds
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+manglprm:
+ @echo manglprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+math:
+ @echo math
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+membug1:
+ @echo membug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+minusstr:
+ @echo minusstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty:
+ @echo nasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty2:
+ @echo nasty2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+negexp:
+ @echo negexp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nested:
+ @echo nested
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfldstr:
+ @echo nfldstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfneg:
+ @echo nfneg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfset:
+ @echo nfset
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlfldsep:
+ @echo nlfldsep
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlinstr:
+ @echo nlinstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlstrina:
+ @echo nlstrina
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noeffect:
+ @echo noeffect
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nofmtch:
+ @echo nofmtch
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop1:
+ @echo noloop1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop2:
+ @echo noloop2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noparms:
+ @echo noparms
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nulrsend:
+ @echo nulrsend
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numindex:
+ @echo numindex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numsubstr:
+ @echo numsubstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+octsub:
+ @echo octsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmt:
+ @echo ofmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtbig:
+ @echo ofmtbig
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtfidl:
+ @echo ofmtfidl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmts:
+ @echo ofmts
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+onlynl:
+ @echo onlynl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnidx:
+ @echo opasnidx
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnslf:
+ @echo opasnslf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramdup:
+ @echo paramdup
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramtyp:
+ @echo paramtyp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+parseme:
+ @echo parseme
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+pcntplus:
+ @echo pcntplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prdupval:
+ @echo prdupval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prec:
+ @echo prec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf1:
+ @echo printf1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmarscl:
+ @echo prmarscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmreuse:
+ @echo prmreuse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prt1eval:
+ @echo prt1eval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prtoeval:
+ @echo prtoeval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+psx96sub:
+ @echo psx96sub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rand:
+ @echo rand
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b1:
+ @echo rebt8b1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b2:
+ @echo rebt8b2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regeq:
+ @echo regeq
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reindops:
+ @echo reindops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reparse:
+ @echo reparse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+resplit:
+ @echo resplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rs:
+ @echo rs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnul1nl:
+ @echo rsnul1nl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest1:
+ @echo rstest1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest2:
+ @echo rstest2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest3:
+ @echo rstest3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest4:
+ @echo rstest4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest5:
+ @echo rstest5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rswhite:
+ @echo rswhite
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+scalar:
+ @echo scalar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclforin:
+ @echo sclforin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclifin:
+ @echo sclifin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sortempty:
+ @echo sortempty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitargv:
+ @echo splitargv
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitarr:
+ @echo splitarr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitdef:
+ @echo splitdef
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitvar:
+ @echo splitvar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitwht:
+ @echo splitwht
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sprintfc:
+ @echo sprintfc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strcat1:
+ @echo strcat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtod:
+ @echo strtod
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subsepnm:
+ @echo subsepnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subslash:
+ @echo subslash
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+substr:
+ @echo substr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+swaplns:
+ @echo swaplns
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+synerr1:
+ @echo synerr1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit2:
+ @echo uninit2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit3:
+ @echo uninit3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit4:
+ @echo uninit4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninitialized:
+ @echo uninitialized
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+unterm:
+ @echo unterm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+wjposer1:
+ @echo wjposer1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroe0:
+ @echo zeroe0
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroflag:
+ @echo zeroflag
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getlnhd:
+ @echo getlnhd
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asort:
+ @echo asort
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asorti:
+ @echo asorti
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backw:
+ @echo backw
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo clos1way
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fieldwdth:
+ @echo fieldwdth
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsfwfs:
+ @echo fsfwfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub:
+ @echo gensub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub2:
+ @echo gensub2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops2:
+ @echo gnuops2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops3:
+ @echo gnuops3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnureops:
+ @echo gnureops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasefs:
+ @echo icasefs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasers:
+ @echo icasers
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncdym:
+ @echo igncdym
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncfs:
+ @echo igncfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcase:
+ @echo ignrcase
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+lint:
+ @echo lint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match1:
+ @echo match1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match2:
+ @echo match2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nondec:
+ @echo nondec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+posix:
+ @echo posix
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+procinfs:
+ @echo procinfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printfbad1:
+ @echo printfbad1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regx8bit:
+ @echo regx8bit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebuf:
+ @echo rebuf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest6:
+ @echo rstest6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+shadow:
+ @echo shadow
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sort1:
+ @echo sort1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtonum:
+ @echo strtonum
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# end of file Maketests
+
+# Targets generated for other tests:
+
+$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
+ $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" *.awk *.in > $(srcdir)/Maketests
+
+clean:
+ rm -fr _* core core.* junk out1 out2 out3 strftime.ok test1 test2 seq *~
+
+# An attempt to print something that can be grepped for in build logs
+pass-fail:
+ @COUNT=`ls _* 2>/dev/null | wc -l` ; \
+ if test $$COUNT = 0 ; \
+ then echo ALL TESTS PASSED ; \
+ else echo $$COUNT TESTS FAILED ; \
+ fi
+
+# This target for my convenience to look at all the results
+diffout:
+ for i in _* ; \
+ do \
+ echo ============== $$i ============= ; \
+ diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ done | more
+
+# This target is for testing with electric fence.
+efence:
+ for i in $$(ls _* | sed 's;_\(.*\);\1;') ; \
+ do \
+ bad=$$(wc -l < _$$i) \
+ ok=$$(wc -l < $$i.ok) ; \
+ if (( $$bad == $$ok + 2 )) ; \
+ then \
+ rm _$$i ; \
+ fi ; \
+ done
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Gt-dummy:
+# file Maketests, generated from Makefile.am by the Gentests program
+addcomma:
+ @echo addcomma
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+anchgsub:
+ @echo anchgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayparm:
+ @echo arrayparm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayref:
+ @echo arrayref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrymem1:
+ @echo arrymem1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm2:
+ @echo arrayprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arrayprm3:
+ @echo arrayprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref2:
+ @echo arryref2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref3:
+ @echo arryref3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref4:
+ @echo arryref4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arryref5:
+ @echo arryref5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arynasty:
+ @echo arynasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm1:
+ @echo aryprm1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm2:
+ @echo aryprm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm3:
+ @echo aryprm3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm4:
+ @echo aryprm4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm5:
+ @echo aryprm5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm6:
+ @echo aryprm6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm7:
+ @echo aryprm7
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+aryprm8:
+ @echo aryprm8
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+arysubnm:
+ @echo arysubnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asgext:
+ @echo asgext
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+back89:
+ @echo back89
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backgsub:
+ @echo backgsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+childin:
+ @echo childin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clsflnam:
+ @echo clsflnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+compare2:
+ @echo compare2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat1:
+ @echo concat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat2:
+ @echo concat2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+concat3:
+ @echo concat3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+convfmt:
+ @echo convfmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+datanonl:
+ @echo datanonl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+defref:
+ @echo defref
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarprm:
+ @echo delarprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delarpm2:
+ @echo delarpm2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+delfunc:
+ @echo delfunc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+dynlj:
+ @echo dynlj
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+eofsplit:
+ @echo eofsplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+exitval2:
+ @echo exitval2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchg:
+ @echo fldchg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fldchgnf:
+ @echo fldchgnf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fmttest:
+ @echo fmttest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnamedat:
+ @echo fnamedat
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray:
+ @echo fnarray
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarray2:
+ @echo fnarray2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnarydel:
+ @echo fnarydel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnaryscl:
+ @echo fnaryscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnasgnm:
+ @echo fnasgnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnmisc:
+ @echo fnmisc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fnparydl:
+ @echo fnparydl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fordel:
+ @echo fordel
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+forsimp:
+ @echo forsimp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsbs:
+ @echo fsbs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsrs:
+ @echo fsrs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fstabplus:
+ @echo fstabplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsemnl:
+ @echo funsemnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funsmnam:
+ @echo funsmnam
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+funstack:
+ @echo funstack
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline:
+ @echo getline
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getline3:
+ @echo getline3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tb:
+ @echo getnr2tb
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getnr2tm:
+ @echo getnr2tm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubasgn:
+ @echo gsubasgn
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtest:
+ @echo gsubtest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst2:
+ @echo gsubtst2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst4:
+ @echo gsubtst4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gsubtst5:
+ @echo gsubtst5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hex:
+ @echo hex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+hsprint:
+ @echo hsprint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+inputred:
+ @echo inputred
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intest:
+ @echo intest
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+intprec:
+ @echo intprec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+iobug1:
+ @echo iobug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+leadnl:
+ @echo leadnl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longsub:
+ @echo longsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+longwrds:
+ @echo longwrds
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+manglprm:
+ @echo manglprm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+math:
+ @echo math
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+membug1:
+ @echo membug1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+minusstr:
+ @echo minusstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty:
+ @echo nasty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nasty2:
+ @echo nasty2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+negexp:
+ @echo negexp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nested:
+ @echo nested
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfldstr:
+ @echo nfldstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfneg:
+ @echo nfneg
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nfset:
+ @echo nfset
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlfldsep:
+ @echo nlfldsep
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlinstr:
+ @echo nlinstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nlstrina:
+ @echo nlstrina
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noeffect:
+ @echo noeffect
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nofmtch:
+ @echo nofmtch
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop1:
+ @echo noloop1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noloop2:
+ @echo noloop2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+noparms:
+ @echo noparms
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nulrsend:
+ @echo nulrsend
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numindex:
+ @echo numindex
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+numsubstr:
+ @echo numsubstr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+octsub:
+ @echo octsub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmt:
+ @echo ofmt
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtbig:
+ @echo ofmtbig
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmtfidl:
+ @echo ofmtfidl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ofmts:
+ @echo ofmts
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+onlynl:
+ @echo onlynl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnidx:
+ @echo opasnidx
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+opasnslf:
+ @echo opasnslf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramdup:
+ @echo paramdup
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+paramtyp:
+ @echo paramtyp
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+parseme:
+ @echo parseme
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+pcntplus:
+ @echo pcntplus
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prdupval:
+ @echo prdupval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prec:
+ @echo prec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printf1:
+ @echo printf1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmarscl:
+ @echo prmarscl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prmreuse:
+ @echo prmreuse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prt1eval:
+ @echo prt1eval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+prtoeval:
+ @echo prtoeval
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+psx96sub:
+ @echo psx96sub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rand:
+ @echo rand
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b1:
+ @echo rebt8b1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebt8b2:
+ @echo rebt8b2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regeq:
+ @echo regeq
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reindops:
+ @echo reindops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+reparse:
+ @echo reparse
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+resplit:
+ @echo resplit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rs:
+ @echo rs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rsnul1nl:
+ @echo rsnul1nl
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest1:
+ @echo rstest1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest2:
+ @echo rstest2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest3:
+ @echo rstest3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest4:
+ @echo rstest4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest5:
+ @echo rstest5
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rswhite:
+ @echo rswhite
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+scalar:
+ @echo scalar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclforin:
+ @echo sclforin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sclifin:
+ @echo sclifin
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sortempty:
+ @echo sortempty
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitargv:
+ @echo splitargv
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitarr:
+ @echo splitarr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitdef:
+ @echo splitdef
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitvar:
+ @echo splitvar
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+splitwht:
+ @echo splitwht
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sprintfc:
+ @echo sprintfc
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strcat1:
+ @echo strcat1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtod:
+ @echo strtod
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subsepnm:
+ @echo subsepnm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+subslash:
+ @echo subslash
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+substr:
+ @echo substr
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+swaplns:
+ @echo swaplns
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+synerr1:
+ @echo synerr1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit2:
+ @echo uninit2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit3:
+ @echo uninit3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninit4:
+ @echo uninit4
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+uninitialized:
+ @echo uninitialized
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+unterm:
+ @echo unterm
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+wjposer1:
+ @echo wjposer1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroe0:
+ @echo zeroe0
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+zeroflag:
+ @echo zeroflag
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+getlnhd:
+ @echo getlnhd
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asort:
+ @echo asort
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+asorti:
+ @echo asorti
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+backw:
+ @echo backw
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo clos1way
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fieldwdth:
+ @echo fieldwdth
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+fsfwfs:
+ @echo fsfwfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub:
+ @echo gensub
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gensub2:
+ @echo gensub2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops2:
+ @echo gnuops2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnuops3:
+ @echo gnuops3
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+gnureops:
+ @echo gnureops
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasefs:
+ @echo icasefs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+icasers:
+ @echo icasers
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncdym:
+ @echo igncdym
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+igncfs:
+ @echo igncfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+ignrcase:
+ @echo ignrcase
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+lint:
+ @echo lint
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match1:
+ @echo match1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+match2:
+ @echo match2
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+nondec:
+ @echo nondec
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+posix:
+ @echo posix
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+procinfs:
+ @echo procinfs
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+printfbad1:
+ @echo printfbad1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+regx8bit:
+ @echo regx8bit
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rebuf:
+ @echo rebuf
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+rstest6:
+ @echo rstest6
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+shadow:
+ @echo shadow
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+sort1:
+ @echo sort1
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+strtonum:
+ @echo strtonum
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+# end of file Maketests
--- /dev/null
+Mon Jan 22 13:08:58 EST 1996
+
+This directory contains the tests for gawk. The tests use the
+following conventions.
+
+Given some aspect of gawk named `foo', there will be one or more
+of the following files:
+
+foo.awk --- actual code for the test if not inline in the Makefile
+foo.in --- the data for the test, if it needs data
+foo.ok --- the expected results
+_foo --- the actual results; generated at run time
+
+The _foo file will be left around if a test fails, allowing you to
+compare actual and expected results, in case they differ.
+
+If they do differ (other than strftime.ok and _strftime!), send in a
+bug report. See the manual for the bug report procedure.
--- /dev/null
+# addcomma - put commas in numbers
+# input: a number per line
+# output: the input number followed by
+# the number with commas and two decimal places
+
+{ printf("%-12s %20s\n", $0, addcomma($0)) }
+
+function addcomma(x, num) {
+ if (x < 0)
+ return "-" addcomma(-x)
+ num = sprintf("%.2f", x) # num is dddddd.dd
+ while (num ~ /[0-9][0-9][0-9][0-9]/)
+ sub(/[0-9][0-9][0-9][,.]/, ",&", num)
+ return num
+}
--- /dev/null
+0
+-1
+-12.34
+12345
+-1234567.89
+-123.
+-123456
--- /dev/null
+0 0.00
+-1 -1.00
+-12.34 -12.34
+12345 12,345.00
+-1234567.89 -1,234,567.89
+-123. -123.00
+-123456 -123,456.00
--- /dev/null
+{ gsub(/^[ ]*/, "", $0) ; print }
--- /dev/null
+ This is a test, this is only a test.
--- /dev/null
+This is a test, this is only a test.
--- /dev/null
+BEGIN {
+ argn = " argument" (ARGC > 1 ? "s" : "")
+ are = ARGC > 1 ? "are" : "is"
+ print "here we have " ARGC argn
+ print "which " are
+ for (x = 0; x < ARGC; x++)
+ print "\t", ARGV[x]
+ print "Environment variable TEST=" ENVIRON["TEST"]
+ print "and the current input file is called \"" FILENAME "\""
+}
+
+FNR == 1 {
+ print "in main loop, this input file is known as \"" FILENAME "\""
+}
--- /dev/null
+this is a simple test file
--- /dev/null
+here we have 3 arguments
+which are
+ gawk
+ ./argarray.in
+ -
+Environment variable TEST=
+and the current input file is called ""
+in main loop, this input file is known as "./argarray.in"
+in main loop, this input file is known as "-"
--- /dev/null
+BEGIN {
+ for (i = 0; i < ARGC; i++)
+ printf("ARGV[%d] = %s\n", i, ARGV[i])
+}
--- /dev/null
+ARGV[0] = gawk
+ARGV[1] = -x
+ARGV[2] = -y
+ARGV[3] = abc
--- /dev/null
+#
+# Test program from:
+#
+# Date: Tue, 21 Feb 95 16:09:29 EST
+# From: emory!blackhawk.com!aaron (Aaron Sosnick)
+#
+BEGIN {
+ foo[1]=1;
+ foo[2]=2;
+ bug1(foo);
+}
+function bug1(i) {
+ for (i in foo) {
+ bug2(i);
+ delete foo[i];
+ print i,1,bot[1];
+ }
+}
+function bug2(arg) {
+ bot[arg]=arg;
+}
--- /dev/null
+gawk: arrayparm.awk:18: fatal: attempt to use array `i (from foo)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+# From spcecdt@armory.com Wed Apr 30 11:08:48 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h3U7uZWr015489
+# for <arnold@localhost>; Wed, 30 Apr 2003 11:08:48 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Wed, 30 Apr 2003 11:08:48 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Wed Apr 30 11:05:01 2003)
+# X-From_: spcecdt@armory.com Wed Apr 30 04:06:46 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h3U16iv04111 for <arobbins@actcom.co.il>;
+# Wed, 30 Apr 2003 04:06:45 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h3U16nEv009589
+# for <arobbins@actcom.co.il>; Wed, 30 Apr 2003 04:06:50 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7/8.11.6) with ESMTP id h3U16gj29182
+# for <arnold@skeeve.com>; Tue, 29 Apr 2003 21:06:42 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.10)
+# id 19Ag3W-00029w-00
+# for bug-gawk@gnu.org; Tue, 29 Apr 2003 21:06:42 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13)
+# id 19Ag1V-0001AN-00
+# for bug-gawk@gnu.org; Tue, 29 Apr 2003 21:04:39 -0400
+# Received: from deepthought.armory.com ([192.122.209.42] helo=armory.com)
+# by monty-python.gnu.org with smtp (Exim 4.10.13)
+# id 19Ag1V-0001A3-00
+# for bug-gawk@gnu.org; Tue, 29 Apr 2003 21:04:37 -0400
+# Date: Tue, 29 Apr 2003 18:04:35 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: bug-gawk@gnu.org
+# Subject: gawk 3.1.2a bug
+# Message-ID: <20030430010434.GA4278@armory.com>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-Spam-Status: No, hits=-7.2 required=5.0
+# tests=SIGNATURE_SHORT_DENSE,SPAM_PHRASE_00_01,USER_AGENT,
+# USER_AGENT_MUTT
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# gawk-3.1.2a 'BEGIN {foo(bar)};function foo(baz){split("x",baz)}'
+# gawk-3.1.2a: cmd. line:1: fatal: split: second argument is not an array
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
+BEGIN {
+ foo(bar)
+}
+
+function foo(baz)
+{
+ split("x", baz)
+}
--- /dev/null
+# From spcecdt@armory.com Fri May 2 13:24:46 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h42AChum021950
+# for <arnold@localhost>; Fri, 2 May 2003 13:24:46 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Fri, 02 May 2003 13:24:46 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Fri May 2 13:23:37 2003)
+# X-From_: spcecdt@armory.com Fri May 2 00:43:51 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h41Lhm500217 for <arobbins@actcom.co.il>;
+# Fri, 2 May 2003 00:43:49 +0300 (EET DST)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h41LiGcO022817
+# for <arobbins@actcom.co.il>; Fri, 2 May 2003 00:44:18 +0300
+# Received: from armory.com (deepthought.armory.com [192.122.209.42])
+# by f7.net (8.11.7/8.11.6) with SMTP id h41Lhj106516
+# for <arnold@skeeve.com>; Thu, 1 May 2003 17:43:46 -0400
+# Date: Thu, 1 May 2003 14:43:45 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: Aharon Robbins <arnold@skeeve.com>
+# Subject: Re: gawk 3.1.2a bug
+# Message-ID: <20030501214345.GA24615@armory.com>
+# References: <200305011738.h41Hcg76017565@localhost.localdomain>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# In-Reply-To: <200305011738.h41Hcg76017565@localhost.localdomain>
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# On Thu, May 01, 2003 at 08:38:42PM +0300, Aharon Robbins wrote:
+# > > That worked, thanks.
+# >
+# > Great. Your report motivated me to find everywhere such additional
+# > code ought to be needed. I think I did so. --Arnold
+#
+# Here's another one (perhaps fixed by your additional work):
+#
+BEGIN { foo(a) }
+function foo(a) { bar(a); print "" in a }
+function bar(a) { a[""]; }
+#
+# Prints 1 with gawk-3.1.1; 0 with 3.1.2a.
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
--- /dev/null
+ BEGIN { # foo[10] = 0 # put this line in and it will work
+ test(foo); print foo[1]
+ test2(foo2); print foo2[1]
+ }
+
+ function test(foo)
+ {
+ test2(foo)
+ }
+ function test2(bar)
+ {
+ bar[1] = 1
+ }
--- /dev/null
+# From spcecdt@armory.com Thu Jun 14 13:24:32 2001
+# Received: from mail.actcom.co.il [192.114.47.13]
+# by localhost with POP3 (fetchmail-5.5.0)
+# for arnold@localhost (single-drop); Thu, 14 Jun 2001 13:24:32 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Thu Jun 14 13:25:13 2001)
+# X-From_: spcecdt@armory.com Thu Jun 14 06:34:47 2001
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id GAA29661 for <arobbins@actcom.co.il>;
+# Thu, 14 Jun 2001 06:34:46 +0300 (EET DST)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from billohost.com (www.billohost.com [209.196.35.10])
+# by lmail.actcom.co.il (8.11.2/8.11.2) with ESMTP id f5E3YiO27337
+# for <arobbins@actcom.co.il>; Thu, 14 Jun 2001 06:34:45 +0300
+# Received: from fencepost.gnu.org (we-refuse-to-spy-on-our-users@fencepost.gnu.org [199.232.76.164])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id XAA02681
+# for <arnold@skeeve.com>; Wed, 13 Jun 2001 23:33:57 -0400
+# Received: from deepthought.armory.com ([192.122.209.42])
+# by fencepost.gnu.org with smtp (Exim 3.16 #1 (Debian))
+# id 15ANu2-00005C-00
+# for <bug-gawk@gnu.org>; Wed, 13 Jun 2001 23:34:38 -0400
+# Date: Wed, 13 Jun 2001 20:32:42 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: bug-gawk@gnu.org
+# Subject: gawk 3.1.0 bug
+# Message-ID: <20010613203242.A29975@armory.com>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# X-Mailer: Mutt 1.0.1i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# Status: RO
+#
+# Under SCO OpenServer 5.0.6a using gawk 3.1.0 compiled with gcc 2.95.2, this
+# program:
+
+ BEGIN {
+ f1(Procs,b)
+ print "test"
+ }
+
+ function f1(Procs,a) {
+ # a[""]
+ a[""] = "a" # ADR: Give it a value so can trace it
+ f2()
+ }
+
+ function f2() {
+ # b[""]
+ b[""] = "b" # ADR: Give it a value so can trace it
+ }
+
+ # ADR: 1/28/2003: Added this:
+ BEGIN { for (i in b) printf("b[\"%s\"] = \"%s\"\n", i, b[i]) }
+ # END ADR added.
+
+# gives:
+#
+# gawk: ./gtest:5: fatal error: internal error
+#
+# and dumps core.
+#
+# gdb gives me this stack backtrace:
+#
+# #0 0x80019943 in kill () from /usr/lib/libc.so.1
+# #1 0x8003e754 in abort () from /usr/lib/libc.so.1
+# #2 0x8062a87 in catchsig (sig=0, code=0) at main.c:947
+# #3 0x80053a0c in _sigreturn () from /usr/lib/libc.so.1
+# #4 0x80023d36 in cleanfree () from /usr/lib/libc.so.1
+# #5 0x80023156 in _real_malloc () from /usr/lib/libc.so.1
+# #6 0x80023019 in malloc () from /usr/lib/libc.so.1
+# #7 0x8053b95 in do_print (tree=0x0) at builtin.c:1336
+# #8 0x806b47c in interpret (tree=0x8084ee4) at eval.c:606
+# #9 0x806ad8d in interpret (tree=0x8084f0c) at eval.c:384
+# #10 0x806ad21 in interpret (tree=0x8084f5c) at eval.c:367
+# #11 0x8061d5b in main (argc=4, argv=0x80478ac) at main.c:506
+#
+# John
+# --
+# John DuBois spcecdt@armory.com. KC6QKZ/AE http://www.armory.com./~spcecdt/
+#
--- /dev/null
+test
+b[""] = "b"
--- /dev/null
+BEGIN {
+ foo(a)
+
+ for (i in a)
+ print i, a[i]
+}
+
+function foo(b)
+{
+ bar(b)
+ b[2] = "local"
+}
+
+function bar(c)
+{
+ a[3] = "global"
+ c[1] = "local2"
+}
--- /dev/null
+1 local2
+2 local
+3 global
--- /dev/null
+BEGIN {
+ foo(a)
+
+ for (i in a)
+ print i, a[i]
+}
+
+function foo(b)
+{
+ a[1] = "global"
+ b[2] = "local"
+ bar(b)
+}
+
+function bar(c)
+{
+ c = 12
+}
--- /dev/null
+gawk: arryref3.awk:17: fatal: attempt to use array `c (from b, from a)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ foo(a)
+
+ print a
+}
+
+function foo(b)
+{
+ a = "global"
+ b[2] = "local"
+# bar(b)
+}
+
+function bar(c)
+{
+ c = 12
+}
--- /dev/null
+gawk: arryref4.awk:10: fatal: attempt to use scalar parameter `b' as an array
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ foo(a)
+
+ print a
+}
+
+function foo(b)
+{
+ b[2] = "local"
+ a = "global"
+# bar(b)
+}
+
+function bar(c)
+{
+ c = 12
+}
--- /dev/null
+gawk: arryref5.awk:10: fatal: attempt to use array `a' in a scalar context
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ a = 12.153
+#print "-- stroring test[a]" > "/dev/stderr" ; fflush("/dev/stderr")
+ test[a] = "hi"
+#print "-- setting CONVFMT" > "/dev/stderr" ; fflush("/dev/stderr")
+ CONVFMT = "%.0f"
+#print "-- setting a" > "/dev/stderr" ; fflush("/dev/stderr")
+ a = 5
+#stopme()
+#print "-- starting loop" > "/dev/stderr" ; fflush("/dev/stderr")
+ for (i in test) {
+#print("-- i =", i) > "/dev/stderr" ; fflush("/dev/stderr");
+#printf("-- i = <%s>\n", i) > "/dev/stderr" ; fflush("/dev/stderr");
+ printf ("test[%s] = %s\n", i, test[i])
+ }
+}
--- /dev/null
+test[12.153] = hi
--- /dev/null
+#To: bug-gnu-utils@gnu.org
+#From: Kristján Jónasson <kristjan@decode.is>
+#Subject: Gawk bug
+#Cc: arnold@gnu.org
+#
+#Hi!
+#
+#The following seems to be a bug in gawk. I have tried as I could to
+#minimize the bug-causing program, so of course it does not seem to do
+#anything useful in its present form. The error message received is:
+#
+#gawk: test.awk:15: fatal error: internal error
+#Aborted
+#
+#Note that there is an attached file that the program reads, called "a". I
+#played with the program a fair bit and my feeling is that the error is
+#related with the delete statement, and not the reading of the file and the
+#close statement. At one point I was able to remove the file reading and
+#still obtain the error. If, for example, I remove the close statement and
+#make two copies of the file instead, (reading one copy in sub1 and the
+#other in sub2), the error still occurs.
+#
+#The operating system is Red Hat Linux, version 6.0, the gawk is version
+#3.0.4, and the gawk was obtained from an rpm file gawk-3.0.4-1.i386.rpm.
+#
+#The program is:
+#
+
+# Wed Mar 8 13:41:34 IST 2000
+# ADR: modified to use INPUT, so can set it from command line.
+# When run, no output is produced, but it shouldn't core
+# dump, either.
+#
+# The program bug is to not close the file in sub2.
+
+function sub1(x) {
+# while (getline < "a" == 1) i++
+ while (getline < INPUT == 1) i++
+# close("a")
+ close(INPUT)
+}
+
+function sub2(x) {
+ i=0
+ delete y
+# while (getline < "a" == 1) z[++i] = $1
+ while (getline < INPUT == 1) z[++i] = $1
+ for(i in z) y[i] = x[i] + z[i]
+}
+
+function sub3(x, y, z) {
+ sub2(x)
+ for(i=1; i<=4; i++) z[i] = y[i]
+}
+
+BEGIN {
+ sub1(x)
+ sub2(x)
+ sub3(x, y, z)
+}
+#
+#And the data file is:
+#
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+# 32.440 3.830 3.383700000000000 10.08 298 865
+#
+#
--- /dev/null
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
+ 32.440 3.830 3.383700000000000 10.08 298 865
--- /dev/null
+function f(a) {
+ if (3 in a)
+ print 7
+ a = 5
+}
+
+BEGIN {
+ f(arr)
+}
--- /dev/null
+gawk: aryprm1.awk:4: fatal: attempt to use array `a (from arr)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+function f(a) {
+ delete a
+ a *= 5
+}
+
+BEGIN {
+ f(arr)
+}
--- /dev/null
+gawk: aryprm2.awk:3: fatal: attempt to use array `a (from arr)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+function f(a, i) {
+ for (i in a)
+ delete a[i]
+ if (a == 0)
+ print 7
+}
+
+BEGIN {
+ f(arr)
+}
--- /dev/null
+gawk: aryprm3.awk:6: fatal: attempt to use array `a (from arr)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+function f(x){
+ x = 1
+}
+BEGIN {
+ f(a)
+ a[1]
+}
--- /dev/null
+gawk: aryprm4.awk:6: fatal: attempt to use scalar `a' as array
+EXIT CODE: 2
--- /dev/null
+function f(x){
+ x[1] = x
+}
+BEGIN {
+ f(a)
+}
--- /dev/null
+gawk: aryprm5.awk:2: fatal: attempt to use scalar parameter `x' as an array
+EXIT CODE: 2
--- /dev/null
+function f(x){
+ a
+ x[1] = 3
+}
+BEGIN {
+ f(a)
+}
--- /dev/null
+gawk: aryprm6.awk:3: fatal: attempt to use scalar parameter `x' as an array
+EXIT CODE: 2
--- /dev/null
+function f(x, y){
+ y[1] = x
+}
+BEGIN {
+ f(a, a)
+}
--- /dev/null
+gawk: aryprm7.awk:2: fatal: attempt to use scalar parameter `y' as an array
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ f(0, a) # nothing
+ f(1, a)
+}
+function f(i, a) {
+ if (i == 0) return
+ g(a, a)
+ pr(a)
+}
+function g(x, y) {
+ h(y, x, y)
+}
+function h(b, c, d) {
+ b[1] = 1
+ c[1] = 2 # rewrite
+ print b[1], d[1]
+ c[2] = 1
+ b[2] = 2 # should rewrite
+}
+function pr(x) {
+ print x[1], x[2]
+}
--- /dev/null
+BEGIN { n = 11 ; foo[n] = n; print (2 <= n) }
--- /dev/null
+{ print $3; $4 = "a"; print }
--- /dev/null
+1 2 3
+1
+1 2 3 4
--- /dev/null
+3
+1 2 3 a
+
+1 a
+3
+1 2 3 a
--- /dev/null
+function init(a)
+{
+ a[1] = "aardvark"
+ a[2] = "animal"
+ a[3] = "zebra"
+ a[4] = "zoo"
+ a[5] = "Iguana"
+ a[6] = "Alligator"
+ a[7] = "Nouns"
+ a[8] = "people"
+}
+
+BEGIN {
+
+ for (IGNORECASE = 0; IGNORECASE < 2; IGNORECASE++) {
+ init(a)
+
+ n = asort(a)
+
+ for (i = 1; i <= n; i++)
+ printf("a[%d] = \"%s\"\n", i, a[i])
+
+ print "============"
+ }
+}
--- /dev/null
+a[1] = "Alligator"
+a[2] = "Iguana"
+a[3] = "Nouns"
+a[4] = "aardvark"
+a[5] = "animal"
+a[6] = "people"
+a[7] = "zebra"
+a[8] = "zoo"
+============
+a[1] = "aardvark"
+a[2] = "Alligator"
+a[3] = "animal"
+a[4] = "Iguana"
+a[5] = "Nouns"
+a[6] = "people"
+a[7] = "zebra"
+a[8] = "zoo"
+============
--- /dev/null
+function init(a)
+{
+ delete a
+
+ a["aardvark"] = 1
+ a["animal"] = 2
+ a["zebra"] = 3
+ a["zoo"] = 4
+ a["Iguana"] = 5
+ a["Alligator"] = 6
+ a["Nouns"] = 7
+ a["people"] = 8
+}
+
+BEGIN {
+
+ for (IGNORECASE = 0; IGNORECASE < 2; IGNORECASE++) {
+ init(a)
+
+ n = asorti(a)
+
+ for (i = 1; i <= n; i++)
+ printf("a[%d] = \"%s\"\n", i, a[i])
+
+ print "============"
+ }
+}
--- /dev/null
+a[1] = "Alligator"
+a[2] = "Iguana"
+a[3] = "Nouns"
+a[4] = "aardvark"
+a[5] = "animal"
+a[6] = "people"
+a[7] = "zebra"
+a[8] = "zoo"
+============
+a[1] = "aardvark"
+a[2] = "Alligator"
+a[3] = "animal"
+a[4] = "Iguana"
+a[5] = "Nouns"
+a[6] = "people"
+a[7] = "zebra"
+a[8] = "zoo"
+============
--- /dev/null
+{
+ gsub( "\\\\", "\\\\")
+ print
+}
--- /dev/null
+123
+abc
+456
--- /dev/null
+123
+abc
+456
--- /dev/null
+gawk: option requires an argument -- f
+Usage: gawk [POSIX or GNU style options] -f progfile [--] file ...
+Usage: gawk [POSIX or GNU style options] [--] 'program' file ...
+POSIX options: GNU long options:
+ -f progfile --file=progfile
+ -F fs --field-separator=fs
+ -v var=val --assign=var=val
+ -m[fr] val
+ -W compat --compat
+ -W copyleft --copyleft
+ -W copyright --copyright
+ -W dump-variables[=file] --dump-variables[=file]
+ -W exec=file --exec=file
+ -W gen-po --gen-po
+ -W help --help
+ -W lint[=fatal] --lint[=fatal]
+ -W lint-old --lint-old
+ -W non-decimal-data --non-decimal-data
+ -W profile[=file] --profile[=file]
+ -W posix --posix
+ -W re-interval --re-interval
+ -W source=program-text --source=program-text
+ -W traditional --traditional
+ -W usage --usage
+ -W version --version
+
+To report bugs, see node `Bugs' in `gawk.info', which is
+section `Reporting Problems and Bugs' in the printed version.
+
+gawk is a pattern scanning and processing language.
+By default it reads standard input and writes standard output.
+
+Examples:
+ gawk '{ sum += $1 }; END { print sum }' file
+ gawk -F: '{ print $1 }' /etc/passwd
--- /dev/null
+BEGIN { "cat" | getline; print; close("cat") }
--- /dev/null
+BEGIN {
+ print "000800" > "seq"
+ close("seq")
+ ARGV[1] = "seq"
+ ARGC = 2
+}
+
+{ printf "%06d", $1 + 1 >"seq";
+ printf "%06d", $1 + 1 }
+# Date: Mon, 20 Jan 1997 15:14:06 -0600 (CST)
+# From: Dave Bodenstab <emory!synet.net!imdave>
+# To: bug-gnu-utils@prep.ai.mit.edu
+# Subject: GNU awk 3.0.2 core dump
+# Cc: arnold@gnu.ai.mit.edu
+#
+# The following program produces a core file on my FreeBSD system:
+#
+# bash$ echo 000800 >/tmp/seq
+# bash$ gawk '{ printf "%06d", $1 + 1 >"/tmp/seq";
+# printf "%06d", $1 + 1 }' /tmp/seq
+#
+# This fragment comes from mgetty+sendfax.
+#
+# Here is the trace:
+#
+# Script started on Mon Jan 20 15:09:04 1997
+# bash$ gawk --version
+# GNU Awk 3.0.2
+# Copyright (C) 1989, 1991-1996 Free Software Foundation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# bash$ gdb gawk
+# GDB is free software and you are welcome to distribute copies of it
+# under certain conditions; type "show copying" to see the conditions.
+# There is absolutely no warranty for GDB; type "show warranty" for details.
+# GDB 4.13 (i386-unknown-freebsd),
+# Copyright 1994 Free Software Foundation, Inc...
+# (gdb) shell echo 000800 >/tmp/seq
+# (gdb) r '{ printf "%06d", $1 + 1 >"/tmp/seq"; printf "%06d", $1 + 1 }(gdb) r '{ printf "%06d", $1 + 1 >"/tmp/seq"; printf "%06d", $1 + 1 }' /tmp/seq
+# Starting program: /scratch/archive/src/cmd/gnuawk-3.0.2/gawk '{ printf "%06d", $1 + 1 >"/tmp/seq"; printf "%06d", $1 + 1 }' /tmp/seq
+#
+# Program received signal SIGBUS, Bus error.
+# 0xd86f in def_parse_field (up_to=1, buf=0x37704, len=6, fs=0x3b240, rp=0x0,
+# set=0xce6c <set_field>, n=0x0) at field.c:391
+# 391 sav = *end;
+# (gdb) bt
+# #0 0xd86f in def_parse_field (up_to=1, buf=0x37704, len=6, fs=0x3b240,
+# rp=0x0, set=0xce6c <set_field>, n=0x0) at field.c:391
+# #1 0xddb1 in get_field (requested=1, assign=0x0) at field.c:669
+# #2 0xc25d in r_get_lhs (ptr=0x3b9b4, assign=0x0) at eval.c:1339
+# #3 0x9ab0 in r_tree_eval (tree=0x3b9b4, iscond=0) at eval.c:604
+# #4 0xa5f1 in r_tree_eval (tree=0x3b9fc, iscond=0) at eval.c:745
+# #5 0x4661 in format_tree (fmt_string=0x3e040 "%06d", n0=0, carg=0x3ba20)
+# at builtin.c:620
+# #6 0x5beb in do_sprintf (tree=0x3b96c) at builtin.c:809
+# #7 0x5cd5 in do_printf (tree=0x3ba8c) at builtin.c:844
+# #8 0x9271 in interpret (tree=0x3ba8c) at eval.c:465
+# #9 0x8ca3 in interpret (tree=0x3bbd0) at eval.c:308
+# #10 0x8c34 in interpret (tree=0x3bc18) at eval.c:292
+# #11 0xf069 in do_input () at io.c:312
+# #12 0x12ba9 in main (argc=3, argv=0xefbfd538) at main.c:393
+# (gdb) l
+# 386 *buf += len;
+# 387 return nf;
+# 388 }
+# 389
+# 390 /* before doing anything save the char at *end */
+# 391 sav = *end;
+# 392 /* because it will be destroyed now: */
+# 393
+# 394 *end = ' '; /* sentinel character */
+# 395 for (; nf < up_to; scan++) {
+# (gdb) print end
+# $1 = 0x804d006 <Error reading address 0x804d006: No such file or directory>
+# (gdb) print buf
+# $2 = (char **) 0x37704
+# (gdb) print *buf
+# $3 = 0x804d000 <Error reading address 0x804d000: No such file or directory>
+# (gdb) q
+# The program is running. Quit anyway (and kill it)? (y or n) y
+# bash$ exit
+#
+# Script done on Mon Jan 20 15:11:07 1997
+#
+# Dave Bodenstab
+# imdave@synet.net
--- /dev/null
+000801
\ No newline at end of file
--- /dev/null
+BEGIN {
+ command = "LC_ALL=C sort"
+
+ n = split("abcdefghijklmnopqrstuvwxyz", a, "")
+ for (i = n; i > 0; i--) {
+# print "printing", a[i] > "/dev/stderr"
+ print a[i] |& command
+ }
+
+ close(command, "to")
+
+# print "starting read loop" > "/dev/stderr"
+ do {
+ if (line)
+ print "got", line
+# stopme();
+ } while ((command |& getline line) > 0)
+
+# print "doing final close" > "/dev/stderr"
+ close(command)
+}
--- /dev/null
+got a
+got b
+got c
+got d
+got e
+got f
+got g
+got h
+got i
+got j
+got k
+got l
+got m
+got n
+got o
+got p
+got q
+got r
+got s
+got t
+got u
+got v
+got w
+got x
+got y
+got z
--- /dev/null
+#! /usr/bin/awk -f
+BEGIN {
+ getline
+# print ("FILENAME =", FILENAME) > "/dev/stderr"
+ #Rewind the file
+ if (close(FILENAME)) {
+ print "Error `" ERRNO "' closing input file" > "/dev/stderr";
+ exit;
+ }
+}
+{ print "Analysing ", $0 }
+
--- /dev/null
+line 1
+line 2
+line 3
--- /dev/null
+Error `close of redirection that was never opened' closing input file
--- /dev/null
+BEGIN {
+ if (ARGV[1]) print 1
+ ARGV[1] = ""
+ if (ARGV[2]) print 2
+ ARGV[2] = ""
+ if ("0") print "zero"
+ if ("") print "null"
+ if (0) print 0
+}
+{
+ if ($0) print $0
+ if ($1) print $1
+}
--- /dev/null
+0
+1
+0 1
+
--- /dev/null
+2
+zero
+1
+1
+0 1
--- /dev/null
+# From beebe@math.utah.edu Thu Aug 2 15:35:07 2001
+# Received: from mail.actcom.co.il [192.114.47.13]
+# by localhost with POP3 (fetchmail-5.7.4)
+# for arnold@localhost (single-drop); Thu, 02 Aug 2001 15:35:07 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Thu Aug 2 16:02:36 2001)
+# X-From_: beebe@sunshine.math.utah.edu Thu Aug 2 15:41:13 2001
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id PAA01349 for <arobbins@actcom.co.il>;
+# Thu, 2 Aug 2001 15:41:06 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from billohost.com (www.billohost.com [209.196.35.10])
+# by lmail.actcom.co.il (8.11.2/8.11.2) with ESMTP id f72Cf3I21032
+# for <arobbins@actcom.co.il>; Thu, 2 Aug 2001 15:41:05 +0300
+# Received: from fencepost.gnu.org (we-refuse-to-spy-on-our-users@fencepost.gnu.org [199.232.76.164])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id IAA28585
+# for <arnold@skeeve.com>; Thu, 2 Aug 2001 08:34:38 -0400
+# Received: from sunshine.math.utah.edu ([128.110.198.2])
+# by fencepost.gnu.org with esmtp (Exim 3.22 #1 (Debian))
+# id 15SHjG-00036x-00
+# for <arnold@gnu.org>; Thu, 02 Aug 2001 08:37:30 -0400
+# Received: from suncore.math.utah.edu (IDENT:GsUbUdUYCtFLRE4HvnnvhN4JsjooYcfR@suncore0.math.utah.edu [128.110.198.5])
+# by sunshine.math.utah.edu (8.9.3/8.9.3) with ESMTP id GAA00190;
+# Thu, 2 Aug 2001 06:37:04 -0600 (MDT)
+# Received: (from beebe@localhost)
+# by suncore.math.utah.edu (8.9.3/8.9.3) id GAA20469;
+# Thu, 2 Aug 2001 06:37:03 -0600 (MDT)
+# Date: Thu, 2 Aug 2001 06:37:03 -0600 (MDT)
+# From: "Nelson H. F. Beebe" <beebe@math.utah.edu>
+# To: arnold@gnu.org
+# Cc: beebe@math.utah.edu
+# X-US-Mail: "Center for Scientific Computing, Department of Mathematics, 322
+# INSCC, University of Utah, 155 S 1400 E RM 233, Salt Lake City, UT
+# 84112-0090, USA"
+# X-Telephone: +1 801 581 5254
+# X-FAX: +1 801 585 1640, +1 801 581 4148
+# X-URL: http://www.math.utah.edu/~beebe
+# Subject: awk implementations: a bug, or new dark corner?
+# Message-ID: <CMM.0.92.0.996755823.beebe@suncore.math.utah.edu>
+# Status: RO
+#
+# Consider the following program:
+#
+# % cat bug.awk
+BEGIN {
+ split("00/00/00",mdy,"/")
+ if ((mdy[1] == 0) && (mdy[2] == 0) && (mdy[3] == 0))
+ {
+ print "OK: zero strings compare equal to number zero"
+ exit(0)
+ }
+ else
+ {
+ print "ERROR: zero strings compare unequal to number zero"
+ exit(1)
+ }
+}
+#
+# Here are the awk implementation versions (on Sun Solaris 2.7):
+#
+# % awk -V
+# awk version 19990416
+#
+# % mawk -W version
+# mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
+#
+# % nawk -V
+# awk version 20001115
+#
+# % gawk --version
+# GNU Awk 3.1.10
+# ...
+#
+# Here's what they say about the test program:
+#
+# foreach f (awk mawk nawk gawk gawk-*)
+# echo ======== $f
+# $f -f ~/bug.awk
+# end
+#
+# ======== awk
+# OK: zero strings compare equal to number zero
+# ======== mawk
+# OK: zero strings compare equal to number zero
+# ======== nawk
+# OK: zero strings compare equal to number zero
+# ======== gawk
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.0
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.1
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.3
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.4
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.5
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.6
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.60
+# OK: zero strings compare equal to number zero
+# ======== gawk-3.0.90
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.91
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.92
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.93
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.94
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.95
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.96
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.0.97
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.1.0
+# ERROR: zero strings compare unequal to number zero
+# ======== gawk-3.1.10
+# ERROR: zero strings compare unequal to number zero
+#
+# Identical results were obtained on Apple Rhapsody, Apple Darwin,
+# Compaq/DEC Alpha OSF/1, Intel x86 GNU/Linux, SGI IRIX 6.5, DEC Alpha
+# GNU/Linux, and Sun SPARC GNU/Linux, so it definitely is not a C
+# compiler problem.
+#
+# However, the gray awk book, p. 44, says:
+#
+# In a comparison expression like:
+# x == y
+# if both operands have a numeric type, the comparison is numeric;
+# otherwise, any numeric operand is converted to a string and the
+# comparison is made on the string values.
+#
+# and the new green gawk book, p. 95, says:
+#
+# When comparing operands of mixed types, numeric operands are
+# converted to strings using the value of `CONVFMT'
+#
+# This suggests that the OK response in bug.awk is wrong, and the ERROR
+# response is correct. Only recent gawk releases do the right thing,
+# and it is awk, mawk, and nawk that have a bug.
+#
+# If I change the test program from "00/00/00" to "0/0/0", all versions
+# tested produce the OK response.
+#
+# Comments?
+#
+# After reading the two book excerpts, I changed my code to read
+#
+# if (((0 + mdy[1]) == 0) && ((0 + mdy[2]) == 0) && ((0 + mdy[3]) == 0))
+#
+# and output from all implementations now agrees.
+#
+# -------------------------------------------------------------------------------
+# - Nelson H. F. Beebe Tel: +1 801 581 5254 -
+# - Center for Scientific Computing FAX: +1 801 585 1640, +1 801 581 4148 -
+# - University of Utah Internet e-mail: beebe@math.utah.edu -
+# - Department of Mathematics, 322 INSCC beebe@acm.org beebe@computer.org -
+# - 155 S 1400 E RM 233 beebe@ieee.org -
+# - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe -
+# -------------------------------------------------------------------------------
+#
--- /dev/null
+OK: zero strings compare equal to number zero
--- /dev/null
+#From deep@cicada-semi.com Wed Jan 23 13:15:52 2002
+#X-From_: deep@cicada-semi.com Wed Jan 23 01:24:54 2002
+#From: "Mandeep Chadha" <deep@cicada-semi.com>
+#To: <bug-gawk@gnu.org>
+#Subject: gawk version 3.1.0 will not print a ";"
+#Date: Tue, 22 Jan 2002 17:23:57 -0600
+#Message-ID: <NCBBLGONGLINHCDGFCPNOENHCOAA.deep@cicada-semi.com>
+#MIME-Version: 1.0
+#Content-Type: text/plain;
+# charset="iso-8859-1"
+#Content-Transfer-Encoding: 7bit
+#X-Priority: 3 (Normal)
+#X-MSMail-Priority: Normal
+#X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0)
+#Importance: Normal
+#X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700
+#
+#
+#The file "tmp" contains the following lines:
+#
+#A
+#B
+#C
+#D
+#
+#and when I run the command:
+#
+# gawk '{print "Input = "$_" ; "}' tmp
+{print "Input = "$_" ; "}
+#
+#I get the following output:
+#
+#Input = A
+#Input = B
+#Input = C
+#Input = D
+#
+#while I expect the following output:
+#
+#Input = A ;
+#Input = B ;
+#Input = C ;
+#Input = D ;
+#
+#Running gawk --version produces the following output:
+#
+#GNU Awk 3.1.0
+#Copyright (C) 1989, 1991-2001 Free Software Foundation.
+#
+#This program is free software; you can redistribute it and/or modify
+#it under the terms of the GNU General Public License as published by
+#the Free Software Foundation; either version 2 of the License, or
+#(at your option) any later version.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU General Public License
+#along with this program; if not, write to the Free Software
+#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#I am running this on a i686 machine that is running RedHat 7.2 (out of the box).
+#
+#Thanks,
+#
+#Mandeep Chadha
+#
+#----------------------------------------
+#Mandeep Chadha
+#Cicada Semiconductor Corp.
+#811 Barton Springs Road, Suite 550
+#Austin, TX 78704
+#Ph: (512) 327-3500 x111
+#E-mail: deep@cicada-semi.com
+#URL: http://www.cicada-semi.com
+#----------------------------------------
--- /dev/null
+A
+B
+C
+D
--- /dev/null
+Input = A ;
+Input = B ;
+Input = C ;
+Input = D ;
--- /dev/null
+function f(s, x) {
+ x = 1
+ s = 3
+ s = s x
+ print s
+}
+
+BEGIN { for (i = 1; i <=12; i++) f() }
--- /dev/null
+31
+31
+31
+31
+31
+31
+31
+31
+31
+31
+31
+31
--- /dev/null
+BEGIN { a; a = a (b "c"); print a; print b }
--- /dev/null
+BEGIN {
+ CONVFMT = "%2.2f"
+ a = 123.456
+ b = a "" # give `a' string value also
+ printf "a = %s\n", a
+ CONVFMT = "%.6g"
+ printf "a = %s\n", a
+ a += 0 # make `a' numeric only again
+ printf "a = %s\n", a # use `a' as string
+}
--- /dev/null
+a = 123.46
+a = 123.456
+a = 123.456
--- /dev/null
+# example program from alex@bofh.torun.pl
+BEGIN { IGNORECASE=1 }
+/\w+@([[:alnum:]]+\.)+[[:alnum:]]+[[:blank:]]+/ {print $0}
--- /dev/null
+bleble@foo1.bh.pl deny
\ No newline at end of file
--- /dev/null
+bleble@foo1.bh.pl deny
--- /dev/null
+BEGIN { foo() }
--- /dev/null
+gawk: defref.awk:2: warning: function `foo' called but never defined
+gawk: defref.awk:1: fatal: function `foo' not defined
+EXIT CODE: 2
--- /dev/null
+# From beebe@math.utah.edu Sat May 17 21:31:27 2003
+# Return-Path: <beebe@math.utah.edu>
+# Received: from localhost (aahz [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h4HIQmCw001380
+# for <arnold@localhost>; Sat, 17 May 2003 21:31:27 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Sat, 17 May 2003 21:31:27 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Sat May 17 21:34:07 2003)
+# X-From_: beebe@sunshine.math.utah.edu Fri May 16 20:38:45 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h4GHcd226764 for <arobbins@actcom.co.il>;
+# Fri, 16 May 2003 20:38:40 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h4GHgBc2023067
+# for <arobbins@actcom.co.il>; Fri, 16 May 2003 20:42:13 +0300
+# Received: from sunshine.math.utah.edu (sunshine.math.utah.edu [128.110.198.2])
+# by f7.net (8.11.7/8.11.6) with ESMTP id h4GHcbf09202
+# for <arnold@skeeve.com>; Fri, 16 May 2003 13:38:37 -0400
+# Received: from suncore.math.utah.edu (IDENT:r8KQWmkF4jVMLBhxpojXGNCAnBZB38ET@suncore.math.utah.edu [128.110.198.5])
+# by sunshine.math.utah.edu (8.9.3p2/8.9.3) with ESMTP id LAA09111;
+# Fri, 16 May 2003 11:38:34 -0600 (MDT)
+# Received: (from beebe@localhost)
+# by suncore.math.utah.edu (8.9.3p2/8.9.3) id LAA01743;
+# Fri, 16 May 2003 11:38:34 -0600 (MDT)
+# Date: Fri, 16 May 2003 11:38:34 -0600 (MDT)
+# From: "Nelson H. F. Beebe" <beebe@math.utah.edu>
+# To: "Arnold Robbins" <arnold@skeeve.com>
+# Cc: beebe@math.utah.edu
+# X-US-Mail: "Center for Scientific Computing, Department of Mathematics, 110
+# LCB, University of Utah, 155 S 1400 E RM 233, Salt Lake City, UT
+# 84112-0090, USA"
+# X-Telephone: +1 801 581 5254
+# X-FAX: +1 801 585 1640, +1 801 581 4148
+# X-URL: http://www.math.utah.edu/~beebe
+# Subject: gawk-3.1.2[ab]: bug in delete
+# Message-ID: <CMM.0.92.0.1053106714.beebe@suncore.math.utah.edu>
+#
+# I discovered yesterday that one of my tools got broken by the upgrade
+# to gawk-3.1.2a and gawk-3.1.2b. For now, I've temporarily reset
+# /usr/local/bin/gawk on the Sun Solaris and Intel GNU/Linux systems
+# back to be gawk-3.1.2.
+#
+# This morning, I isolated the problem to the following small test case:
+#
+# % cat bug.awk
+ BEGIN {
+ clear_array(table)
+ foo(table)
+ for (key in table)
+ print key, table[k]
+ clear_array(table)
+ exit(0)
+ }
+
+ function clear_array(array, key)
+ {
+ for (key in array)
+ delete array[key]
+ }
+
+ function foo(a)
+ {
+ a[1] = "one"
+ a[2] = "two"
+ }
+#
+# With nawk, mawk, and also gawk-3.1.2 or earlier, I get this:
+#
+# % mawk -f bug.awk
+# 1
+# 2
+#
+# However, with the two most recent gawk releases, I get:
+#
+# % gawk-3.1.2b -f bug.awk
+# gawk-3.1.2b: bug.awk:12: fatal: delete: illegal use of variable `table' as
+# array
+#
+# If the first clear_array() statement is commented out, it runs.
+# However, the problem is that in a large program, it may not be easy to
+# identify places where it is safe to invoke delete, so I believe the
+# old behavior is more desirable.
+#
+# -------------------------------------------------------------------------------
+# - Nelson H. F. Beebe Tel: +1 801 581 5254 -
+# - Center for Scientific Computing FAX: +1 801 581 4148 -
+# - University of Utah Internet e-mail: beebe@math.utah.edu -
+# - Department of Mathematics, 110 LCB beebe@acm.org beebe@computer.org -
+# - 155 S 1400 E RM 233 beebe@ieee.org -
+# - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe -
+# -------------------------------------------------------------------------------
+#
--- /dev/null
+# From dragon!unagi.cis.upenn.edu!sjanet Tue Mar 25 17:12:20 1997
+# Return-Path: <dragon!unagi.cis.upenn.edu!sjanet>
+# Received: by skeeve.atl.ga.us (/\==/\ Smail3.1.22.1 #22.1)
+# id <m0w9eS4-000GWyC@skeeve.atl.ga.us>; Tue, 25 Mar 97 17:12 EST
+# Received: by vecnet.com (DECUS UUCP /2.0/2.0/2.0/);
+# Tue, 25 Mar 97 16:58:36 EDT
+# Received: from gnu-life.ai.mit.edu by antaries.vec.net (MX V4.2 VAX) with SMTP;
+# Tue, 25 Mar 1997 16:58:26 EST
+# Received: from linc.cis.upenn.edu by gnu-life.ai.mit.edu (8.8.5/8.6.12GNU) with
+# ESMTP id QAA24350 for <bug-gnu-utils@prep.ai.mit.edu>; Tue, 25 Mar
+# 1997 16:56:59 -0500 (EST)
+# Received: from unagi.cis.upenn.edu (UNAGI.CIS.UPENN.EDU [158.130.8.153]) by
+# linc.cis.upenn.edu (8.8.5/8.8.5) with ESMTP id QAA09424; Tue, 25 Mar
+# 1997 16:56:54 -0500 (EST)
+# Received: (from sjanet@localhost) by unagi.cis.upenn.edu (8.8.5/8.8.5) id
+# QAA03969; Tue, 25 Mar 1997 16:56:50 -0500 (EST)
+# Date: Tue, 25 Mar 1997 16:56:50 -0500 (EST)
+# From: Stan Janet <sjanet@unagi.cis.upenn.edu>
+# Message-ID: <199703252156.QAA03969@unagi.cis.upenn.edu>
+# To: bug-gnu-utils@prep.ai.mit.edu
+# CC: arnold@gnu.ai.mit.edu
+# Subject: GNU awk 3.0.2 bug: fatal error deleting local array inside function
+# Status: ORf
+#
+# Version: GNU Awk 3.0.2
+# Platforms: SunOS 4.1.1 (compiled with Sun cc)
+# IRIX 5.3 (compiled with SGI cc)
+# Problem: Deleting local array inside function causes fatal internal error (and
+# core dump. The error does not occur when the variable "x", unused in
+# the example, is removed or when the function is declared foo(x,p).
+# When the function is declared foo(p,x), adding a dummy line that uses
+# "x", e.g. "x=1" does not prevent the error. If "p" is not deleted,
+# there is no error. If "p[1]" is used to delete the lone element, there
+# is no error.
+#
+# ==== The program x.gawk ====
+
+function foo(p,x) {
+ p[1]="bar"
+ delete p
+ return 0
+}
+
+BEGIN {
+ foo()
+}
+
+# ==== The output for "gawk -f x.gawk" (SunOS) ====
+#
+# gawk: x.gawk:4: fatal error: internal error
--- /dev/null
+# from Stepan Kasal, 9 July 2003
+function f()
+{
+ delete f
+}
+
+BEGIN { f() }
--- /dev/null
+gawk: delfunc.awk:4: fatal: attempt to use function `f' as an array
+EXIT CODE: 2
--- /dev/null
+BEGIN { printf "%*sworld\n", -20, "hello" }
--- /dev/null
+hello world
--- /dev/null
+# Date: Sat, 30 Mar 1996 12:47:17 -0800 (PST)
+# From: Charles Howes <chowes@grid.direct.ca>
+# To: bug-gnu-utils@prep.ai.mit.edu, arnold@gnu.ai.mit.edu
+# Subject: Bug in Gawk 3.0.0, sample code:
+#
+#!/usr/local/bin/gawk -f
+#
+# Hello! This is a bug report from chowes@direct.ca
+#
+# uname -a
+# SunOS hostname 5.5 Generic sun4m
+#
+# Gnu Awk (gawk) 3.0, patchlevel 0:
+BEGIN{
+FS=":"
+while ((getline < "/etc/passwd") > 0) {
+ r=$3
+ z=0
+ n[0]=1
+ }
+FS=" "
+}
+#gawk: fp.new:16: fatal error: internal error
+#Abort
+
+# #!/usr/local/bin/gawk -f
+# # Gnu Awk (gawk) 2.15, patchlevel 6
+#
+# BEGIN{
+# f="/etc/passwd"
+# while (getline < f) n[0]=1
+# FS=" "
+# }
+# #gawk: /staff/chowes/bin/fp:7: fatal error: internal error
+# #Abort
+
+# These examples are not perfect coding style because I took a real
+# piece of code and tried to strip away anything that didn't make the error
+# message go away.
+#
+# The interesting part of the 'truss' is:
+#
+# fstat(3, 0xEFFFF278) = 0
+# lseek(3, 0, SEEK_SET) = 0
+# read(3, " r o o t : x : 0 : 1 : S".., 2291) = 2291
+# brk(0x00050020) = 0
+# brk(0x00052020) = 0
+# read(3, 0x0004F4B8, 2291) = 0
+# close(3) = 0
+# Incurred fault #6, FLTBOUNDS %pc = 0x0001B810
+# siginfo: SIGSEGV SEGV_MAPERR addr=0x00053000
+# Received signal #11, SIGSEGV [caught]
+# siginfo: SIGSEGV SEGV_MAPERR addr=0x00053000
+# write(2, " g a w k", 4) = 4
+# write(2, " : ", 2) = 2
+#
+# --
+# Charles Howes -- chowes@direct.ca Voice: (604) 691-1607
+# System Administrator Fax: (604) 691-1605
+# Internet Direct - 1050 - 555 West Hastings St - Vancouver, BC V6B 4N6
+#
+# A sysadmin's life is a sorry one. The only advantage he has over Emergency
+# Room doctors is that malpractice suits are rare. On the other hand, ER
+# doctors never have to deal with patients installing new versions of their
+# own innards! -Michael O'Brien
+#
+# "I think I know what may have gone wrong in the original s/w.
+# It's a bug in the way it was written." - Vagueness**n
--- /dev/null
+# This should exit 0, even though child exits 1
+BEGIN { "exit 1" | getline junk ; exit 12 }
+END { exit 0 }
--- /dev/null
+EXIT CODE: 0
--- /dev/null
+BEGIN { print "foo" | "read x ; echo $x ; exit 12" }
+# this should still exit 0, as pointed out by kenny mccormack in
+# comp.lang.awk on 2 feb 2005
--- /dev/null
+1st
+2nd
+1st
+2nd
+1st
+2nd
+1st
+2nd
+1st
+2nd
+1st
+2nd
+1st
+2nd
+1st
+2nd
--- /dev/null
+#! /bin/sh
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"cat"}'
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"cat"}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");close("/dev/stdout");print "2nd"|"cat"}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"cat";close("cat")}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"cat";close("cat")}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"cat";close("cat")}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"sort"}'|cat
+
+../gawk 'BEGIN{print "1st";fflush("/dev/stdout");print "2nd"|"sort";close("sort")}'|cat
--- /dev/null
+BEGIN { FIELDWIDTHS = "2 3 4" }
+{ print $2 }
--- /dev/null
+{
+# print "0:", $0
+ gsub("aa", "+")
+ print "1:", $0
+ $3 = "<" $3 ">"
+ print "2:", $0
+ print "2a:" "%" $1 "%" $2 "%" $3 "%" $4 "%" $5
+}
--- /dev/null
+aa aab c d e f
--- /dev/null
+1: + +b c d e f
+2: + +b <c> d e f
+2a:%+%+b%<c>%d%e
--- /dev/null
+{ OFS = ":"; $2 = ""; print $0; print NF }
--- /dev/null
+### /u/sy/beebe/xml/shbook/fmttest.awk, Sat May 31 09:13:52 2003
+### Edit by Nelson H. F. Beebe <beebe@math.utah.edu>
+### ====================================================================
+### Test the degree of support for printf format items in awk
+### implementations.
+###
+### Usage:
+### awk -f fmttest.awk
+### [31-May-2003]
+### ====================================================================
+
+BEGIN {
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: c\n"
+
+ printf("ABC with %%c : %c\n", "ABC")
+ printf("123 with %%c : %c\n", 123)
+
+ printf("ABC with %%.15c : %.15c\n", "ABC")
+ printf("123 with %%.15c : %.15c\n", 123)
+
+ printf("ABC with %%15c : %15c\n", "ABC")
+ printf("123 with %%15c : %15c\n", 123)
+
+ printf("ABC with %%-15c : %-15c\n", "ABC")
+ printf("123 with %%-15c : %-15c\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: d\n"
+
+ printf("ABC with %%d : %d\n", "ABC")
+ printf("123 with %%d : %d\n", 123)
+
+ printf("ABC with %%.15d : %.15d\n", "ABC")
+ printf("123 with %%.15d : %.15d\n", 123)
+
+ printf("ABC with %%15d : %15d\n", "ABC")
+ printf("123 with %%15d : %15d\n", 123)
+
+ printf("ABC with %%-15d : %-15d\n", "ABC")
+ printf("123 with %%-15d : %-15d\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: e\n"
+
+ printf("ABC with %%e : %e\n", "ABC")
+ printf("123 with %%e : %e\n", 123)
+
+ printf("ABC with %%.25e : %.25e\n", "ABC")
+ printf("123 with %%.25e : %.25e\n", 123)
+
+ printf("ABC with %%25e : %25e\n", "ABC")
+ printf("123 with %%25e : %25e\n", 123)
+
+ printf("ABC with %%-25e : %-25e\n", "ABC")
+ printf("123 with %%-25e : %-25e\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: f\n"
+
+ printf("ABC with %%f : %f\n", "ABC")
+ printf("123 with %%f : %f\n", 123)
+
+ printf("ABC with %%.25f : %.25f\n", "ABC")
+ printf("123 with %%.25f : %.25f\n", 123)
+
+ printf("ABC with %%25f : %25f\n", "ABC")
+ printf("123 with %%25f : %25f\n", 123)
+
+ printf("ABC with %%-25f : %-25f\n", "ABC")
+ printf("123 with %%-25f : %-25f\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: g\n"
+
+ printf("ABC with %%g : %g\n", "ABC")
+ printf("123 with %%g : %g\n", 123)
+
+ printf("ABC with %%.25g : %.25g\n", "ABC")
+ printf("123 with %%.25g : %.25g\n", 123)
+
+ printf("ABC with %%25g : %25g\n", "ABC")
+ printf("123 with %%25g : %25g\n", 123)
+
+ printf("ABC with %%-25g : %-25g\n", "ABC")
+ printf("123 with %%-25g : %-25g\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: o\n"
+
+ printf("ABC with %%o : %o\n", "ABC")
+ printf("123 with %%o : %o\n", 123)
+
+ printf("ABC with %%.15o : %.15o\n", "ABC")
+ printf("123 with %%.15o : %.15o\n", 123)
+
+ printf("ABC with %%15o : %15o\n", "ABC")
+ printf("123 with %%15o : %15o\n", 123)
+
+ printf("ABC with %%-15o : %-15o\n", "ABC")
+ printf("123 with %%-15o : %-15o\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: s\n"
+
+ printf("ABC with %%s : %s\n", "ABC")
+ printf("123 with %%s : %s\n", 123)
+
+ printf("ABC with %%.15s : %.15s\n", "ABC")
+ printf("123 with %%.15s : %.15s\n", 123)
+
+ printf("ABC with %%15s : %15s\n", "ABC")
+ printf("123 with %%15s : %15s\n", 123)
+
+ printf("ABC with %%-15s : %-15s\n", "ABC")
+ printf("123 with %%-15s : %-15s\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: u\n"
+
+ printf("ABC with %%u : %u\n", "ABC")
+ printf("123 with %%u : %u\n", 123)
+
+ printf("ABC with %%.15u : %.15u\n", "ABC")
+ printf("123 with %%.15u : %.15u\n", 123)
+
+ printf("ABC with %%15u : %15u\n", "ABC")
+ printf("123 with %%15u : %15u\n", 123)
+
+ printf("ABC with %%-15u : %-15u\n", "ABC")
+ printf("123 with %%-15u : %-15u\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: x\n"
+
+ printf("ABC with %%x : %x\n", "ABC")
+ printf("123 with %%x : %x\n", 123)
+
+ printf("ABC with %%.15x : %.15x\n", "ABC")
+ printf("123 with %%.15x : %.15x\n", 123)
+
+ printf("ABC with %%15x : %15x\n", "ABC")
+ printf("123 with %%15x : %15x\n", 123)
+
+ printf("ABC with %%-15x : %-15x\n", "ABC")
+ printf("123 with %%-15x : %-15x\n", 123)
+
+ ## -----------------------------------------------------------------
+ print "\n\nFormat item: X\n"
+
+ printf("ABC with %%X : %X\n", "ABC")
+ printf("123 with %%X : %X\n", 123)
+
+ printf("ABC with %%.15X : %.15X\n", "ABC")
+ printf("123 with %%.15X : %.15X\n", 123)
+
+ printf("ABC with %%15X : %15X\n", "ABC")
+ printf("123 with %%15X : %15X\n", 123)
+
+ printf("ABC with %%-15X : %-15X\n", "ABC")
+ printf("123 with %%-15X : %-15X\n", 123)
+
+ exit(0)
+}
--- /dev/null
+
+
+Format item: c
+
+ABC with %c : A
+123 with %c : {
+ABC with %.15c : A
+123 with %.15c : {
+ABC with %15c : A
+123 with %15c : {
+ABC with %-15c : A
+123 with %-15c : {
+
+
+Format item: d
+
+ABC with %d : 0
+123 with %d : 123
+ABC with %.15d : 000000000000000
+123 with %.15d : 000000000000123
+ABC with %15d : 0
+123 with %15d : 123
+ABC with %-15d : 0
+123 with %-15d : 123
+
+
+Format item: e
+
+ABC with %e : 0.000000e+00
+123 with %e : 1.230000e+02
+ABC with %.25e : 0.0000000000000000000000000e+00
+123 with %.25e : 1.2300000000000000000000000e+02
+ABC with %25e : 0.000000e+00
+123 with %25e : 1.230000e+02
+ABC with %-25e : 0.000000e+00
+123 with %-25e : 1.230000e+02
+
+
+Format item: f
+
+ABC with %f : 0.000000
+123 with %f : 123.000000
+ABC with %.25f : 0.0000000000000000000000000
+123 with %.25f : 123.0000000000000000000000000
+ABC with %25f : 0.000000
+123 with %25f : 123.000000
+ABC with %-25f : 0.000000
+123 with %-25f : 123.000000
+
+
+Format item: g
+
+ABC with %g : 0
+123 with %g : 123
+ABC with %.25g : 0
+123 with %.25g : 123
+ABC with %25g : 0
+123 with %25g : 123
+ABC with %-25g : 0
+123 with %-25g : 123
+
+
+Format item: o
+
+ABC with %o : 0
+123 with %o : 173
+ABC with %.15o : 000000000000000
+123 with %.15o : 000000000000173
+ABC with %15o : 0
+123 with %15o : 173
+ABC with %-15o : 0
+123 with %-15o : 173
+
+
+Format item: s
+
+ABC with %s : ABC
+123 with %s : 123
+ABC with %.15s : ABC
+123 with %.15s : 123
+ABC with %15s : ABC
+123 with %15s : 123
+ABC with %-15s : ABC
+123 with %-15s : 123
+
+
+Format item: u
+
+ABC with %u : 0
+123 with %u : 123
+ABC with %.15u : 000000000000000
+123 with %.15u : 000000000000123
+ABC with %15u : 0
+123 with %15u : 123
+ABC with %-15u : 0
+123 with %-15u : 123
+
+
+Format item: x
+
+ABC with %x : 0
+123 with %x : 7b
+ABC with %.15x : 000000000000000
+123 with %.15x : 00000000000007b
+ABC with %15x : 0
+123 with %15x : 7b
+ABC with %-15x : 0
+123 with %-15x : 7b
+
+
+Format item: X
+
+ABC with %X : 0
+123 with %X : 7B
+ABC with %.15X : 000000000000000
+123 with %.15X : 00000000000007B
+ABC with %15X : 0
+123 with %15X : 7B
+ABC with %-15X : 0
+123 with %-15X : 7B
--- /dev/null
+function foo() { print foo } {foo()}
--- /dev/null
+gawk: fnamedat.awk:1: (FILENAME=- FNR=1) fatal: can't use function name `foo' as variable or array
+EXIT CODE: 2
--- /dev/null
+function foo(N) {
+ return 0
+}
+BEGIN {
+ Num = foo[c]
+}
+
--- /dev/null
+gawk: fnarray.awk:5: Num = foo[c]
+gawk: fnarray.awk:5: ^ use of non-array as array
+EXIT CODE: 1
--- /dev/null
+function pile(c, r)
+{
+ r = ++pile[c]
+}
+{ pile($1) }
--- /dev/null
+gawk: fnarray2.awk:3: r = ++pile[c]
+gawk: fnarray2.awk:3: ^ use of non-array as array
+EXIT CODE: 1
--- /dev/null
+#!/usr/local/bin/gawk -f
+BEGIN {
+ process()
+}
+
+function process(aa,a) {
+ delete aa
+}
+
+BEGIN {
+ for (i = 1; i < 10; i++)
+ a[i] = i;
+
+ print "first loop"
+ for (i in a)
+ print a[i]
+
+ delete a
+
+ print "second loop"
+ for (i in a)
+ print a[i]
+
+ for (i = 1; i < 10; i++)
+ a[i] = i;
+
+ print "third loop"
+ for (i in a)
+ print a[i]
+
+ print "call func"
+ delit(a)
+
+ print "fourth loop"
+ for (i in a)
+ print a[i]
+
+ stressit()
+}
+
+function delit(arr)
+{
+ delete arr
+}
+
+function stressit( array, i)
+{
+ delete array
+ array[4] = 4
+ array[5] = 5
+ delete array[5]
+ print "You should just see: 4 4"
+ for (i in array)
+ print i, array[i]
+ delete array
+ print "You should see nothing between this line"
+ for (i in array)
+ print i, array[i]
+ print "And this one"
+}
--- /dev/null
+first loop
+4
+5
+6
+7
+8
+9
+1
+2
+3
+second loop
+third loop
+4
+5
+6
+7
+8
+9
+1
+2
+3
+call func
+fourth loop
+You should just see: 4 4
+4 4
+You should see nothing between this line
+And this one
--- /dev/null
+BEGIN {
+ foo[1] = 4
+ f1(foo)
+}
+
+function f1(a) { f2(a) }
+
+function f2(b) { f3(b) }
+
+function f3(c) { c = 6 }
--- /dev/null
+gawk: fnaryscl.awk:10: fatal: attempt to use array `c (from b, from a, from foo)' in a scalar context
+EXIT CODE: 2
--- /dev/null
+# AFP_Bug1.awk - illustrate a problem with `gawk' (GNU Awk 3.0.3 on OS/2)
+# Arthur Pool .. pool@commerce.uq.edu.au
+# $Id: AFP_Bug1.awk,v 1.1 1998-03-17 12:22:44+10 pool Exp pool $
+
+# Assignment to a variable with the same name as a function from within
+# that function causes an ABEND.
+#
+# Yes, I do realise that it's not a smart thing to do, but an error
+# message would be a kinder response than a core dump (and would make
+# debugging a whole lot easier).
+
+{ShowMe()}
+
+function ShowMe() {ShowMe = 1}
--- /dev/null
+gawk: fnasgnm.awk:14: (FILENAME=- FNR=1) fatal: can't use function name `ShowMe' as variable or array
+EXIT CODE: 2
--- /dev/null
+# Tue Feb 4 12:20:10 IST 2003
+
+# Misc functions tests, in case we start mucking around in the grammar again.
+
+# Empty body shouldn't hurt anything:
+function f() {}
+BEGIN { f() }
+
+# Using a built-in function name should manage the symbol table
+# correctly:
+function split(x) { return x }
+
+function x(a) { return a }
--- /dev/null
+gawk: fnmisc.awk:11: function split(x) { return x }
+gawk: fnmisc.awk:11: ^ `split' is a built-in function, it cannot be redefined
+EXIT CODE: 1
--- /dev/null
+# fnparydl.awk --- check that deleting works with arrays
+# that are parameters.
+#
+# Tue Jul 11 14:20:58 EDT 2000
+
+function delit(a, k)
+{
+ print "BEFORE LOOP"
+ for (k in a) {
+ print "DELETING KEY", k
+ delete a[k]
+ }
+ print "AFTER LOOP"
+}
+
+BEGIN {
+ for (i = 1 ; i <= 7; i++) {
+ q[i] = sprintf("element %d", i)
+ x[i] = i
+ y[i] = q[i]
+ }
+# adump(q)
+ delit(q)
+# for (i in q)
+# delete q[i]
+ j = 0;
+ for (i in q)
+ j++
+ print j, "elements still in q[]"
+# adump(q)
+}
--- /dev/null
+BEFORE LOOP
+DELETING KEY 4
+DELETING KEY 5
+DELETING KEY 6
+DELETING KEY 7
+DELETING KEY 1
+DELETING KEY 2
+DELETING KEY 3
+AFTER LOOP
+0 elements still in q[]
--- /dev/null
+#Date: Mon, 7 Jun 2004 10:40:28 -0500
+#From: mary1john8@earthlink.net
+#To: arnold@skeeve.com
+#Subject: gawk internal errors
+#Message-ID: <20040607154028.GA2457@apollo>
+#
+#Hello,
+#
+# gawk-3.1.3i internal errors:
+#
+#[1]
+#
+#$> ./gawk 'BEGIN { for (i in a) delete a; }'
+BEGIN { for (i in a) delete a; }
+#gawk: fatal error: internal error
+#Aborted
+#
+#------------------------------------------------------------------
+#--- awkgram.y.orig 2004-06-07 09:42:14.000000000 -0500
+#+++ awkgram.y 2004-06-07 09:45:58.000000000 -0500
+#@@ -387,7 +387,7 @@
+# * Check that the body is a `delete a[i]' statement,
+# * and that both the loop var and array names match.
+# */
+#- if ($8 != NULL && $8->type == Node_K_delete) {
+#+ if ($8 != NULL && $8->type == Node_K_delete && $8->rnode != NULL) {
+# NODE *arr, *sub;
+#
+# assert($8->rnode->type == Node_expression_list);
+#------------------------------------------------------------------
+#
+#
+#[2]
+#
+#$> ./gawk 'BEGIN { printf("%3$*10$.*1$s\n", 20, 10, "hello"); }'
+#gawk: fatal error: internal error
+#Aborted
+#
+#------------------------------------------------------------------
+#--- builtin.c.orig 2004-06-07 10:04:20.000000000 -0500
+#+++ builtin.c 2004-06-07 10:06:08.000000000 -0500
+#@@ -780,7 +780,10 @@
+# s1++;
+# n0--;
+# }
+#-
+#+ if (val >= num_args) {
+#+ toofew = TRUE;
+#+ break;
+#+ }
+# arg = the_args[val];
+# } else {
+# parse_next_arg();
+#------------------------------------------------------------------
+#
+#
+# Finally, a test for the rewritten get_src_buf():
+#
+#$> AWKBUFSIZE=2 make check
+#
+#I get 3 failed tests. Not sure this is of any interest.
+#
+#
+#Thanks,
+#John
--- /dev/null
+BEGIN { for (print 9; 0;); }
--- /dev/null
+BEGIN { FS = "\\" }
+{ print $1, $2 }
--- /dev/null
+BEGIN{FIELDWIDTHS="6 6 6 5";OFS=",";FS=FS}{print $1,$2,$3,$4}
--- /dev/null
+00000113000 00000000000
+00000275000 00000000000
+00000321334 00000000000
+00000048709 00000010000
+00000117000 00000100000
+00000152000 00000138000
+00000000000 00000150000
+00000189425 00000000000
+00000146128 00000000000
+00000146128 00000000000
+00000146128 00000000000
+00000000000 00000050000
+00000000000 00000050000
+00000000000 00000000000
+00000158014 00000000000
+00000113656 00000000000
--- /dev/null
+00000113000,00000000000,,
+00000275000,00000000000,,
+00000321334,00000000000,,
+00000048709,00000010000,,
+00000117000,00000100000,,
+00000152000,00000138000,,
+00000000000,00000150000,,
+00000189425,00000000000,,
+00000146128,00000000000,,
+00000146128,00000000000,,
+00000146128,00000000000,,
+00000000000,00000050000,,
+00000000000,00000050000,,
+00000000000,00000000000,,
+00000158014,00000000000,,
+00000113656,00000000000,,
--- /dev/null
+BEGIN {
+ RS=""; FS="\n";
+ ORS=""; OFS="\n";
+ }
+{
+ split ($2,f," ")
+ print $0;
+}
--- /dev/null
+a b
+c d
+e f
+
+1 2
+3 4
+5 6
--- /dev/null
+a b
+c d
+e f1 2
+3 4
+5 6
\ No newline at end of file
--- /dev/null
+# Date: Wed, 08 Dec 2004 12:59:42 +0600
+# From: Alexander Sashnov <asashnov@sw-soft.com>
+# Subject: addon to gawk test suite
+# Sender: asashnov@sashnov.plesk.ru
+# To: "Arnold D. Robbins" <arnold@skeeve.com>
+# Message-id: <lzy8g9xokh.fsf@sashnov.plesk.ru>
+#
+#
+# Hello, Arnold.
+#
+# I'm hit bug on SuSE 9.1 with awk:
+#
+# vsuse91:~ # echo "a:b:c" | awk '{ print $2 }' 'FS=[ :]'
+# b
+# vsuse91:~ # echo "a:b:c" | awk '{ print $2 }' 'FS=[ :]+'
+# awk: cmd. line:2: fatal: Trailing backslash: /[ :]+/
+#
+# vsuse91:~ # awk --version
+# GNU Awk 3.1.3
+#
+#
+#
+# But on my Debian machine all OK:
+#
+# asashnov@sashnov:~$ echo "a:b:c" | awk '{ print $2 }' 'FS=[ :]'
+# b
+# asashnov@sashnov:~$ echo "a:b:c" | awk '{ print $2 }' 'FS=[ :]+'
+# b
+# asashnov@sashnov:~$ awk --version
+# GNU Awk 3.1.4
+#
+#
+# Need add test for this sample to gawk test suite for avoid this problems in future.
+# --
+# Alexander Sashnov
+# Plesk QA Engineer
+# SWsoft, Inc.
+# E-mail: asashnov@sw-soft.com
+# ICQ UIN: 79404252
+
+{ print $2 }
--- /dev/null
+BEGIN { FS = "\t+" }
+ { print $1, $2 }
--- /dev/null
+# make sure that ; + \n at end after function works
+function foo() { print "foo" } ;
+BEGIN { foo() }
--- /dev/null
+function foo( \
+ foo)
+{
+ print foo
+}
+{ foo() }
--- /dev/null
+gawk: funsmnam.awk:6: fatal: function `foo': can't use function name as parameter name
+EXIT CODE: 2
--- /dev/null
+### ====================================================================
+### @Awk-file{
+### author = "Nelson H. F. Beebe",
+### version = "1.00",
+### date = "09 October 1996",
+### time = "15:57:06 MDT",
+### filename = "journal-toc.awk",
+### address = "Center for Scientific Computing
+### Department of Mathematics
+### University of Utah
+### Salt Lake City, UT 84112
+### USA",
+### telephone = "+1 801 581 5254",
+### FAX = "+1 801 581 4148",
+### URL = "http://www.math.utah.edu/~beebe",
+### checksum = "25092 977 3357 26493",
+### email = "beebe@math.utah.edu (Internet)",
+### codetable = "ISO/ASCII",
+### keywords = "BibTeX, bibliography, HTML, journal table of
+### contents",
+### supported = "yes",
+### docstring = "Create a journal cover table of contents from
+### <at>Article{...} entries in a journal BibTeX
+### .bib file for checking the bibliography
+### database against the actual journal covers.
+### The output can be either plain text, or HTML.
+###
+### Usage:
+### bibclean -max-width 0 BibTeX-file(s) | \
+### bibsort -byvolume | \
+### awk -f journal-toc.awk \
+### [-v HTML=nnn] [-v INDENT=nnn] \
+### [-v BIBFILEURL=url] >foo.toc
+###
+### or if the bibliography is already sorted
+### by volume,
+###
+### bibclean -max-width 0 BibTeX-file(s) | \
+### awk -f journal-toc.awk \
+### [-v HTML=nnn] [-v INDENT=nnn] \
+### [-v BIBFILEURL=url] >foo.toc
+###
+### A non-zero value of the command-line option,
+### HTML=nnn, results in HTML output instead of
+### the default plain ASCII text (corresponding
+### to HTML=0). The
+###
+### The INDENT=nnn command-line option specifies
+### the number of blanks to indent each logical
+### level of HTML. The default is INDENT=4.
+### INDENT=0 suppresses indentation. The INDENT
+### option has no effect when the default HTML=0
+### (plain text output) option is in effect.
+###
+### When HTML output is selected, the
+### BIBFILEURL=url command-line option provides a
+### way to request hypertext links from table of
+### contents page numbers to the complete BibTeX
+### entry for the article. These links are
+### created by appending a sharp (#) and the
+### citation label to the BIBFILEURL value, which
+### conforms with the practice of
+### bibtex-to-html.awk.
+###
+### The HTML output form may be useful as a more
+### compact representation of journal article
+### bibliography data than the original BibTeX
+### file provides. Of course, the
+### table-of-contents format provides less
+### information, and is considerably more
+### troublesome for a computer program to parse.
+###
+### When URL key values are provided, they will
+### be used to create hypertext links around
+### article titles. This supports journals that
+### provide article contents on the World-Wide
+### Web.
+###
+### For parsing simplicity, this program requires
+### that BibTeX
+###
+### key = "value"
+###
+### and
+###
+### @String{name = "value"}
+###
+### specifications be entirely contained on
+### single lines, which is readily provided by
+### the `bibclean -max-width 0' filter. It also
+### requires that bibliography entries begin and
+### end at the start of a line, and that
+### quotation marks, rather than balanced braces,
+### delimit string values. This is a
+### conventional format that again can be
+### guaranteed by bibclean.
+###
+### This program requires `new' awk, as described
+### in the book
+###
+### Alfred V. Aho, Brian W. Kernighan, and
+### Peter J. Weinberger,
+### ``The AWK Programming Language'',
+### Addison-Wesley (1988), ISBN
+### 0-201-07981-X,
+###
+### such as provided by programs named (GNU)
+### gawk, nawk, and recent AT&T awk.
+###
+### The checksum field above contains a CRC-16
+### checksum as the first value, followed by the
+### equivalent of the standard UNIX wc (word
+### count) utility output of lines, words, and
+### characters. This is produced by Robert
+### Solovay's checksum utility.",
+### }
+### ====================================================================
+
+BEGIN { initialize() }
+
+/^ *@ *[Ss][Tt][Rr][Ii][Nn][Gg] *{/ { do_String(); next }
+
+/^ *@ *[Pp][Rr][Ee][Aa][Mm][Bb][Ll][Ee]/ { next }
+
+/^ *@ *[Aa][Rr][Tt][Ii][Cc][Ll][Ee]/ { do_Article(); next }
+
+/^ *@/ { do_Other(); next }
+
+/^ *author *= *\"/ { do_author(); next }
+
+/^ *journal *= */ { do_journal(); next }
+
+/^ *volume *= *\"/ { do_volume(); next }
+
+/^ *number *= *\"/ { do_number(); next }
+
+/^ *year *= *\"/ { do_year(); next }
+
+/^ *month *= */ { do_month(); next }
+
+/^ *title *= *\"/ { do_title(); next }
+
+/^ *pages *= *\"/ { do_pages(); next }
+
+/^ *URL *= *\"/ { do_URL(); next }
+
+/^ *} *$/ { if (In_Article) do_end_entry(); next }
+
+END { terminate() }
+
+
+########################################################################
+# NB: The programming conventions for variables in this program are: #
+# UPPERCASE global constants and user options #
+# Initialuppercase global variables #
+# lowercase local variables #
+# Any deviation is an error! #
+########################################################################
+
+
+function do_Article()
+{
+ In_Article = 1
+
+ Citation_label = $0
+ sub(/^[^\{]*{/,"",Citation_label)
+ sub(/ *, *$/,"",Citation_label)
+
+ Author = ""
+ Title = ""
+ Journal = ""
+ Volume = ""
+ Number = ""
+ Month = ""
+ Year = ""
+ Pages = ""
+ Url = ""
+}
+
+
+function do_author()
+{
+ Author = TeX_to_HTML(get_value($0))
+}
+
+
+function do_end_entry( k,n,parts)
+{
+ n = split(Author,parts," and ")
+ if (Last_number != Number)
+ do_new_issue()
+ for (k = 1; k < n; ++k)
+ print_toc_line(parts[k] " and", "", "")
+ Title_prefix = html_begin_title()
+ Title_suffix = html_end_title()
+ if (html_length(Title) <= (MAX_TITLE_CHARS + MIN_LEADERS)) # complete title fits on line
+ print_toc_line(parts[n], Title, html_begin_pages() Pages html_end_pages())
+ else # need to split long title over multiple lines
+ do_long_title(parts[n], Title, html_begin_pages() Pages html_end_pages())
+}
+
+
+function do_journal()
+{
+ if ($0 ~ /[=] *"/) # have journal = "quoted journal name",
+ Journal = get_value($0)
+ else # have journal = journal-abbreviation,
+ {
+ Journal = get_abbrev($0)
+ if (Journal in String) # replace abbrev by its expansion
+ Journal = String[Journal]
+ }
+ gsub(/\\-/,"",Journal) # remove discretionary hyphens
+}
+
+
+function do_long_title(author,title,pages, last_title,n)
+{
+ title = trim(title) # discard leading and trailing space
+ while (length(title) > 0)
+ {
+ n = html_breakpoint(title,MAX_TITLE_CHARS+MIN_LEADERS)
+ last_title = substr(title,1,n)
+ title = substr(title,n+1)
+ sub(/^ +/,"",title) # discard any leading space
+ print_toc_line(author, last_title, (length(title) == 0) ? pages : "")
+ author = ""
+ }
+}
+
+
+function do_month( k,n,parts)
+{
+ Month = ($0 ~ /[=] *"/) ? get_value($0) : get_abbrev($0)
+ gsub(/[\"]/,"",Month)
+ gsub(/ *# *\\slash *# */," / ",Month)
+ gsub(/ *# *-+ *# */," / ",Month)
+ n = split(Month,parts," */ *")
+ Month = ""
+ for (k = 1; k <= n; ++k)
+ Month = Month ((k > 1) ? " / " : "") \
+ ((parts[k] in Month_expansion) ? Month_expansion[parts[k]] : parts[k])
+}
+
+
+function do_new_issue()
+{
+ Last_number = Number
+ if (HTML)
+ {
+ if (Last_volume != Volume)
+ {
+ Last_volume = Volume
+ print_line(prefix(2) "<BR>")
+ }
+ html_end_toc()
+ html_begin_issue()
+ print_line(prefix(2) Journal "<BR>")
+ }
+ else
+ {
+ print_line("")
+ print_line(Journal)
+ }
+
+ print_line(strip_html(vol_no_month_year()))
+
+ if (HTML)
+ {
+ html_end_issue()
+ html_toc_entry()
+ html_begin_toc()
+ }
+ else
+ print_line("")
+}
+
+
+function do_number()
+{
+ Number = get_value($0)
+}
+
+
+function do_Other()
+{
+ In_Article = 0
+}
+
+
+function do_pages()
+{
+ Pages = get_value($0)
+ sub(/--[?][?]/,"",Pages)
+}
+
+
+function do_String()
+{
+ sub(/^[^\{]*\{/,"",$0) # discard up to and including open brace
+ sub(/\} *$/,"",$0) # discard from optional whitespace and trailing brace to end of line
+ String[get_key($0)] = get_value($0)
+}
+
+
+function do_title()
+{
+ Title = TeX_to_HTML(get_value($0))
+}
+
+
+function do_URL( parts)
+{
+ Url = get_value($0)
+ split(Url,parts,"[,;]") # in case we have multiple URLs
+ Url = trim(parts[1])
+}
+
+
+function do_volume()
+{
+ Volume = get_value($0)
+}
+
+
+function do_year()
+{
+ Year = get_value($0)
+}
+
+
+function get_abbrev(s)
+{ # return abbrev from ``key = abbrev,''
+ sub(/^[^=]*= */,"",s) # discard text up to start of non-blank value
+ sub(/ *,? *$/,"",s) # discard trailing optional whitspace, quote,
+ # optional comma, and optional space
+ return (s)
+}
+
+
+function get_key(s)
+{ # return kay from ``key = "value",''
+ sub(/^ */,"",s) # discard leading space
+ sub(/ *=.*$/,"",s) # discard everthing after key
+
+ return (s)
+}
+
+
+function get_value(s)
+{ # return value from ``key = "value",''
+ sub(/^[^\"]*\" */,"",s) # discard text up to start of non-blank value
+ sub(/ *\",? *$/,"",s) # discard trailing optional whitspace, quote,
+ # optional comma, and optional space
+ return (s)
+}
+
+
+function html_accents(s)
+{
+ if (index(s,"\\") > 0) # important optimization
+ {
+ # Convert common lower-case accented letters according to the
+ # table on p. 169 of in Peter Flynn's ``The World Wide Web
+ # Handbook'', International Thomson Computer Press, 1995, ISBN
+ # 1-85032-205-8. The official table of ISO Latin 1 SGML
+ # entities used in HTML can be found in the file
+ # /usr/local/lib/html-check/lib/ISOlat1.sgml (your path
+ # may differ).
+
+ gsub(/{\\\a}/, "\\à", s)
+ gsub(/{\\'a}/, "\\á", s)
+ gsub(/{\\[\^]a}/,"\\â", s)
+ gsub(/{\\~a}/, "\\ã", s)
+ gsub(/{\\\"a}/, "\\ä", s)
+ gsub(/{\\aa}/, "\\å", s)
+ gsub(/{\\ae}/, "\\æ", s)
+
+ gsub(/{\\c{c}}/,"\\ç", s)
+
+ gsub(/{\\\e}/, "\\è", s)
+ gsub(/{\\'e}/, "\\é", s)
+ gsub(/{\\[\^]e}/,"\\ê", s)
+ gsub(/{\\\"e}/, "\\ë", s)
+
+ gsub(/{\\\i}/, "\\ì", s)
+ gsub(/{\\'i}/, "\\í", s)
+ gsub(/{\\[\^]i}/,"\\î", s)
+ gsub(/{\\\"i}/, "\\ï", s)
+
+ # ignore eth and thorn
+
+ gsub(/{\\~n}/, "\\ñ", s)
+
+ gsub(/{\\\o}/, "\\ò", s)
+ gsub(/{\\'o}/, "\\ó", s)
+ gsub(/{\\[\^]o}/, "\\ô", s)
+ gsub(/{\\~o}/, "\\õ", s)
+ gsub(/{\\\"o}/, "\\ö", s)
+ gsub(/{\\o}/, "\\ø", s)
+
+ gsub(/{\\\u}/, "\\ù", s)
+ gsub(/{\\'u}/, "\\ú", s)
+ gsub(/{\\[\^]u}/,"\\û", s)
+ gsub(/{\\\"u}/, "\\ü", s)
+
+ gsub(/{\\'y}/, "\\ý", s)
+ gsub(/{\\\"y}/, "\\ÿ", s)
+
+ # Now do the same for upper-case accents
+
+ gsub(/{\\\A}/, "\\À", s)
+ gsub(/{\\'A}/, "\\Á", s)
+ gsub(/{\\[\^]A}/, "\\Â", s)
+ gsub(/{\\~A}/, "\\Ã", s)
+ gsub(/{\\\"A}/, "\\Ä", s)
+ gsub(/{\\AA}/, "\\Å", s)
+ gsub(/{\\AE}/, "\\Æ", s)
+
+ gsub(/{\\c{C}}/,"\\Ç", s)
+
+ gsub(/{\\\e}/, "\\È", s)
+ gsub(/{\\'E}/, "\\É", s)
+ gsub(/{\\[\^]E}/, "\\Ê", s)
+ gsub(/{\\\"E}/, "\\Ë", s)
+
+ gsub(/{\\\I}/, "\\Ì", s)
+ gsub(/{\\'I}/, "\\Í", s)
+ gsub(/{\\[\^]I}/, "\\Î", s)
+ gsub(/{\\\"I}/, "\\Ï", s)
+
+ # ignore eth and thorn
+
+ gsub(/{\\~N}/, "\\Ñ", s)
+
+ gsub(/{\\\O}/, "\\Ò", s)
+ gsub(/{\\'O}/, "\\Ó", s)
+ gsub(/{\\[\^]O}/, "\\Ô", s)
+ gsub(/{\\~O}/, "\\Õ", s)
+ gsub(/{\\\"O}/, "\\Ö", s)
+ gsub(/{\\O}/, "\\Ø", s)
+
+ gsub(/{\\\U}/, "\\Ù", s)
+ gsub(/{\\'U}/, "\\Ú", s)
+ gsub(/{\\[\^]U}/, "\\Û", s)
+ gsub(/{\\\"U}/, "\\Ü", s)
+
+ gsub(/{\\'Y}/, "\\Ý", s)
+
+ gsub(/{\\ss}/, "\\ß", s)
+
+ # Others not mentioned in Flynn's book
+ gsub(/{\\'\\i}/,"\\í", s)
+ gsub(/{\\'\\j}/,"j", s)
+ }
+ return (s)
+}
+
+
+function html_begin_issue()
+{
+ print_line("")
+ print_line(prefix(2) "<HR>")
+ print_line("")
+ print_line(prefix(2) "<H1>")
+ print_line(prefix(3) "<A NAME=\"" html_label() "\">")
+}
+
+
+function html_begin_pages()
+{
+ return ((HTML && (BIBFILEURL != "")) ? ("<A HREF=\"" BIBFILEURL "#" Citation_label "\">") : "")
+}
+
+
+function html_begin_pre()
+{
+ In_PRE = 1
+ print_line("<PRE>")
+}
+
+
+function html_begin_title()
+{
+ return ((HTML && (Url != "")) ? ("<A HREF=\"" Url "\">") : "")
+}
+
+
+function html_begin_toc()
+{
+ html_end_toc()
+ html_begin_pre()
+}
+
+
+function html_body( k)
+{
+ for (k = 1; k <= BodyLines; ++k)
+ print Body[k]
+}
+
+function html_breakpoint(title,maxlength, break_after,k)
+{
+ # Return the largest character position in title AFTER which we
+ # can break the title across lines, without exceeding maxlength
+ # visible characters.
+ if (html_length(title) > maxlength) # then need to split title across lines
+ {
+ # In the presence of HTML markup, the initialization of
+ # k here is complicated, because we need to advance it
+ # until html_length(title) is at least maxlength,
+ # without invoking the expensive html_length() function
+ # too frequently. The need to split the title makes the
+ # alternative of delayed insertion of HTML markup much
+ # more complicated.
+ break_after = 0
+ for (k = min(maxlength,length(title)); k < length(title); ++k)
+ {
+ if (substr(title,k+1,1) == " ")
+ { # could break after position k
+ if (html_length(substr(title,1,k)) <= maxlength)
+ break_after = k
+ else # advanced too far, retreat back to last break_after
+ break
+ }
+ }
+ if (break_after == 0) # no breakpoint found by forward scan
+ { # so switch to backward scan
+ for (k = min(maxlength,length(title)) - 1; \
+ (k > 0) && (substr(title,k+1,1) != " "); --k)
+ ; # find space at which to break title
+ if (k < 1) # no break point found
+ k = length(title) # so must print entire string
+ }
+ else
+ k = break_after
+ }
+ else # title fits on one line
+ k = length(title)
+ return (k)
+}
+
+
+
+function html_end_issue()
+{
+ print_line(prefix(3) "</A>")
+ print_line(prefix(2) "</H1>")
+}
+
+
+function html_end_pages()
+{
+ return ((HTML && (BIBFILEURL != "")) ? "</A>" : "")
+}
+
+
+function html_end_pre()
+{
+ if (In_PRE)
+ {
+ print_line("</PRE>")
+ In_PRE = 0
+ }
+}
+
+
+function html_end_title()
+{
+ return ((HTML && (Url != "")) ? "</A>" : "")
+}
+
+
+function html_end_toc()
+{
+ html_end_pre()
+}
+
+
+function html_fonts(s, arg,control_word,k,level,n,open_brace)
+{
+ open_brace = index(s,"{")
+ if (open_brace > 0) # important optimization
+ {
+ level = 1
+ for (k = open_brace + 1; (level != 0) && (k <= length(s)); ++k)
+ {
+ if (substr(s,k,1) == "{")
+ level++
+ else if (substr(s,k,1) == "}")
+ level--
+ }
+
+ # {...} is now found at open_brace ... (k-1)
+ for (control_word in Font_decl_map) # look for {\xxx ...}
+ {
+ if (substr(s,open_brace+1,length(control_word)+1) ~ \
+ ("\\" control_word "[^A-Za-z]"))
+ {
+ n = open_brace + 1 + length(control_word)
+ arg = trim(substr(s,n,k - n))
+ if (Font_decl_map[control_word] == "toupper") # arg -> ARG
+ arg = toupper(arg)
+ else if (Font_decl_map[control_word] != "") # arg -> <TAG>arg</TAG>
+ arg = "<" Font_decl_map[control_word] ">" arg "</" Font_decl_map[control_word] ">"
+ return (substr(s,1,open_brace-1) arg html_fonts(substr(s,k)))
+ }
+ }
+ for (control_word in Font_cmd_map) # look for \xxx{...}
+ {
+ if (substr(s,open_brace - length(control_word),length(control_word)) ~ \
+ ("\\" control_word))
+ {
+ n = open_brace + 1
+ arg = trim(substr(s,n,k - n))
+ if (Font_cmd_map[control_word] == "toupper") # arg -> ARG
+ arg = toupper(arg)
+ else if (Font_cmd_map[control_word] != "") # arg -> <TAG>arg</TAG>
+ arg = "<" Font_cmd_map[control_word] ">" arg "</" Font_cmd_map[control_word] ">"
+ n = open_brace - length(control_word) - 1
+ return (substr(s,1,n) arg html_fonts(substr(s,k)))
+ }
+ }
+ }
+ return (s)
+}
+
+
+function html_header()
+{
+ USER = ENVIRON["USER"]
+ if (USER == "")
+ USER = ENVIRON["LOGNAME"]
+ if (USER == "")
+ USER = "????"
+ "hostname" | getline HOSTNAME
+ "date" | getline DATE
+ ("ypcat passwd | grep '^" USER ":' | awk -F: '{print $5}'") | getline PERSONAL_NAME
+ if (PERSONAL_NAME == "")
+ ("grep '^" USER ":' /etc/passwd | awk -F: '{print $5}'") | getline PERSONAL_NAME
+
+
+ print "<!-- WARNING: Do NOT edit this file. It was converted from -->"
+ print "<!-- BibTeX format to HTML by journal-toc.awk version " VERSION_NUMBER " " VERSION_DATE " -->"
+ print "<!-- on " DATE " -->"
+ print "<!-- for " PERSONAL_NAME " (" USER "@" HOSTNAME ") -->"
+ print ""
+ print ""
+ print "<!DOCTYPE HTML public \"-//IETF//DTD HTML//EN\">"
+ print ""
+ print "<HTML>"
+ print prefix(1) "<HEAD>"
+ print prefix(2) "<TITLE>"
+ print prefix(3) Journal
+ print prefix(2) "</TITLE>"
+ print prefix(2) "<LINK REV=\"made\" HREF=\"mailto:" USER "@" HOSTNAME "\">"
+ print prefix(1) "</HEAD>"
+ print ""
+ print prefix(1) "<BODY>"
+}
+
+
+function html_label( label)
+{
+ label = Volume "(" Number "):" Month ":" Year
+ gsub(/[^A-Za-z0-9():,;.\/\-]/,"",label)
+ return (label)
+}
+
+
+function html_length(s)
+{ # Return visible length of s, ignoring any HTML markup
+ if (HTML)
+ {
+ gsub(/<\/?[^>]*>/,"",s) # remove SGML tags
+ gsub(/&[A-Za-z0-9]+;/,"",s) # remove SGML entities
+ }
+ return (length(s))
+}
+
+
+function html_toc()
+{
+ print prefix(2) "<H1>"
+ print prefix(3) "Table of contents for issues of " Journal
+ print prefix(2) "</H1>"
+ print HTML_TOC
+}
+
+
+function html_toc_entry()
+{
+ HTML_TOC = HTML_TOC " <A HREF=\"#" html_label() "\">"
+ HTML_TOC = HTML_TOC vol_no_month_year()
+ HTML_TOC = HTML_TOC "</A><BR>" "\n"
+}
+
+
+function html_trailer()
+{
+ html_end_pre()
+ print prefix(1) "</BODY>"
+ print "</HTML>"
+}
+
+
+function initialize()
+{
+ # NB: Update these when the program changes
+ VERSION_DATE = "[09-Oct-1996]"
+ VERSION_NUMBER = "1.00"
+
+ HTML = (HTML == "") ? 0 : (0 + HTML)
+
+ if (INDENT == "")
+ INDENT = 4
+
+ if (HTML == 0)
+ INDENT = 0 # indentation suppressed in ASCII mode
+
+ LEADERS = " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
+
+ MAX_TITLE_CHARS = 36 # 36 produces a 79-char output line when there is
+ # just an initial page number. If this is
+ # increased, the LEADERS string may need to be
+ # lengthened.
+
+ MIN_LEADERS = 4 # Minimum number of characters from LEADERS
+ # required when leaders are used. The total
+ # number of characters that can appear in a
+ # title line is MAX_TITLE_CHARS + MIN_LEADERS.
+ # Leaders are omitted when the title length is
+ # between MAX_TITLE_CHARS and this sum.
+
+ MIN_LEADERS_SPACE = " " # must be at least MIN_LEADERS characters long
+
+ Month_expansion["jan"] = "January"
+ Month_expansion["feb"] = "February"
+ Month_expansion["mar"] = "March"
+ Month_expansion["apr"] = "April"
+ Month_expansion["may"] = "May"
+ Month_expansion["jun"] = "June"
+ Month_expansion["jul"] = "July"
+ Month_expansion["aug"] = "August"
+ Month_expansion["sep"] = "September"
+ Month_expansion["oct"] = "October"
+ Month_expansion["nov"] = "November"
+ Month_expansion["dec"] = "December"
+
+ Font_cmd_map["\\emph"] = "EM"
+ Font_cmd_map["\\textbf"] = "B"
+ Font_cmd_map["\\textit"] = "I"
+ Font_cmd_map["\\textmd"] = ""
+ Font_cmd_map["\\textrm"] = ""
+ Font_cmd_map["\\textsc"] = "toupper"
+ Font_cmd_map["\\textsl"] = "I"
+ Font_cmd_map["\\texttt"] = "t"
+ Font_cmd_map["\\textup"] = ""
+
+ Font_decl_map["\\bf"] = "B"
+ Font_decl_map["\\em"] = "EM"
+ Font_decl_map["\\it"] = "I"
+ Font_decl_map["\\rm"] = ""
+ Font_decl_map["\\sc"] = "toupper"
+ Font_decl_map["\\sf"] = ""
+ Font_decl_map["\\tt"] = "TT"
+ Font_decl_map["\\itshape"] = "I"
+ Font_decl_map["\\upshape"] = ""
+ Font_decl_map["\\slshape"] = "I"
+ Font_decl_map["\\scshape"] = "toupper"
+ Font_decl_map["\\mdseries"] = ""
+ Font_decl_map["\\bfseries"] = "B"
+ Font_decl_map["\\rmfamily"] = ""
+ Font_decl_map["\\sffamily"] = ""
+ Font_decl_map["\\ttfamily"] = "TT"
+}
+
+function min(a,b)
+{
+ return (a < b) ? a : b
+}
+
+
+function prefix(level)
+{
+ # Return a prefix of up to 60 blanks
+
+ if (In_PRE)
+ return ("")
+ else
+ return (substr(" ", \
+ 1, INDENT * level))
+}
+
+
+function print_line(line)
+{
+ if (HTML) # must buffer in memory so that we can accumulate TOC
+ Body[++BodyLines] = line
+ else
+ print line
+}
+
+
+function print_toc_line(author,title,pages, extra,leaders,n,t)
+{
+ # When we have a multiline title, the hypertext link goes only
+ # on the first line. A multiline hypertext link looks awful
+ # because of long underlines under the leading indentation.
+
+ if (pages == "") # then no leaders needed in title lines other than last one
+ t = sprintf("%31s %s%s%s", author, Title_prefix, title, Title_suffix)
+ else # last title line, with page number
+ {
+ n = html_length(title) # potentially expensive
+ extra = n % 2 # extra space for aligned leader dots
+ if (n <= MAX_TITLE_CHARS) # then need leaders
+ leaders = substr(LEADERS, 1, MAX_TITLE_CHARS + MIN_LEADERS - extra - \
+ min(MAX_TITLE_CHARS,n))
+ else # title (almost) fills line, so no leaders
+ leaders = substr(MIN_LEADERS_SPACE,1, \
+ (MAX_TITLE_CHARS + MIN_LEADERS - extra - n))
+ t = sprintf("%31s %s%s%s%s%s %4s", \
+ author, Title_prefix, title, Title_suffix, \
+ (extra ? " " : ""), leaders, pages)
+ }
+
+ Title_prefix = "" # forget any hypertext
+ Title_suffix = "" # link material
+
+ # Efficency note: an earlier version accumulated the body in a
+ # single scalar like this: "Body = Body t". Profiling revealed
+ # this statement as the major hot spot, and the change to array
+ # storage made the program more than twice as fast. This
+ # suggests that awk might benefit from an optimization of
+ # "s = s t" that uses realloc() instead of malloc().
+ if (HTML)
+ Body[++BodyLines] = t
+ else
+ print t
+}
+
+
+function protect_SGML_characters(s)
+{
+ gsub(/&/,"\\&",s) # NB: this one MUST be first
+ gsub(/</,"\\<",s)
+ gsub(/>/,"\\>",s)
+ gsub(/\"/,"\\"",s)
+ return (s)
+}
+
+
+function strip_braces(s, k)
+{ # strip non-backslashed braces from s and return the result
+
+ return (strip_char(strip_char(s,"{"),"}"))
+}
+
+
+function strip_char(s,c, k)
+{ # strip non-backslashed instances of c from s, and return the result
+ k = index(s,c)
+ if (k > 0) # then found the character
+ {
+ if (substr(s,k-1,1) != "\\") # then not backslashed char
+ s = substr(s,1,k-1) strip_char(substr(s,k+1),c) # so remove it (recursively)
+ else # preserve backslashed char
+ s = substr(s,1,k) strip_char(s,k+1,c)
+ }
+ return (s)
+}
+
+
+function strip_html(s)
+{
+ gsub(/<\/?[^>]*>/,"",s)
+ return (s)
+}
+
+
+function terminate()
+{
+ if (HTML)
+ {
+ html_end_pre()
+
+ HTML = 0 # NB: stop line buffering
+ html_header()
+ html_toc()
+ html_body()
+ html_trailer()
+ }
+}
+
+
+function TeX_to_HTML(s, k,n,parts)
+{
+ # First convert the four SGML reserved characters to SGML entities
+ if (HTML)
+ {
+ gsub(/>/, "\\>", s)
+ gsub(/</, "\\<", s)
+ gsub(/"/, "\\"", s)
+ }
+
+ gsub(/[$][$]/,"$$",s) # change display math to triple dollars for split
+ n = split(s,parts,/[$]/)# split into non-math (odd) and math (even) parts
+
+ s = ""
+ for (k = 1; k <= n; ++k) # unbrace non-math part, leaving math mode intact
+ s = s ((k > 1) ? "$" : "") \
+ ((k % 2) ? strip_braces(TeX_to_HTML_nonmath(parts[k])) : \
+ TeX_to_HTML_math(parts[k]))
+
+ gsub(/[$][$][$]/,"$$",s) # restore display math
+
+ return (s)
+}
+
+
+function TeX_to_HTML_math(s)
+{
+ # Mostly a dummy for now, but HTML 3 could support some math translation
+
+ gsub(/\\&/,"\\&",s) # reduce TeX ampersands to SGML entities
+
+ return (s)
+}
+
+
+function TeX_to_HTML_nonmath(s)
+{
+ if (index(s,"\\") > 0) # important optimization
+ {
+ gsub(/\\slash +/,"/",s) # replace TeX slashes with conventional ones
+ gsub(/ *\\emdash +/," --- ",s) # replace BibNet emdashes with conventional ones
+ gsub(/\\%/,"%",s) # reduce TeX percents to conventional ones
+ gsub(/\\[$]/,"$",s) # reduce TeX dollars to conventional ones
+ gsub(/\\#/,"#",s) # reduce TeX sharps to conventional ones
+
+ if (HTML) # translate TeX markup to HTML
+ {
+ gsub(/\\&/,"\\&",s) # reduce TeX ampersands to SGML entities
+ s = html_accents(s)
+ s = html_fonts(s)
+ }
+ else # plain ASCII text output: discard all TeX markup
+ {
+ gsub(/\\\&/, "\\&", s) # reduce TeX ampersands to conventional ones
+
+ gsub(/\\[a-z][a-z] +/,"",s) # remove TeX font changes
+ gsub(/\\[^A-Za-z]/,"",s) # remove remaining TeX control symbols
+ }
+ }
+ return (s)
+}
+
+
+function trim(s)
+{
+ gsub(/^[ \t]+/,"",s)
+ gsub(/[ \t]+$/,"",s)
+ return (s)
+}
+
+
+function vol_no_month_year()
+{
+ return ("Volume " wrap(Volume) ", Number " wrap(Number) ", " wrap(Month) ", " wrap(Year))
+}
+
+
+function wrap(value)
+{
+ return (HTML ? ("<STRONG>" value "</STRONG>") : value)
+}
--- /dev/null
+%%% ====================================================================
+%%% BibTeX-file{
+%%% author = "Nelson H. F. Beebe",
+%%% version = "2.09",
+%%% date = "26 March 1997",
+%%% time = "08:21:19 MST",
+%%% filename = "cacm1970.bib",
+%%% address = "Center for Scientific Computing
+%%% Department of Mathematics
+%%% University of Utah
+%%% Salt Lake City, UT 84112
+%%% USA",
+%%% telephone = "+1 801 581 5254",
+%%% FAX = "+1 801 581 4148",
+%%% checksum = "50673 40670 196033 1787829",
+%%% email = "beebe at math.utah.edu (Internet)",
+%%% codetable = "ISO/ASCII",
+%%% keywords = "bibliography, CACM, Communications of the
+%%% ACM",
+%%% supported = "yes",
+%%% docstring = "This is a bibliography of the journal
+%%% Communications of the ACM, covering
+%%% (incompletely) 1970 -- 1979.
+%%%
+%%% At version 2.09, the year coverage looked
+%%% like this:
+%%%
+%%% 1961 ( 1) 1972 (168) 1983 ( 0)
+%%% 1962 ( 1) 1973 (158) 1984 ( 0)
+%%% 1963 ( 2) 1974 (127) 1985 ( 2)
+%%% 1964 ( 2) 1975 (107) 1986 ( 0)
+%%% 1965 ( 1) 1976 ( 97) 1987 ( 0)
+%%% 1966 ( 2) 1977 (117) 1988 ( 0)
+%%% 1967 ( 1) 1978 (118) 1989 ( 0)
+%%% 1968 ( 1) 1979 ( 78) 1990 ( 2)
+%%% 1969 ( 3) 1980 ( 1) 1991 ( 4)
+%%% 1970 (157) 1981 ( 2) 1992 ( 1)
+%%% 1971 (104) 1982 ( 1)
+%%%
+%%% Article: 1252
+%%% Book: 2
+%%% InProceedings: 1
+%%% Manual: 1
+%%% MastersThesis: 1
+%%% PhdThesis: 1
+%%%
+%%% Total entries: 1258
+%%%
+%%% The size of the original cacm.bib file
+%%% covering 1958--1996 became too large (about
+%%% 4000 entries) for BibTeX and TeX to handle,
+%%% so at version 1.44, it was split into
+%%% cacm1950.bib, cacm1960.bib, cacm1970.bib,
+%%% cacm1980.bib, and cacm1990.bib, each covering
+%%% the decade starting with the year embedded in
+%%% the filename. Version numbers for these
+%%% files begin at 2.00.
+%%%
+%%% Volumes from the 1990s average more than 200
+%%% articles yearly, so a complete bibliography
+%%% for this journal could contain more than 6000
+%%% entries from 1958 to 2000.
+%%%
+%%% These bibliographies also include ACM
+%%% Algorithms 1--492. For Algorithms 493--686,
+%%% including Algorithm 568, published in ACM
+%%% Transactions on Programming Languages and
+%%% Systems (TOPLAS), see the companion
+%%% bibliographies, toms.bib and toplas.bib.
+%%%
+%%% All published Remarks and Corrigenda are
+%%% cross-referenced in both directions, so
+%%% that citing a paper will automatically
+%%% generate citations for those Remarks and
+%%% Corrigenda. Cross-referenced entries are
+%%% duplicated in cacm19*.bib and toms.bib, so
+%%% that each is completely self-contained.
+%%%
+%%% Source code for ACM Algorithms from 380
+%%% onwards, with some omissions, is available
+%%% via the Netlib service at
+%%% http://netlib.ornl.gov/, and
+%%% ftp://netlib.bell-labs.com/netlib/toms.
+%%%
+%%% There is a World Wide Web search facility
+%%% for articles published in this journal from
+%%% 1959 to 1979 at
+%%% http://ciir.cs.umass.edu/cgi-bin/web_query_form/public/cacm2.1.
+%%%
+%%% The initial draft of entries for 1981 --
+%%% 1990 was extracted from the ACM Computing
+%%% Archive CD ROM for the 1980s, with manual
+%%% corrections and additions. Additions were
+%%% then made from all of the bibliographies in
+%%% the TeX User Group collection, from
+%%% bibliographies in the author's personal
+%%% files, from the Compendex database
+%%% (1970--1979), from the IEEE INSPEC database
+%%% (1970--1979), from tables of contents
+%%% information at http://www.acm.org/pubs/cacm/,
+%%% from Zentralblatt fur Mathematik Mathematics
+%%% Abstracts at
+%%% http://www.emis.de/cgi-bin/MATH/, from
+%%% bibliographies at Internet host
+%%% netlib.bell-labs.com, and from the computer
+%%% science bibliography collection on
+%%% ftp.ira.uka.de in /pub/bibliography to which
+%%% many people of have contributed. The
+%%% snapshot of this collection was taken on
+%%% 5-May-1994, and it consists of 441 BibTeX
+%%% files, 2,672,675 lines, 205,289 entries, and
+%%% 6,375 <at>String{} abbreviations, occupying
+%%% 94.8MB of disk space.
+%%%
+%%% Numerous errors in the sources noted above
+%%% have been corrected. Spelling has been
+%%% verified with the UNIX spell and GNU ispell
+%%% programs using the exception dictionary
+%%% stored in the companion file with extension
+%%% .sok.
+%%%
+%%% BibTeX citation tags are uniformly chosen
+%%% as name:year:abbrev, where name is the
+%%% family name of the first author or editor,
+%%% year is a 4-digit number, and abbrev is a
+%%% 3-letter condensation of important title
+%%% words. Citation tags were automatically
+%%% generated by software developed for the
+%%% BibNet Project.
+%%%
+%%% In this bibliography, entries are sorted in
+%%% publication order within each journal,
+%%% using bibsort -byvolume.
+%%%
+%%% The checksum field above contains a CRC-16
+%%% checksum as the first value, followed by the
+%%% equivalent of the standard UNIX wc (word
+%%% count) utility output of lines, words, and
+%%% characters. This is produced by Robert
+%%% Solovay's checksum utility.",
+%%% }
+%%% ====================================================================
+
+@Preamble{"\input bibnames.sty " # "\input path.sty " # "\def \TM {${}^{\sc TM}$} " # "\hyphenation{ al-pha-mer-ic Balz-er Blom-quist Bo-ta-fo-go Bran-din Brans-comb Bu-tera Chris-tina Christ-o-fi-des Col-lins Cor-dell data-base econ-omies Fletch-er
+ flow-chart flow-charts Fry-styk ge-dank-en Gar-fink-el Ge-ha-ni Glush-ko Goud-reau Gua-dan-go Hari-di Haw-thorn Hem-men-ding-er Hor-o-witz Hour-vitz Hirsch-berg Ike-da Ka-chi-tvi-chyan-u-kul Kat-ze-nel-son Kitz-miller Ko-ba-yashi Le-Me-tay-er Ken-ne-dy
+ Law-rence Mac-kay Mai-net-ti Mar-sa-glia Max-well Mer-ner Mo-ran-di Na-ray-an New-ell Nich-ols para-digm pat-ent-ed Phi-lo-kyp-rou Prep-a-ra-ta pseu-do-chain-ing QUIK-SCRIPT Rad-e-mach-er re-eval-u-a-tion re-wind Ros-witha Scheu-er-mann Schwach-heim
+ Schob-bens Schon-berg Sho-sha-ni Si-tha-ra-ma Skwa-rec-ki Streck-er Strin-gi-ni Tes-ler Te-zu-ka Teu-ho-la Till-quist Town-send Tsi-chri-tzis Tur-ski Vuille-min Wald-ing-er Za-bo-row-ski Za-mora }"}
+
+%=======================================================================
+% Acknowledgement abbreviations:
+
+@String{ack-nhfb = "Nelson H. F. Beebe, Center for Scientific Computing, Department of Mathematics, University of Utah, Salt Lake City, UT 84112, USA, Tel: +1 801 581 5254, FAX: +1 801 581 4148, e-mail: \path|beebe@math.utah.edu|"}
+
+@String{ack-nj = "Norbert Juffa, 2445 Mission College Blvd. Santa Clara, CA 95054 USA email: \path=norbert@iit.com="}
+
+%=======================================================================
+% Journal abbreviations:
+
+@String{j-CACM = "Communications of the ACM"}
+
+@String{j-COMP-SURV = "Computing Surveys"}
+
+@String{j-J-ACM = "Journal of the ACM"}
+
+@String{j-MANAGEMENT-SCIENCE = "Management Science"}
+
+@String{j-SIAM-J-COMPUT = "SIAM Journal of Computing"}
+
+@String{j-SPE = "Software --- Practice and Experience"}
+
+@String{j-TOMS = "ACM Transactions on Mathematical Software"}
+
+%=======================================================================
+% Publisher abbreviations:
+
+@String{pub-ANSI = "American National Standards Institute"}
+
+@String{pub-ANSI:adr = "1430 Broadway, New York, NY 10018, USA"}
+
+@String{pub-AW = "Ad{\-d}i{\-s}on-Wes{\-l}ey"}
+
+@String{pub-AW:adr = "Reading, MA, USA"}
+
+@String{pub-SUCSLI = "Stanford University Center for the Study of Language and Information"}
+
+@String{pub-SUCSLI:adr = "Stanford, CA, USA"}
+
+@String{pub-SV = "Spring{\-}er-Ver{\-}lag"}
+
+@String{pub-SV:adr = "Berlin, Germany~/ Heidelberg, Germany~/ London, UK~/ etc."}
+@MastersThesis{Dittmer:1976:IEP,
+ author = "Ingo Dittmer",
+ title = "{Implementation eines Einschrittcompilers f{\"u}r die Progammiersprache PASCAL auf der Rechenanlage IBM\slash 360 der Universit{\"a}t M{\"u}nster}. ({English} title: Implementation of a One-Step Compiler for the Programming Language
+ {PASCAL} on the {IBM}\slash 360 of the {University of Muenster})",
+ type = "Diplomearbeit",
+ school = "Universit{\"a}t M{\"u}nster",
+ address = "M{\"u}nster, Germany",
+ pages = "??",
+ month = "??",
+ year = "1976",
+ bibdate = "Sat Feb 17 13:24:29 1996",
+ note = "Diplomearbeit M{\"u}nster 1976 und doert angegebene Literatur (English: Muenster diploma work 1976 and the literature cited therein). The hashing method was rediscovered fourteen years later by Pearson \cite{Pearson:1990:FHV}, and then
+ commented on by several authors \cite{Dittmer:1991:NFH,Savoy:1991:NFH,Litsios:1991:NFH,Pearson:1991:NFH}.",
+ acknowledgement = ack-nhfb,
+ xxnote = "Cannot find in Dissertation Abstracts, European.",
+}
--- /dev/null
+BEGIN { a = "this is a test of gawk"
+ b = gensub(/(this).*(test).*(gawk)/, "3 = <\\3>, 2 = <\\2>, 1 = <\\1>", 1, a)
+ print b
+}
+NR == 1 { print gensub(/b/, "BB", 2) }
+NR == 2 { print gensub(/c/, "CC", "global") }
+END { print gensub(/foo/, "bar", 1, "DON'T PANIC") }
--- /dev/null
+a b c a b c a b c
+a b c a b c a b c
--- /dev/null
+3 = <gawk>, 2 = <test>, 1 = <this>
+a b c a BB c a b c
+a b CC a b CC a b CC
+DON'T PANIC
--- /dev/null
+BEGIN {
+ print gensub("x","y",2,"xx")
+ print gensub("x","y","2","xx")
+ print gensub("x","y","a","xx")
+}
--- /dev/null
+xy
+xy
+yx
--- /dev/null
+BEGIN {
+ x = y = "s"
+ a = (getline x y)
+ print a, x
+ a = (getline x + 1)
+ print a, x
+ a = (getline x - 2)
+ print a, x
+
+ cmd = "echo A"
+ a = (cmd | getline x y)
+ close(cmd)
+ print a, x
+
+ cmd = "echo B"
+ a = (cmd | getline x + 1)
+ close(cmd)
+ print a, x
+
+ cmd = "echo C"
+ a = (cmd | getline x - 2)
+ close(cmd)
+ print a, x
+
+ cmd = "echo D"
+ a = cmd | getline x
+ close(cmd)
+ print a, x
+}
--- /dev/null
+1s A
+2 B
+-1 C
+1s A
+2 B
+-1 C
+1 D
--- /dev/null
+BEGIN { while( getline > 0) { print } }
--- /dev/null
+BEGIN { while( getline > 0) { print } }
+BEGIN { while( getline > 0) { print } }
--- /dev/null
+BEGIN {
+ cmd = "echo 3"
+ y = 7
+ cmd | getline x y
+ close(cmd)
+ print (cmd | getline x y)
+}
--- /dev/null
+#Date: Tue, 21 Dec 1999 16:11:07 +0100
+#From: Daniel Schnell <Daniel.Schnell.GP@icn.siemens.de>
+#To: bug-gnu-utils@gnu.org
+#CC: arnold@gnu.org
+#Subject: BUG in gawk (version 3.0.4 linux, windows): Text mangeling in between
+
+# search for "@K@CODE" segment
+
+$0 ~ /@K@CODE/ {
+ # get next record
+ getline temp
+ printf ("@K@CODE\n")
+ printf ("%s\n",temp)
+ }
+
+$0 !~ /@K@CODE/ {
+ printf ("%s\n", $0)
+ }
--- /dev/null
+EXTRA_INFO.TYP3.EC := EC;
+EXTRA_INFO.TYP3.TEXT:= 'CONNECT_SERVICE TO OAM FAILED';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C003', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_SWERR, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+917596041
+@K@NAME
+T_ERR4_1
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+MP/NSEI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: MP/NSEI-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903219
+@K@NAME
+T_ERR4_2
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+MP/NSVCI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: MP/NSVCI-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903222
+@K@NAME
+T_ERR4_3
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+NSEI/NSVCI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: NSEI/NSVC-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903226
+@K@NAME
+TR_RESET
+@K@INSCRIPT
+RESTART_
+TNS_RESET_
+TIMER
+@K@CODE
+/* TIMER EVENT DESCRIPTOR STILL THERE */
+
+/* INITIALIZATION OF THE TIMER-EVENT-DESCRIPTOR STILL VALID */
+NSVCI_CON_PTR->.TIM_EVD_PTR->.TIMER:= TNS_RESET_MAP;
+
+/* START TIMER */
+G9PX508_START_TIMER_P
+(
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+@K@FREEZE
+924684867
+@K@NAME
+TX_AUDIT
+@K@INSCRIPT
+FOR
+AUDIT
+
+@K@NAME
+M_BLKOACKM
+@K@INSCRIPT
+NS_
+BLOCK_ACK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+
+IF
+/* 'OTHER' ALIVE NSVC TO THIS NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+THEN
+/* USE THIS 'OTHER' FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+/* NSEI TO BE USED FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+/* NSVCI TO BE USED FOR TRANSPORT */
+ELSE
+/* USE AFFECTED NSVC AGAIN FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+FI;
+
+
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D3);
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR2_NS_BLOCK_ACK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D3.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938805885
+@K@NAME
+T_RCTRUE
+@K@INSCRIPT
+RC
+=
+TRUE
+@K@CODE
+RC:= TRUE;
+
+@K@FREEZE
+922176328
+@K@NAME
+M_AC_SBVCN
+@K@INSCRIPT
+G9IBME0_
+ACT_
+SIGN_BVC_C
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME0_ACT_SIGN_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):= EVD_PTR->.KEYS.INT_ARR(0);
+TX_EVD_PTR->.KEYS.INT_ARR(1):= SIGN_BVCI;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938788211
+@K@NAME
+T_RC_EOD
+@K@INSCRIPT
+RC
+=
+END OF DATA
+
+@K@CODE
+RC:= G9IBSM4_RC_END_OF_DATA;
+
+@K@FREEZE
+921083785
+@K@NAME
+T_RC_EMP
+@K@INSCRIPT
+RC
+=
+EMPTY
+
+@K@CODE
+RC:= G9IBSM4_RC_EMPTY;
+
+@K@FREEZE
+921083757
+@K@NAME
+T_RC_ERR
+@K@INSCRIPT
+RC
+=
+ERROR
+
+@K@CODE
+RC:= G9IBSM4_RC_ERROR;
+
+@K@FREEZE
+921083731
+@K@NAME
+S_UNUSED
+@K@INSCRIPT
+G9IBSM0_
+UNUSED
+@K@CODE
+
+
+@K@FREEZE
+919416670
+@K@NAME
+TA_UNBLOCK
+@K@INSCRIPT
+START_
+TNS_UNBLOCK_
+TIMER
+@K@CODE
+/* GET TIMER-EVENT DESCRIPTOR */
+G9PB513_GET_TIMER_EV_DESCR_P
+(
+SID_GBNSVC,
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+/* INITIALIZATION OF THE TIMER-EVENT-DESCRIPTOR */
+NSVCI_CON_PTR->.TIM_EVD_PTR->.EVENT_CMD:= G9IBSE4_TO_TNS_C;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.EVENT_DESTINATION:= GBNSVC_HANDLE;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.TIMER:= TNS_UNBLOCK_MAP;
+
+/* START TIMER */
+G9PX508_START_TIMER_P
+(
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+@K@FREEZE
+924686210
+@K@NAME
+M_BLK_ACKM
+@K@INSCRIPT
+NS_
+BLOCK_ACK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D3);
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR2_NS_BLOCK_ACK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D3.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+926348442
+@K@NAME
+TA_NXTALIV
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+ALIVE'
+@K@CODE
+IF
+/* ALIVE NSVC TO THE NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+
+THEN
+/* TAKE NEXT ELEMENT IN THE LINKED LIST AS THE NEXT ALIVE NSVC */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR:=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.NEXT_ALV_NSVCI_CON_PTR;
+
+FI;
+
+@K@FREEZE
+938801086
+@K@NAME
+M_DE_CBVCN
+@K@INSCRIPT
+G9IBME2_
+DEACT_
+CELL_BVC_C
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME2_DEACT_CELL_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+TX_EVD_PTR->.KEYS.INT_ARR(1):= EVD_PTR->.ADD_DATA(3);
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+933318270
+@K@NAME
+TA_NXTRESP
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+RESPONSIBLE'
+@K@CODE
+NSEI_CON_PTR->.NEXT_RESP_NSVCI_CON_PTR:=
+ NSEI_CON_PTR->.NEXT_RESP_NSVCI_CON_PTR->.NEXT_LSP_NSVCI_CON_PTR;
+
+
+@K@FREEZE
+938005006
+@K@NAME
+TA_NXTSUBS
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+SUBSTITUTE'
+@K@CODE
+NSEI_CON_PTR->.NEXT_SUBS_NSVCI_CON_PTR:=
+ NSEI_CON_PTR->.NEXT_SUBS_NSVCI_CON_PTR->.NEXT_UBL_NSVCI_CON_PTR;
+
+@K@NAME
+M_BLK_O__M
+@K@INSCRIPT
+NS_
+BLOCK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+
+IF
+/* 'OTHER' ALIVE NSVC TO THIS NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+THEN
+/* USE THIS 'OTHER' FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+/* NSEI TO BE USED FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+/* NSVCI TO BE USED FOR TRANSPORT */
+ELSE
+/* USE AFFECTED NSVC AGAIN FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+FI;
+
+
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D2);
+
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR1_NS_BLOCK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D2.CAUSE_TLV.CAUSE_VAL:=
+ G9IBBA2_NS_TRANSIT_NETWORK_FAILURE; /* CAUSE FOR BLOCK */
+NS_PDU_PTR->.D2.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+GSM 8.16 CHAP. 7.2:
+THE NS-BLOCK-PDU MAY BE SENT IN ANY ALIVE
+(BLOCKED OR UNBLOCKED) NS-VC...
+@K@FREEZE
+938803215
+@K@NAME
+M_DE_SBVCN
+@K@INSCRIPT
+G9IBME1_
+DEACT_
+SIGN_BVC_C
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME1_DEACT_SIGN_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):= EVD_PTR->.KEYS.INT_ARR(0);
+TX_EVD_PTR->.KEYS.INT_ARR(1):= SIGN_BVCI;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938788201
+@K@NAME
+M_OAME401M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSE */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSE;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSE_ID:= EVD_PTR->.KEYS.INT_ARR(0); /*
+USED NSEI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935766108
+@K@NAME
+M_OAME402M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.KEYS.INT_ARR(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935766407
+@K@NAME
+M_OAME411M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_ACK_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSE */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSE;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSE_ID:= EVD_PTR->.KEYS.INT_ARR(0); /*
+USED NSEI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935767332
+@K@NAME
+M_OAME412M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_ACK_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.KEYS.INT_ARR(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935767189
+@K@NAME
+C_CON
+@K@INSCRIPT
+RC_DB
+@K@CODE
+RC_DB
+
+@K@FREEZE
+922176673
+@K@NAME
+M_BLK____M
+@K@INSCRIPT
+NS_
+BLOCK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D2);
+
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR1_NS_BLOCK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D2.CAUSE_TLV.CAUSE_VAL:=
+ G9IBBA2_NS_OAM_INTERVENTION; /* CAUSE FOR BLOCK */
+NS_PDU_PTR->.D2.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+GSM 8.16 CHAP. 7.2:
+THE NS-BLOCK-PDU MAY BE SENT IN ANY ALIVE
+(BLOCKED OR UNBLOCKED) NS-VC...
+@K@FREEZE
+926348613
+@K@NAME
+S_BLOCKED
+@K@INSCRIPT
+G9IBSM0_
+BLOCKED
+@K@CODE
+
+
+@K@FREEZE
+922176496
+@K@NAME
+D_CON
+@K@INSCRIPT
+CONTEXT
+GOT
+@K@CODE
+RC_DB = G9IBSR0_RC_OK
+
+@K@FREEZE
+921772339
+@K@NAME
+M_OAME901M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+UBL->BLK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_ENABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970975
+@K@NAME
+M_OAME902M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+UBL->BLK
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_DISABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970987
+@K@NAME
+M_OAME10SM
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@NAME
+M_OAME911M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+BLK->UBL
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_ENABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970996
+@K@NAME
+M_OAME20SM
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@NAME
+M_OAME10_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443813
+@K@NAME
+D_SEM
+@K@INSCRIPT
+CALL_SEM
+=
+TRUE
+@K@CODE
+CALL_SEM = TRUE
+
+@K@FREEZE
+922176624
+@K@NAME
+D_N_0
+@K@INSCRIPT
+N = 0
+
+@K@CODE
+NSVCI_CON_PTR->.N = 0
+
+@K@FREEZE
+921511000
+@K@NAME
+M_OAME12_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443829
+@K@NAME
+M_OAME21_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ FALSE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443856
+@K@NAME
+M_OAME13_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443838
+@K@NAME
+M_OAME22_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443864
+@K@NAME
+M_OAME30_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FORM_BSS
+RESET_PROCEDURE
+
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_RESET_PROCEDURE;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175973
+@K@NAME
+M_OAME31_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FROM_BSS
+BLOCK_PROCEDURE
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_BLOCK_PROCEDURE;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175976
+@K@NAME
+M_OAME32_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FROM_BSS
+UNBLOCK_PROCEDURE
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_UNBLOCK_PROCEDURE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175980
+@K@NAME
+M_OAME42_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+BLOCK_PDU
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.ADD_DATA(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_BLOCK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.KEYS.INT_ARR(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.KEYS.INT_ARR(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+934296141
+@K@NAME
+M_OAME50_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+STATUS_PDU_CONTAINS_ERROR_INFO
+RECEIVED
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR-CAUSE = STATUS_PDU_CONTAINS_ERROR_INFO */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_STATUS_PDU_CONTAINS_ERROR_INFO;
+/* ADDITIONAL_STATUS_PDU_INFO */
+INT_CAUSE_PTR.INT_PTR:= ADDR(EVD_PTR->.ADD_DATA(2));
+OAM_MSG_PTR->.ADDITIONAL_STATUS_PDU_INFO:=
+ INT_CAUSE_PTR.CAUSE_PTR->; /* CAUSE */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+NICHT OK
+
+@K@FREEZE
+934298924
+@K@NAME
+M_OAME43_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+BLOCK_ACK_PDU
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.ADD_DATA(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_BLOCK_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.KEYS.INT_ARR(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.KEYS.INT_ARR(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+934297710
--- /dev/null
+EXTRA_INFO.TYP3.EC := EC;
+EXTRA_INFO.TYP3.TEXT:= 'CONNECT_SERVICE TO OAM FAILED';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C003', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_SWERR, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+917596041
+@K@NAME
+T_ERR4_1
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+MP/NSEI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: MP/NSEI-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903219
+@K@NAME
+T_ERR4_2
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+MP/NSVCI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: MP/NSVCI-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903222
+@K@NAME
+T_ERR4_3
+@K@INSCRIPT
+ERROR_HANDLING:
+DB_OVERFLOW
+NSEI/NSVCI
+@K@CODE
+/***@@@ ERROR ***/
+/*@@ERRORTEXT
+*@ DB-OVERFLOW
+*@
+*@
+*@@DESCRIPTION
+*@ THE INSTANCE-CREATION WAS NOT POSSIBLE
+*@ BECAUSE THE DATABASE WOULD OVERFLOW
+*@
+*@@EXTRA INFO
+*@ (EXTRA_INFO_4_STRUCT)
+*@ NSEI
+*@ NSVCI
+*@ TEXT
+*@
+*/
+
+EXTRA_INFO.TYP4.NSEI := EVD_PTR->.KEYS.INT_ARR(0);
+EXTRA_INFO.TYP4.NSVCI:= EVD_PTR->.KEYS.INT_ARR(1);
+EXTRA_INFO.TYP4.TEXT := 'NSVC-HAND.: NSEI/NSVC-OVERFLOW';
+
+G9PXYA1S!G9TE500_EHP_P(
+'G9IBSA1C004', /*@@ID*/
+G9PXYA1S!G9TE102_ERR_CLASS_ESC_MAX_ANY, /*@@CLASS*/
+ADDR(EXTRA_INFO.ERROR_HANDLER), /* EXTRA-INFO ADDR */
+G9PXYA1S!G9TE100_GB_LM, /* USER-ID */
+NULL /* OPTIONAL-SWET-INFO ADDR */
+);
+/***@@@ END OF ERROR ***/
+
+@K@FREEZE
+920903226
+@K@NAME
+TR_RESET
+@K@INSCRIPT
+RESTART_
+TNS_RESET_
+TIMER
+@K@CODE
+/* TIMER EVENT DESCRIPTOR STILL THERE */
+
+/* INITIALIZATION OF THE TIMER-EVENT-DESCRIPTOR STILL VALID */
+NSVCI_CON_PTR->.TIM_EVD_PTR->.TIMER:= TNS_RESET_MAP;
+
+/* START TIMER */
+G9PX508_START_TIMER_P
+(
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+@K@FREEZE
+924684867
+@K@NAME
+TX_AUDIT
+@K@INSCRIPT
+FOR
+AUDIT
+
+@K@NAME
+M_BLKOACKM
+@K@INSCRIPT
+NS_
+BLOCK_ACK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+
+IF
+/* 'OTHER' ALIVE NSVC TO THIS NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+THEN
+/* USE THIS 'OTHER' FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+/* NSEI TO BE USED FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+/* NSVCI TO BE USED FOR TRANSPORT */
+ELSE
+/* USE AFFECTED NSVC AGAIN FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+FI;
+
+
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D3);
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR2_NS_BLOCK_ACK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D3.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938805885
+@K@NAME
+T_RCTRUE
+@K@INSCRIPT
+RC
+=
+TRUE
+@K@CODE
+RC:= TRUE;
+
+@K@FREEZE
+922176328
+@K@NAME
+M_AC_SBVCN
+@K@INSCRIPT
+G9IBME0_
+ACT_
+SIGN_BVC_C
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME0_ACT_SIGN_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):= EVD_PTR->.KEYS.INT_ARR(0);
+TX_EVD_PTR->.KEYS.INT_ARR(1):= SIGN_BVCI;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938788211
+@K@NAME
+T_RC_EOD
+@K@INSCRIPT
+RC
+=
+END OF DATA
+
+@K@CODE
+RC:= G9IBSM4_RC_END_OF_DATA;
+
+@K@FREEZE
+921083785
+@K@NAME
+T_RC_EMP
+@K@INSCRIPT
+RC
+=
+EMPTY
+
+@K@CODE
+RC:= G9IBSM4_RC_EMPTY;
+
+@K@FREEZE
+921083757
+@K@NAME
+T_RC_ERR
+@K@INSCRIPT
+RC
+=
+ERROR
+
+@K@CODE
+RC:= G9IBSM4_RC_ERROR;
+
+@K@FREEZE
+921083731
+@K@NAME
+S_UNUSED
+@K@INSCRIPT
+G9IBSM0_
+UNUSED
+@K@CODE
+
+
+@K@FREEZE
+919416670
+@K@NAME
+TA_UNBLOCK
+@K@INSCRIPT
+START_
+TNS_UNBLOCK_
+TIMER
+@K@CODE
+/* GET TIMER-EVENT DESCRIPTOR */
+G9PB513_GET_TIMER_EV_DESCR_P
+(
+SID_GBNSVC,
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+/* INITIALIZATION OF THE TIMER-EVENT-DESCRIPTOR */
+NSVCI_CON_PTR->.TIM_EVD_PTR->.EVENT_CMD:= G9IBSE4_TO_TNS_C;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.EVENT_DESTINATION:= GBNSVC_HANDLE;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+NSVCI_CON_PTR->.TIM_EVD_PTR->.TIMER:= TNS_UNBLOCK_MAP;
+
+/* START TIMER */
+G9PX508_START_TIMER_P
+(
+NSVCI_CON_PTR->.TIM_EVD_PTR
+);
+
+@K@FREEZE
+924686210
+@K@NAME
+M_BLK_ACKM
+@K@INSCRIPT
+NS_
+BLOCK_ACK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D3);
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR2_NS_BLOCK_ACK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D3.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+926348442
+@K@NAME
+TA_NXTALIV
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+ALIVE'
+@K@CODE
+IF
+/* ALIVE NSVC TO THE NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+
+THEN
+/* TAKE NEXT ELEMENT IN THE LINKED LIST AS THE NEXT ALIVE NSVC */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR:=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.NEXT_ALV_NSVCI_CON_PTR;
+
+FI;
+
+@K@FREEZE
+938801086
+@K@NAME
+M_DE_CBVCN
+@K@INSCRIPT
+G9IBME2_
+DEACT_
+CELL_BVC_C
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME2_DEACT_CELL_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+TX_EVD_PTR->.KEYS.INT_ARR(1):= EVD_PTR->.ADD_DATA(3);
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+933318270
+@K@NAME
+TA_NXTRESP
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+RESPONSIBLE'
+@K@CODE
+NSEI_CON_PTR->.NEXT_RESP_NSVCI_CON_PTR:=
+ NSEI_CON_PTR->.NEXT_RESP_NSVCI_CON_PTR->.NEXT_LSP_NSVCI_CON_PTR;
+
+
+@K@FREEZE
+938005006
+@K@NAME
+TA_NXTSUBS
+@K@INSCRIPT
+DEFINE
+NEW 'NEXT_
+SUBSTITUTE'
+@K@CODE
+NSEI_CON_PTR->.NEXT_SUBS_NSVCI_CON_PTR:=
+ NSEI_CON_PTR->.NEXT_SUBS_NSVCI_CON_PTR->.NEXT_UBL_NSVCI_CON_PTR;
+
+@K@NAME
+M_BLK_O__M
+@K@INSCRIPT
+NS_
+BLOCK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+
+IF
+/* 'OTHER' ALIVE NSVC TO THIS NSEI EXISTING? */
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR /= NULL
+THEN
+/* USE THIS 'OTHER' FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI;
+/* NSEI TO BE USED FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+
+NSVCI_CON_PTR->.OWN_NSEI_CON_PTR->.NEXT_ALIV_NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+/* NSVCI TO BE USED FOR TRANSPORT */
+ELSE
+/* USE AFFECTED NSVC AGAIN FOR TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+FI;
+
+
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D2);
+
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR1_NS_BLOCK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D2.CAUSE_TLV.CAUSE_VAL:=
+ G9IBBA2_NS_TRANSIT_NETWORK_FAILURE; /* CAUSE FOR BLOCK */
+NS_PDU_PTR->.D2.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+GSM 8.16 CHAP. 7.2:
+THE NS-BLOCK-PDU MAY BE SENT IN ANY ALIVE
+(BLOCKED OR UNBLOCKED) NS-VC...
+@K@FREEZE
+938803215
+@K@NAME
+M_DE_SBVCN
+@K@INSCRIPT
+G9IBME1_
+DEACT_
+SIGN_BVC_C
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB512_GET_MSG_LESS_EV_DESCR_P
+(
+SID_GBNSVC,
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+TX_EVD_PTR->.EVENT_CMD:= G9IBME1_DEACT_SIGN_BVC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBBVC_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):= EVD_PTR->.KEYS.INT_ARR(0);
+TX_EVD_PTR->.KEYS.INT_ARR(1):= SIGN_BVCI;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+938788201
+@K@NAME
+M_OAME401M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSE */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSE;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSE_ID:= EVD_PTR->.KEYS.INT_ARR(0); /*
+USED NSEI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935766108
+@K@NAME
+M_OAME402M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.KEYS.INT_ARR(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935766407
+@K@NAME
+M_OAME411M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_ACK_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSE */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSE;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSE_ID:= EVD_PTR->.KEYS.INT_ARR(0); /*
+USED NSEI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935767332
+@K@NAME
+M_OAME412M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+RESET_ACK_PDU
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.KEYS.INT_ARR(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_RESET_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.ADD_DATA(0); /* NSEI FROM PDU */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.ADD_DATA(1); /* NSVCI FROM PDU */
+
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+935767189
+@K@NAME
+C_CON
+@K@INSCRIPT
+RC_DB
+@K@CODE
+RC_DB
+
+@K@FREEZE
+922176673
+@K@NAME
+M_BLK____M
+@K@INSCRIPT
+NS_
+BLOCK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9IBDF4_NS_LM_M) + G9IBD44_NS_PDU_DATA_OFFSET_C),
+TX_EVD_PTR
+);
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9IBD40_NS_LM_PDU_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= GBDL_HANDLE;
+TX_EVD_PTR->.KEYS.INT_ARR(0):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSEI; /* NSEI TO BE USED FOR
+TRANSPORT */
+TX_EVD_PTR->.KEYS.INT_ARR(1):=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVCI TO BE USED FOR
+TRANSPORT */
+/* POINTER TO PDU IN POOL-ELEMENT */
+NS_PDU_PTR:= NS_PDU_REF_M (INT(TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT)
+ + G9IBD44_NS_PDU_DATA_OFFSET_C);
+/* OFFSET OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= G9IBD44_NS_PDU_DATA_OFFSET_C;
+/* LENGTH OF THE PDU IN POOL-ELEMENT */
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(NS_PDU_PTR->.G9IBDF4_PDU_TYPE) +
+SIZE(NS_PDU_PTR->.D2);
+
+
+/* NOW THE POOL-ELEMENT */
+NS_PDU_PTR->.G9IBDF4_PDU_TYPE:= G9IBDR1_NS_BLOCK_C; /* PDU-TYPE */
+
+NS_PDU_PTR->.D2.CAUSE_TLV.CAUSE_VAL:=
+ G9IBBA2_NS_OAM_INTERVENTION; /* CAUSE FOR BLOCK */
+NS_PDU_PTR->.D2.NSVCI_TLV.NSVCI_VAL :=
+ NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI; /* NSVC TO BE BLOCKED */
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+GSM 8.16 CHAP. 7.2:
+THE NS-BLOCK-PDU MAY BE SENT IN ANY ALIVE
+(BLOCKED OR UNBLOCKED) NS-VC...
+@K@FREEZE
+926348613
+@K@NAME
+S_BLOCKED
+@K@INSCRIPT
+G9IBSM0_
+BLOCKED
+@K@CODE
+
+
+@K@FREEZE
+922176496
+@K@NAME
+D_CON
+@K@INSCRIPT
+CONTEXT
+GOT
+@K@CODE
+RC_DB = G9IBSR0_RC_OK
+
+@K@FREEZE
+921772339
+@K@NAME
+M_OAME901M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+UBL->BLK
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_ENABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970975
+@K@NAME
+M_OAME902M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+UBL->BLK
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_DISABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970987
+@K@NAME
+M_OAME10SM
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@NAME
+M_OAME911M
+@K@INSCRIPT
+ERROR_MESSAGE:
+OPERATIONAL_STATE_CHANGE
+BLK->UBL
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = OPERATIONAL_STATE_CHANGE */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_OPERATIONAL_STATE_CHANGE;
+/* ADDITIONAL_OPERATIONAL_STATE_INFO */
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.OPER_STATE_NEW:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_OLD:=
+ G9OC102_ENABLED;
+OAM_MSG_PTR->.ADDITIONAL_OPERATIONAL_STATE_INFO.ADMIN_STATE_NEW:=
+ G9OC102_ENABLED;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+925970996
+@K@NAME
+M_OAME20SM
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@NAME
+M_OAME10_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443813
+@K@NAME
+D_SEM
+@K@INSCRIPT
+CALL_SEM
+=
+TRUE
+@K@CODE
+CALL_SEM = TRUE
+
+@K@FREEZE
+922176624
+@K@NAME
+D_N_0
+@K@INSCRIPT
+N = 0
+
+@K@CODE
+NSVCI_CON_PTR->.N = 0
+
+@K@FREEZE
+921511000
+@K@NAME
+M_OAME12_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443829
+@K@NAME
+M_OAME21_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ TRUE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ FALSE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443856
+@K@NAME
+M_OAME13_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_BEGIN_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_BEGIN_NS_ALIVE_TEST*/
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_BEGIN_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_UNBLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443838
+@K@NAME
+M_OAME22_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ALARM_END_NS_ALIVE_TEST
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = ALARM_END_NS_ALIVE_TEST */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ALARM_END_NS_ALIVE_TEST;
+/* ADDITIONAL_ALARM_INFO */
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.ADMINISTRATIVE_STATE_CHANGED:=
+ FALSE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_OLD:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.OPER_STATE_NEW:=
+ G9OC101_BLOCKED;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_OLD:=
+ G9OC103_DEAD;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.AVAIL_STATE_NEW:=
+ G9OC103_ALIVE;
+OAM_MSG_PTR->.ADDITIONAL_ALARM_INFO.CONFIGURATION_OF_NSVC:=
+ TRUE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922443864
+@K@NAME
+M_OAME30_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FORM_BSS
+RESET_PROCEDURE
+
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_RESET_PROCEDURE;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175973
+@K@NAME
+M_OAME31_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FROM_BSS
+BLOCK_PROCEDURE
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_BLOCK_PROCEDURE;
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175976
+@K@NAME
+M_OAME32_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+NO_ANSWER_FROM_BSS
+UNBLOCK_PROCEDURE
+
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR_CAUSE = NO_ANSWER_FROM_BSS */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_NO_ANSWER_FROM_BSS;
+/* INITIATED_PROCEDURE */
+OAM_MSG_PTR->.INITIATED_PROCEDURE:=
+ G9OC123_UNBLOCK_PROCEDURE;
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+922175980
+@K@NAME
+M_OAME42_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+BLOCK_PDU
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.ADD_DATA(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_BLOCK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.KEYS.INT_ARR(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.KEYS.INT_ARR(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+934296141
+@K@NAME
+M_OAME50_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+STATUS_PDU_CONTAINS_ERROR_INFO
+RECEIVED
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:=
+NSVCI_CON_PTR->.DBMS.NSVC_INSTANCE.NSVCI;
+
+/* ERROR-CAUSE = STATUS_PDU_CONTAINS_ERROR_INFO */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_STATUS_PDU_CONTAINS_ERROR_INFO;
+/* ADDITIONAL_STATUS_PDU_INFO */
+INT_CAUSE_PTR.INT_PTR:= ADDR(EVD_PTR->.ADD_DATA(2));
+OAM_MSG_PTR->.ADDITIONAL_STATUS_PDU_INFO:=
+ INT_CAUSE_PTR.CAUSE_PTR->; /* CAUSE */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@TEXT
+NICHT OK
+
+@K@FREEZE
+934298924
+@K@NAME
+M_OAME43_M
+@K@INSCRIPT
+ERROR_MESSAGE:
+ERRONOUS_PDU
+BLOCK_ACK_PDU
+@K@CODE
+/* GETTING THE EVENT DESCRIPTOR */
+G9PB511_GET_MSG_BOUND_EV_DESCR_P
+(
+SID_GBNSVC,
+(SIZE(G9OC109_REPORTED_EVENT_STR_M)),
+TX_EVD_PTR
+);
+
+
+/* COMPOSING THE EVENT */
+/* FIRST THE DESCRIPTOR */
+TX_EVD_PTR->.EVENT_CMD:= G9PX040_SEND_MBC_C;
+TX_EVD_PTR->.EVENT_DESTINATION:= RXTX_HANDLE;
+TX_EVD_PTR->.KEYS.UBI_INDEX:= OAM_UBI_INDEX;
+TX_EVD_PTR->.BOUND.DATA_OFFSET:= 0;
+TX_EVD_PTR->.BOUND.DATA_LENGTH:= SIZE(G9OC109_REPORTED_EVENT_STR_M);
+
+/* NOW THE POOL-ELEMENT */
+/* INITIALIZATION OF THE POINTER WITH THE POOL-ELEMENT-START */
+OAM_MSG_PTR:= OAM_MSG_PTR_M (TX_EVD_PTR->.BOUND.PTR_TO_POOL_ELEMENT);
+
+/* COMPOSING THE MESSAGE */
+/* HANDLED OBJECT = AFFECTED INSTANCE, TYPE NSVC */
+OAM_MSG_PTR->.HANDLED_OBJECT.OBJECT_TYPE:= G9OC104_NSVC;
+OAM_MSG_PTR->.HANDLED_OBJECT.NSVC_ID:= EVD_PTR->.ADD_DATA(1); /*
+USED NSVCI (FROM ECI) */
+
+/* ERROR-CAUSE = ERRONEOUS_PDU */
+OAM_MSG_PTR->.ERROR_CAUSE:= G9OC108_ERRONEOUS_PDU;
+/* ADDITIONAL_PDU_INFO */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_PDU_TYPE:=
+ G9OC124_BLOCK_ACK_PDU;
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSEI:=
+ EVD_PTR->.KEYS.INT_ARR(0); /* AFFECTED NSEI (FROM PDU) */
+OAM_MSG_PTR->.ADDITIONAL_PDU_INFO.G9OC120_REPORTED_NSVC:=
+ EVD_PTR->.KEYS.INT_ARR(1); /* AFFECTED NSVCI (FROM PDU) */
+
+
+
+/* SENDING */
+G9PX503_POST_EVENT_P(TX_EVD_PTR);
+
+@K@FREEZE
+934297710
--- /dev/null
+BEGIN { pipe = "cat <<EOF\n"
+ pipe = pipe "select * from user\n"
+ pipe = pipe " where Name = 'O\\'Donell'\n"
+ pipe = pipe "EOF\n"
+
+ while ((pipe | getline) > 0)
+ print
+
+ exit 0
+}
--- /dev/null
+select * from user
+ where Name = 'O\'Donell'
--- /dev/null
+#From vp@dmat.uevora.pt Thu Jun 18 09:10 EDT 1998
+#Received: from mescaline.gnu.org (we-refuse-to-spy-on-our-users@mescaline.gnu.org [158.121.106.21]) by cssun.mathcs.emory.edu (8.7.5/8.6.9-940818.01cssun) with ESMTP id JAA23649 for <arnold@mathcs.emory.edu>; Thu, 18 Jun 1998 09:10:54 -0400 (EDT)
+#Received: from khromeleque.dmat.uevora.pt by mescaline.gnu.org (8.8.5/8.6.12GNU) with ESMTP id JAA21732 for <arnold@gnu.ai.mit.edu>; Thu, 18 Jun 1998 09:11:19 -0400
+#Received: from khromeleque.dmat.uevora.pt (vp@localhost [127.0.0.1])
+# by khromeleque.dmat.uevora.pt (8.8.8/8.8.8/Debian/GNU) with ESMTP id OAA11817
+# for <arnold@gnu.ai.mit.edu>; Thu, 18 Jun 1998 14:13:57 +0100
+#Message-Id: <199806181313.OAA11817@khromeleque.dmat.uevora.pt>
+#To: arnold@gnu.org
+#Subject: concatenation bug in gawk 3.0.3
+#Date: Thu, 18 Jun 1998 14:13:57 +0200
+#From: Vasco Pedro <vp@dmat.uevora.pt>
+#Content-Type: text
+#Content-Length: 2285
+#Status: RO
+#
+#Hi,
+#
+#The gawk program '{print NR " " 10/NR}' will print:
+#
+#1 10
+#5 5
+#3 3.33333
+#2 2.5
+#2 2
+#1 1.66667
+#
+#instead of the correct:
+#
+#1 10
+#2 5
+#3 3.33333
+#4 2.5
+#5 2
+#6 1.66667
+#
+#You'll notice, on the incorrect output, that the first column is
+#the first digit of the second.
+#
+#I think the problem comes from the way builtin variables are handled.
+#Since the items to be concatenated are processed in reverse order and
+#the return value of tree_eval(``NR'') is a pointer to the value part
+#of `NR_node', the `unref()' of `NR_node' due to its second occurrence
+#will leave a dangling pointer in `strlist'. The reason that it doesn't
+#reuse the freed space with objects of the same type. (Using Electric
+#Fence with EF_PROTECT_FREE set confirms that freed space is being
+#accessed.)
+#
+#The enclosed patch (hack would be a better word to describe it) is
+#all I could come up with. With it installed, things seem to work ok,
+#but I doubt this is the correct way to do it. (If I treated the
+#case for `Node_field_spec' as the I did others, `make check' would
+#fail in several places.)
+#
+#Regards,
+#vasco
+#
+#*** eval.c~ Tue May 6 21:39:55 1997
+#--- eval.c Thu Jun 18 13:39:25 1998
+#***************
+#*** 685,697 ****
+# return func_call(tree->rnode, tree->lnode);
+#
+# /* unary operations */
+# case Node_NR:
+# case Node_FNR:
+# case Node_NF:
+# case Node_FIELDWIDTHS:
+# case Node_FS:
+# case Node_RS:
+#- case Node_field_spec:
+# case Node_subscript:
+# case Node_IGNORECASE:
+# case Node_OFS:
+#--- 685,700 ----
+# return func_call(tree->rnode, tree->lnode);
+#
+# /* unary operations */
+#+ case Node_field_spec:
+#+ lhs = get_lhs(tree, (Func_ptr *) NULL);
+#+ return *lhs;
+#+
+# case Node_NR:
+# case Node_FNR:
+# case Node_NF:
+# case Node_FIELDWIDTHS:
+# case Node_FS:
+# case Node_RS:
+# case Node_subscript:
+# case Node_IGNORECASE:
+# case Node_OFS:
+#***************
+#*** 699,705 ****
+# case Node_OFMT:
+# case Node_CONVFMT:
+# lhs = get_lhs(tree, (Func_ptr *) NULL);
+#! return *lhs;
+#
+# case Node_var_array:
+# fatal("attempt to use array `%s' in a scalar context",
+#--- 702,710 ----
+# case Node_OFMT:
+# case Node_CONVFMT:
+# lhs = get_lhs(tree, (Func_ptr *) NULL);
+#! r = dupnode(*lhs);
+#! r->flags |= TEMP;
+#! return r;
+#
+# case Node_var_array:
+# fatal("attempt to use array `%s' in a scalar context",
+#
+{ print NR " " 10/NR }
--- /dev/null
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
--- /dev/null
+1 10
+2 5
+3 3.33333
+4 2.5
+5 2
+6 1.66667
--- /dev/null
+#From dhw@gamgee.acad.emich.edu Sat Oct 31 22:54:07 1998
+#Return-Path: <dhw@gamgee.acad.emich.edu>
+#Received: from cssun.mathcs.emory.edu (cssun.mathcs.emory.edu [170.140.150.1])
+# by amx.netvision.net.il (8.9.0.Beta5/8.8.6) with ESMTP id HAA08891
+# for <arobbins@netvision.net.il>; Sat, 31 Oct 1998 07:14:07 +0200 (IST)
+#Received: from mescaline.gnu.org (we-refuse-to-spy-on-our-users@mescaline.gnu.org [158.121.106.21]) by cssun.mathcs.emory.edu (8.7.5/8.6.9-940818.01cssun) with ESMTP id AAA14947 for <arnold@mathcs.emory.edu>; Sat, 31 Oct 1998 00:14:32 -0500 (EST)
+#Received: from gamgee.acad.emich.edu (gamgee.acad.emich.edu [164.76.102.76])
+# by mescaline.gnu.org (8.9.1a/8.9.1) with SMTP id AAA20645
+# for <arnold@gnu.ai.mit.edu>; Sat, 31 Oct 1998 00:17:54 -0500
+#Received: by gamgee.acad.emich.edu (Smail3.1.29.1 #57)
+# id m0zZUKY-000IDSC; Sat, 31 Oct 98 00:16 CST
+#Message-Id: <m0zZUKY-000IDSC@gamgee.acad.emich.edu>
+#Date: Sat, 31 Oct 98 00:16 CST
+#From: dhw@gamgee.acad.emich.edu (David H. West)
+#To: bug-gnu-utils@gnu.org
+#Subject: gawk 3.0.3 bug report
+#Cc: arnold@gnu.org
+#X-UIDL: 7474b825cff989adf38f13883d84fdd7
+#Status: RO
+#
+#gawk version: 3.03
+#System used: Linux, kernel 2.0.28, libc 5.4.33, AMD K5PR133 (i586 clone)
+#Remark: There seems to be at least one bug shown by the demo below.
+# There may also be a Dark Corner involving the value of NR in an
+# END block, a topic on which the info file is silent. In gawk
+# 3.0.3, NR often seems to have the least-surprise value in an
+# END block, but sometimes it doesn't - see example below.
+#Problem descr: the log below shows a case where:
+# a) (this may be a red herring) the output of the gawk script
+# is different depending on whether its input file is named on
+# the command line or catted to stdin, without any use of the
+# legitimate means which could produce this effect.
+# b) NR is clearly getting clobbered; I have tried to simplify
+# the 19-line script "awkerr1" below, but seemingly unrelated
+# changes, like shortening constant strings which appear only in
+# print statements, or removing unexecuted or irrelevant code,
+# cause the clobbering to go away. Some previous (larger)
+# versions of this code would clobber NR also when reading from
+# stdin, but I thought you'd prefer a shorter example :-).
+#Reproduce-By: using the gawk script "awkerr1", the contents of
+# which appear in the transcript below as the output of the
+# command "cat awkerr1". Comments following # were added
+# to the transcript later as explanation.
+#---------------------------------------------- Script started on Fri
+#Oct 30 20:04:16 1998 chipmunk:/ram0# ls -l a1 awkerr1 -rw-r--r-- 1
+#root root 2 Oct 30 18:42 a1 -rwxr-xr-x 1 root root
+#389 Oct 30 19:54 awkerr1 chipmunk:/ram0# cat a1 #a1 contains
+#one printable char and a newline a chipmunk:/ram0# od -c\b \bxc a1
+#0000000 0a61
+# a \n
+#0000002 chipmunk:/ram0# cat a1 | awkerr1 #no surprises here
+#1 lines in 1 sec: 1 lines/sec; nlines=1 chipmunk:/ram0# awkerr1 a1 È
+#lines in 1 sec: 1 lines/sec; nlines=1 #?! first char is an uppercase
+#E-grave chipmunk:/ram0# awkerr1 a1 | od -N1 -xc 0000000 00c8
+# 310 \0
+#0000001 chipmunk:/ram0# cat awkerr1 #the apparent ^M's are not
+#actually in the file
+#!/usr/bin/awk -f
+function process(w) {
+ if(w in ws) {
+ printf " : found\n"; lc[p " " w]++; rc[w " " n]++; }
+ }
+BEGIN {IGNORECASE=1;
+ }
+/^/ {if(NR % 10 ==0)print "processing line " NR;
+ process($1); nlines++;
+ }
+END {p=w; w=n; n="";
+ if(w)process(w); t=1; print NR " lines in " t " sec: " NR+0 " lines/sec; nlines=" nlines;
+ }
+#chipmunk:/ram0# exit Script done on Fri Oct 30 20:07:31 1998
+#---------------------------------------------
+#
+#-David West dhw@gamgee.acad.emich.edu
+#
--- /dev/null
+1 lines in 1 sec: 1 lines/sec; nlines=1
--- /dev/null
+# From Servatius.Brandt@fujitsu-siemens.com Fri Dec 1 13:44:48 2000
+# Received: from mail.actcom.co.il
+# by localhost with POP3 (fetchmail-5.1.0)
+# for arnold@localhost (single-drop); Fri, 01 Dec 2000 13:44:48 +0200 (IST)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Fri Dec 1 13:44:10 2000)
+# X-From_: Servatius.Brandt@fujitsu-siemens.com Fri Dec 1 13:11:23 2000
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id NAA11033 for <arobbins@actcom.co.il>;
+# Fri, 1 Dec 2000 13:11:21 +0200 (EET)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from billohost.com (10-209.196.35.dellhost.com [209.196.35.10] (may be forged))
+# by lmail.actcom.co.il (8.9.3/8.9.1) with ESMTP id NAA30286
+# for <arobbins@actcom.co.il>; Fri, 1 Dec 2000 13:12:25 +0200
+# Received: from fencepost.gnu.org (we-refuse-to-spy-on-our-users@fencepost.gnu.org [199.232.76.164])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id GAA26074
+# for <arnold@skeeve.com>; Fri, 1 Dec 2000 06:09:08 -0500
+# Received: from energy.pdb.sbs.de ([192.109.2.19])
+# by fencepost.gnu.org with esmtp (Exim 3.16 #1 (Debian))
+# id 141o5z-0000RJ-00; Fri, 01 Dec 2000 06:11:16 -0500
+# Received: from trulli.pdb.fsc.net ([172.25.96.20])
+# by energy.pdb.sbs.de (8.9.3/8.9.3) with ESMTP id MAA32687;
+# Fri, 1 Dec 2000 12:11:13 +0100
+# Received: from pdbrd02e.pdb.fsc.net (pdbrd02e.pdb.fsc.net [172.25.96.15])
+# by trulli.pdb.fsc.net (8.9.3/8.9.3) with ESMTP id MAA27384;
+# Fri, 1 Dec 2000 12:11:13 +0100
+# Received: from Fujitsu-Siemens.com (pgtd1181.mch.fsc.net [172.25.126.152]) by pdbrd02e.pdb.fsc.net with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21)
+# id XC2QLXS2; Fri, 1 Dec 2000 12:11:13 +0100
+# Message-ID: <3A2786CF.1000903@Fujitsu-Siemens.com>
+# Date: Fri, 01 Dec 2000 12:09:03 +0100
+# From: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
+# Organization: Fujitsu Siemens Computers
+# User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; m18) Gecko/20001108 Netscape6/6.0
+# X-Accept-Language: de, en
+# MIME-Version: 1.0
+# To: bug-gnu-utils@gnu.org
+# CC: arnold@gnu.org
+# Subject: Bug Report: \y, \B, \<, \> do not work with _
+# Content-Type: text/plain; charset=us-ascii; format=flowed
+# Content-Transfer-Encoding: 7bit
+# Status: R
+#
+# Hello,
+#
+# The \y, \B, \<, \> patterns do not regard _ as
+# word-constituent (unlike \w and \W, which do).
+#
+# Operating system: ReliantUNIX-Y 5.44 C2001 RM600 R10000
+# Version of gawk: 3.0.6
+# C-Compiler: Fujitsu Siemens Computers CDS++ V2.0C0004
+#
+# Test program:
+#
+#!/usr/local/bin/gawk -f
+
+BEGIN {
+ print match("X _abc Y", /\<_abc/) # bug
+ print match("X _abc Y", /\y_abc/) # bug
+ print match("X abc_ Y", /abc_\>/) # bug
+ print match("X abc_ Y", /abc_\y/) # bug
+ print match("X abc_def Y", /abc_\Bdef/) # bug
+
+ print match("X a_c Y", /a\wc/) # ok!
+ print match("X a.c Y", /a\Wc/) # ok!
+ exit
+}
+#
+#
+# Regards,
+# Servatius Brandt
+#
+#
--- /dev/null
+3
+3
+3
+3
+3
+3
+3
--- /dev/null
+# Mon Jan 31 09:57:30 IST 2005
+# test both dfa and regex matchers on \B
+# tests from Stepan Kasal, kasal@ucw.cz
+BEGIN {
+
+ print (" " ~ / \B /) # test dfa matcher
+ print ("a b" ~ /\B/)
+ print (" b" ~ /\B/)
+ print ("a " ~ /\B/)
+
+ a = " "
+ gsub(/\B/, "x", a) # test regex matcher
+ print a
+}
--- /dev/null
+1
+0
+1
+1
+x x x
--- /dev/null
+# test the gnu regexp ops
+
+BEGIN {
+ if ("a rat is here" ~ /\yrat/) print "test 1 ok (\\y)"
+ else print "test 1 failed (\\y)"
+ if ("a rat is here" ~ /rat\y/) print "test 2 ok (\\y)"
+ else print "test 2 failed (\\y)"
+ if ("what a brat" !~ /\yrat/) print "test 3 ok (\\y)"
+ else print "test 3 failed (\\y)"
+
+ if ("in the crate" ~ /\Brat/) print "test 4 ok (\\B)"
+ else print "test 4 failed (\\B)"
+ if ("a rat" !~ /\Brat/) print "test 5 ok (\\B)"
+ else print "test 5 failed (\\B)"
+
+ if ("a word" ~ /\<word/) print "test 6 ok (\\<)"
+ else print "test 6 failed (\\<)"
+ if ("foreword" !~ /\<word/) print "test 7 ok (\\<)"
+ else print "test 7 failed (\\<)"
+
+ if ("a word" ~ /word\>/) print "test 8 ok (\\>)"
+ else print "test 8 failed (\\\\>)"
+ if ("wordy" !~ /word\>/) print "test 9 ok (\\>)"
+ else print "test 9 failed (\\>)"
+
+ if ("a" ~ /\w/) print "test 10 ok (\\w)"
+ else print "test 10 failed (\\\\w)"
+ if ("+" !~ /\w/) print "test 11 ok (\\w)"
+ else print "test 11 failed (\\w)"
+
+ if ("a" !~ /\W/) print "test 12 ok (\\W)"
+ else print "test 12 failed (\\W)"
+ if ("+" ~ /\W/) print "test 13 ok (\\W)"
+ else print "test 13 failed (\\W)"
+
+ if ("a" ~ /\`a/) print "test 14 ok (\\`)"
+ else print "test 14 failed (\\`)"
+ if ("b" !~ /\`a/) print "test 15 ok (\\`)"
+ else print "test 15 failed (\\`)"
+
+ if ("a" ~ /a\'/) print "test 16 ok (\\')"
+ else print "test 16 failed (\\')"
+ if ("b" !~ /a\'/) print "test 17 ok (\\')"
+ else print "test 17 failed (\\')"
+}
--- /dev/null
+test 1 ok (\y)
+test 2 ok (\y)
+test 3 ok (\y)
+test 4 ok (\B)
+test 5 ok (\B)
+test 6 ok (\<)
+test 7 ok (\<)
+test 8 ok (\>)
+test 9 ok (\>)
+test 10 ok (\w)
+test 11 ok (\w)
+test 12 ok (\W)
+test 13 ok (\W)
+test 14 ok (\`)
+test 15 ok (\`)
+test 16 ok (\')
+test 17 ok (\')
--- /dev/null
+# tests for assigning to a function within that function
+
+#1 - should be bad
+function test1 (r) { gsub(r, "x", test1) }
+BEGIN { test1("") }
+
+#2 - should be bad
+function test2 () { gsub(/a/, "x", test2) }
+BEGIN { test2() }
+
+#3 - should be ok
+function test3 (r) { gsub(/a/, "x", r) }
+BEGIN { test3("") }
--- /dev/null
+gawk: gsubasgn.awk:4: function test1 (r) { gsub(r, "x", test1) }
+gawk: gsubasgn.awk:4: ^ gsub third parameter is not a changeable object
+gawk: gsubasgn.awk:8: function test2 () { gsub(/a/, "x", test2) }
+gawk: gsubasgn.awk:8: ^ gsub third parameter is not a changeable object
+EXIT CODE: 1
--- /dev/null
+BEGIN {
+ str = "abc"; print gsub("b+", "FOO", str), str
+ str = "abc"; print gsub("x*", "X", str), str
+ str = "abc"; print gsub("b*", "X", str), str
+ str = "abc"; print gsub("c", "X", str), str
+ str = "abc"; print gsub("c+", "X", str), str
+ str = "abc"; print gsub("x*$", "X", str), str
+ str = "abc"; print gsub("b|$", "X", str), str
+}
--- /dev/null
+1 aFOOc
+4 XaXbXcX
+3 XaXcX
+1 abX
+1 abX
+1 abcX
+2 aXcX
--- /dev/null
+#From arnold Thu May 9 17:27:03 2002
+#Return-Path: <arnold@skeeve.com>
+#Received: (from arnold@localhost)
+# by skeeve.com (8.11.6/8.11.6) id g49ER3K27925
+# for arnold; Thu, 9 May 2002 17:27:03 +0300
+#Date: Thu, 9 May 2002 17:27:03 +0300
+#From: Aharon Robbins <arnold@skeeve.com>
+#Message-Id: <200205091427.g49ER3K27925@skeeve.com>
+#To: arnold@skeeve.com
+#Subject: fixme
+#X-SpamBouncer: 1.4 (10/07/01)
+#X-SBRule: Pattern Match (Other Patterns) (Score: 4850)
+#X-SBRule: Pattern Match (Spam Phone #) (Score: 0)
+#X-SBClass: Blocked
+#Status: O
+#
+#Path: ord-read.news.verio.net!dfw-artgen!iad-peer.news.verio.net!news.verio.net!fu-berlin.de!uni-berlin.de!host213-120-137-48.in-addr.btopenworld.COM!not-for-mail
+#From: laura@madonnaweb.com (laura fairhead)
+#Newsgroups: comp.lang.awk
+#Subject: bug in gawk3.1.0 regex code
+#Date: Wed, 08 May 2002 23:31:40 GMT
+#Organization: that'll be the daewooo :)
+#Lines: 211
+#Message-ID: <3cd9b0f7.29675926@NEWS.CIS.DFN.DE>
+#Reply-To: laura@madonnaweb.com
+#NNTP-Posting-Host: host213-120-137-48.in-addr.btopenworld.com (213.120.137.48)
+#X-Trace: fu-berlin.de 1020900891 18168286 213.120.137.48 (16 [53286])
+#X-Newsreader: Forte Free Agent 1.21/32.243
+#Xref: dfw-artgen comp.lang.awk:13059
+#
+#
+#I believe I've just found a bug in gawk3.1.0 implementation of
+#extended regular expressions. It seems to be down to the alternation
+#operator; when using an end anchor '$' as a subexpression in an
+#alternation and the entire matched RE is a nul-string it fails
+#to match the end of string, for example;
+#
+#gsub(/$|2/,"x")
+#print
+#
+#input = 12345
+#expected output = 1x345x
+#actual output = 1x345
+#
+#The start anchor '^' always works as expected;
+#
+#gsub(/^|2/,"x")
+#print
+#
+#input = 12345
+#expected output = x1x345
+#actual output = x1x345
+#
+#This was with POSIX compliance enabled althought that doesn't
+#effect the result.
+#
+#I checked on gawk3.0.6 and got exactly the same results however
+#gawk2.15.6 gives the expected results.
+#
+#I'm about to post a bug report about this into gnu.utils.bug
+#but I thought I'd post it here first in case anyone has
+#any input/comments/whatever ....
+#
+#Complete test results were as follows;
+#
+#input 12345
+#output gsub(/regex/,"x",input)
+#
+#regex output
+#(^) x12345
+#($) 12345x
+#(^)|($) x12345x
+#($)|(^) x12345x
+#(2) 1x345
+#(^)|2 x1x345
+#2|(^) x1x345
+#($)|2 1x345
+#2|($) 1x345
+#(2)|(^) x1x345
+#(^)|(2) x1x345
+#(2)|($) 1x345
+#($)|(2) 1x345
+#.((2)|(^)) x345
+#.((^)|(2)) x345
+#.((2)|($)) x34x
+#.(($)|(2)) x34x
+#x{0}((2)|(^)) x1x345
+#x{0}((^)|(2)) x1x345
+#x{0}((2)|($)) 1x345
+#x{0}(($)|(2)) 1x345
+#x*((2)|(^)) x1x345
+#x*((^)|(2)) x1x345
+#x*((2)|($)) 1x345
+#x*(($)|(2)) 1x345
+#
+#Here's the test program I used, a few of the cases use ERE {n[,[m]]}
+#operators so that will have to be commented out or have a check
+#added or something (should have put a conditional in I know... ;-)
+#
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+BEGIN{
+
+TESTSTR="12345"
+
+print "input "TESTSTR
+print "output gsub(/regex/,\"x\",input)"
+print ""
+
+print "regex output"
+$0=TESTSTR
+gsub(/(^)/,"x")
+print "(^) "$0
+
+$0=TESTSTR
+gsub(/($)/,"x")
+print "($) "$0
+
+$0=TESTSTR
+gsub(/(^)|($)/,"x")
+print "(^)|($) "$0
+
+$0=TESTSTR
+gsub(/($)|(^)/,"x")
+print "($)|(^) "$0
+
+$0=TESTSTR
+gsub(/2/,"x")
+print "(2) "$0
+
+$0=TESTSTR
+gsub(/(^)|2/,"x")
+print "(^)|2 "$0
+
+$0=TESTSTR
+gsub(/2|(^)/,"x")
+print "2|(^) "$0
+
+$0=TESTSTR
+gsub(/($)|2/,"x")
+print "($)|2 "$0
+
+$0=TESTSTR
+gsub(/2|($)/,"x")
+print "2|($) "$0
+
+$0=TESTSTR
+gsub(/(2)|(^)/,"x")
+print "(2)|(^) "$0
+
+$0=TESTSTR
+gsub(/(^)|(2)/,"x")
+print "(^)|(2) "$0
+
+$0=TESTSTR
+gsub(/(2)|($)/,"x")
+print "(2)|($) "$0
+
+$0=TESTSTR
+gsub(/($)|(2)/,"x")
+print "($)|(2) "$0
+
+$0=TESTSTR
+gsub(/.((2)|(^))/,"x")
+print ".((2)|(^)) "$0
+
+$0=TESTSTR
+gsub(/.((^)|(2))/,"x")
+print ".((^)|(2)) "$0
+
+$0=TESTSTR
+gsub(/.((2)|($))/,"x")
+print ".((2)|($)) "$0
+
+$0=TESTSTR
+gsub(/.(($)|(2))/,"x")
+print ".(($)|(2)) "$0
+
+# $0=TESTSTR
+# gsub(/x{0}((2)|(^))/,"x")
+# print "x{0}((2)|(^)) "$0
+#
+# $0=TESTSTR
+# gsub(/x{0}((^)|(2))/,"x")
+# print "x{0}((^)|(2)) "$0
+#
+# $0=TESTSTR
+# gsub(/x{0}((2)|($))/,"x")
+# print "x{0}((2)|($)) "$0
+#
+# $0=TESTSTR
+# gsub(/x{0}(($)|(2))/,"x")
+# print "x{0}(($)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x*((2)|(^))/,"x")
+print "x*((2)|(^)) "$0
+
+$0=TESTSTR
+gsub(/x*((^)|(2))/,"x")
+print "x*((^)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x*((2)|($))/,"x")
+print "x*((2)|($)) "$0
+
+$0=TESTSTR
+gsub(/x*(($)|(2))/,"x")
+print "x*(($)|(2)) "$0
+
+# $0=TESTSTR
+# gsub(/x{0}^/,"x")
+# print "x{0}^ "$0
+#
+# $0=TESTSTR
+# gsub(/x{0}$/,"x")
+# print "x{0}$ "$0
+#
+# $0=TESTSTR
+# gsub(/(x{0}^)|2/,"x")
+# print "(x{0}^)|2 "$0
+#
+# $0=TESTSTR
+# gsub(/(x{0}$)|2/,"x")
+# print "(x{0}$)|2 "$0
+
+
+}
+#
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#byefrom
+#
+#--
+#laura fairhead # laura@madonnaweb.com http://lf.8k.com
+# # if you are bored crack my sig.
+#1F8B0808CABB793C0000666667002D8E410E83300C04EF91F2877D00CA138A7A
+#EAA98F30C494480157B623C4EF1B508FDED1CEFA9152A23DE35D661593C5318E
+#630C313CD701BE92E390563326EE17A3CA818F5266E4C2461547F1F5267659CA
+#8EE2092F76C329ED02CA430C5373CC62FF94BAC6210B36D9F9BC4AB53378D978
+#80F2978A1A6E5D6F5133B67B6113178DC1059526698AFE5C17A5187E7D930492
--- /dev/null
+input 12345
+output gsub(/regex/,"x",input)
+
+regex output
+(^) x12345
+($) 12345x
+(^)|($) x12345x
+($)|(^) x12345x
+(2) 1x345
+(^)|2 x1x345
+2|(^) x1x345
+($)|2 1x345x
+2|($) 1x345x
+(2)|(^) x1x345
+(^)|(2) x1x345
+(2)|($) 1x345x
+($)|(2) 1x345x
+.((2)|(^)) x345
+.((^)|(2)) x345
+.((2)|($)) x34x
+.(($)|(2)) x34x
+x*((2)|(^)) x1x345
+x*((^)|(2)) x1x345
+x*((2)|($)) 1x345x
+x*(($)|(2)) 1x345x
--- /dev/null
+# From laura_fairhead@talk21.com Fri May 10 11:24:41 2002
+# Return-Path: <laura_fairhead@talk21.com>
+# Received: from localhost (aahz [127.0.0.1])
+# by skeeve.com (8.11.2/8.11.2) with ESMTP id g4A8OdU01822
+# for <arnold@localhost>; Fri, 10 May 2002 11:24:40 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.7.4)
+# for arnold@localhost (single-drop); Fri, 10 May 2002 11:24:40 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Fri May 10 11:30:42 2002)
+# X-From_: laura_fairhead@talk21.com Fri May 10 05:39:57 2002
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id g4A2dpw26380 for <arobbins@actcom.co.il>;
+# Fri, 10 May 2002 05:39:52 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by lmail.actcom.co.il (8.11.6/8.11.6) with ESMTP id g4A2dxl10851
+# for <arobbins@actcom.co.il>; Fri, 10 May 2002 05:39:59 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.6/8.11.6) with ESMTP id g4A2dwN11097
+# for <arnold@skeeve.com>; Thu, 9 May 2002 22:39:58 -0400
+# Received: from [194.73.242.6] (helo=wmpmta04-app.mail-store.com)
+# by fencepost.gnu.org with smtp (Exim 3.34 #1 (Debian))
+# id 1760K4-0001QX-00
+# for <bug-gawk@gnu.org>; Thu, 09 May 2002 22:39:56 -0400
+# Received: from wmpmtavirtual ([10.216.84.15])
+# by wmpmta04-app.mail-store.com
+# (InterMail vM.5.01.02.00 201-253-122-103-101-20001108) with SMTP
+# id <20020510023921.EEW24107.wmpmta04-app.mail-store.com@wmpmtavirtual>
+# for <bug-gawk@gnu.org>; Fri, 10 May 2002 03:39:21 +0100
+# Received: from 213.1.102.243 by t21web05-lrs ([10.216.84.15]); Fri, 10 May 02 03:38:42 GMT+01:00
+# X-Mailer: talk21 v1.24 - http://talk21.btopenworld.com
+# From: laura_fairhead@talk21.com
+# To: bug-gawk@gnu.org
+# X-Talk21Ref: none
+# Date: Fri, 10 May 2002 03:38:42 GMT+01:00
+# Subject: bug in gawk 3.1.0 regex code
+# Mime-Version: 1.0
+# Content-type: multipart/mixed; boundary="--GgOuLpDpIyE--1020998322088--"
+# Message-Id: <20020510023921.EEW24107.wmpmta04-app.mail-store.com@wmpmtavirtual>
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# Multipart Message Boundary - attachment/bodypart follows:
+#
+#
+# ----GgOuLpDpIyE--1020998322088--
+# Content-Type: text/plain
+# Content-Transfer-Encoding: 7bit
+#
+#
+# I believe I've just found a bug in gawk3.1.0 implementation of
+# extended regular expressions. It seems to be down to the alternation
+# operator; when using an end anchor '$' as a subexpression in an
+# alternation and the entire matched RE is a nul-string it fails
+# to match the end of string, for example;
+#
+# gsub(/$|2/,"x")
+# print
+#
+# input = 12345
+# expected output = 1x345x
+# actual output = 1x345
+#
+# The start anchor '^' always works as expected;
+#
+# gsub(/^|2/,"x")
+# print
+#
+# input = 12345
+# expected output = x1x345
+# actual output = x1x345
+#
+# This was with POSIX compliance enabled althought that doesn't
+# effect the result.
+#
+# I checked on gawk3.0.6 and got exactly the same results however
+# gawk2.15.6 gives the expected results.
+#
+# All the follow platforms produced the same results;
+#
+# gawk3.0.6 / Win98 / i386
+# gawk3.1.0 / Win98 / i386
+# gawk3.0.5 / Linux2.2.16 / i386
+#
+# Complete test results were as follows;
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# regex input expected actual bug?
+# -------------------------------------------------------------
+# (^) 12345 x12345 x12345
+# ($) 12345 12345x 12345x
+# (^)|($) 12345 x12345x x12345x
+# ($)|(^) 12345 x12345x x12345x
+# 2 12345 1x345 1x345
+# (^)|2 12345 x1x345 x1x345
+# 2|(^) 12345 x1x345 x1x345
+# ($)|2 12345 1x345x 1x345 **BUG**
+# 2|($) 12345 1x345x 1x345 **BUG**
+# (2)|(^) 12345 x1x345 x1x345
+# (^)|(2) 12345 x1x345 x1x345
+# (2)|($) 12345 1x345x 1x345 **BUG**
+# ($)|(2) 12345 1x345x 1x345 **BUG**
+# ((2)|(^)). 12345 xx45 xx45
+# ((^)|(2)). 12345 xx45 xx45
+# .((2)|($)) 12345 x34x x34x
+# .(($)|(2)) 12345 x34x x34x
+# (^)|6 12345 x12345 x12345
+# 6|(^) 12345 x12345 x12345
+# ($)|6 12345 12345x 12345x
+# 6|($) 12345 12345x 12345x
+# 2|6|(^) 12345 x1x345 x1x345
+# 2|(^)|6 12345 x1x345 x1x345
+# 6|2|(^) 12345 x1x345 x1x345
+# 6|(^)|2 12345 x1x345 x1x345
+# (^)|6|2 12345 x1x345 x1x345
+# (^)|2|6 12345 x1x345 x1x345
+# 2|6|($) 12345 1x345x 1x345 **BUG**
+# 2|($)|6 12345 1x345x 1x345 **BUG**
+# 6|2|($) 12345 1x345x 1x345 **BUG**
+# 6|($)|2 12345 1x345x 1x345 **BUG**
+# ($)|6|2 12345 1x345x 1x345 **BUG**
+# ($)|2|6 12345 1x345x 1x345 **BUG**
+# 2|4|(^) 12345 x1x3x5 x1x3x5
+# 2|(^)|4 12345 x1x3x5 x1x3x5
+# 4|2|(^) 12345 x1x3x5 x1x3x5
+# 4|(^)|2 12345 x1x3x5 x1x3x5
+# (^)|4|2 12345 x1x3x5 x1x3x5
+# (^)|2|4 12345 x1x3x5 x1x3x5
+# 2|4|($) 12345 1x3x5x 1x3x5 **BUG**
+# 2|($)|4 12345 1x3x5x 1x3x5 **BUG**
+# 4|2|($) 12345 1x3x5x 1x3x5 **BUG**
+# 4|($)|2 12345 1x3x5x 1x3x5 **BUG**
+# ($)|4|2 12345 1x3x5x 1x3x5 **BUG**
+# ($)|2|4 12345 1x3x5x 1x3x5 **BUG**
+# x{0}((2)|(^)) 12345 x1x345 x1x345
+# x{0}((^)|(2)) 12345 x1x345 x1x345
+# x{0}((2)|($)) 12345 1x345x 1x345 **BUG**
+# x{0}(($)|(2)) 12345 1x345x 1x345 **BUG**
+# x*((2)|(^)) 12345 x1x345 x1x345
+# x*((^)|(2)) 12345 x1x345 x1x345
+# x*((2)|($)) 12345 1x345x 1x345 **BUG**
+# x*(($)|(2)) 12345 1x345x 1x345 **BUG**
+# x{0}^ 12345 x12345 x12345
+# x{0}$ 12345 12345x 12345x
+# (x{0}^)|2 12345 x1x345 x1x345
+# (x{0}$)|2 12345 1x345x 1x345 **BUG**
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#
+# Here's the test program I used, a few of the cases use ERE {n[,[m]]}
+# operators so need '-W posix', (although the same results minus
+# those tests came out without POSIX compliance enabled)
+#
+# [ Invocation was 'gawk -W posix -f tregex.awk' ]
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# tregex.awk
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+BEGIN{
+print _=sprintf("%-20s%-10s%-10s%-10s%-10s\n","regex","input","expected","actual","bug?")
+OFS="-"
+$(length(_)+1)=""
+print $0
+
+while(getline <ARGV[1]) # ADR: was testre.dat
+{
+RE=$1;IN=$2;OUT=$3
+$0=IN
+gsub(RE,"x")
+printf "%-20s%-10s%-10s%-10s%-10s\n",RE,IN,OUT,$0,$0==OUT?"":"**BUG**"
+}
+}
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# This is the test data file used;
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# testre.dat
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# (^) 12345 x12345
+# ($) 12345 12345x
+# (^)|($) 12345 x12345x
+# ($)|(^) 12345 x12345x
+# 2 12345 1x345
+# (^)|2 12345 x1x345
+# 2|(^) 12345 x1x345
+# ($)|2 12345 1x345x
+# 2|($) 12345 1x345x
+# (2)|(^) 12345 x1x345
+# (^)|(2) 12345 x1x345
+# (2)|($) 12345 1x345x
+# ($)|(2) 12345 1x345x
+# ((2)|(^)). 12345 xx45
+# ((^)|(2)). 12345 xx45
+# .((2)|($)) 12345 x34x
+# .(($)|(2)) 12345 x34x
+# (^)|6 12345 x12345
+# 6|(^) 12345 x12345
+# ($)|6 12345 12345x
+# 6|($) 12345 12345x
+# 2|6|(^) 12345 x1x345
+# 2|(^)|6 12345 x1x345
+# 6|2|(^) 12345 x1x345
+# 6|(^)|2 12345 x1x345
+# (^)|6|2 12345 x1x345
+# (^)|2|6 12345 x1x345
+# 2|6|($) 12345 1x345x
+# 2|($)|6 12345 1x345x
+# 6|2|($) 12345 1x345x
+# 6|($)|2 12345 1x345x
+# ($)|6|2 12345 1x345x
+# ($)|2|6 12345 1x345x
+# 2|4|(^) 12345 x1x3x5
+# 2|(^)|4 12345 x1x3x5
+# 4|2|(^) 12345 x1x3x5
+# 4|(^)|2 12345 x1x3x5
+# (^)|4|2 12345 x1x3x5
+# (^)|2|4 12345 x1x3x5
+# 2|4|($) 12345 1x3x5x
+# 2|($)|4 12345 1x3x5x
+# 4|2|($) 12345 1x3x5x
+# 4|($)|2 12345 1x3x5x
+# ($)|4|2 12345 1x3x5x
+# ($)|2|4 12345 1x3x5x
+# x{0}((2)|(^)) 12345 x1x345
+# x{0}((^)|(2)) 12345 x1x345
+# x{0}((2)|($)) 12345 1x345x
+# x{0}(($)|(2)) 12345 1x345x
+# x*((2)|(^)) 12345 x1x345
+# x*((^)|(2)) 12345 x1x345
+# x*((2)|($)) 12345 1x345x
+# x*(($)|(2)) 12345 1x345x
+# x{0}^ 12345 x12345
+# x{0}$ 12345 12345x
+# (x{0}^)|2 12345 x1x345
+# (x{0}$)|2 12345 1x345x
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# I've attached a full copy of this e-mail in ZIP format
+# in case of e-mail transport errors corrupting the data.
+#
+# I've posted the same bug report to gnu.utils.bug and
+# it's being discussed in this thread on comp.lang.awk;
+#
+# From: laura@madonnaweb.com (laura fairhead)
+# Newsgroups: comp.lang.awk
+# Subject: bug in gawk3.1.0 regex code
+# Date: Wed, 08 May 2002 23:31:40 GMT
+# Message-ID: <3cd9b0f7.29675926@NEWS.CIS.DFN.DE>
+#
+#
+# byefrom
+#
+# Laura Fairhead
+#
+#
+#
+#
+# --------------------
+# talk21 your FREE portable and private address on the net at http://www.talk21.com
+# ----GgOuLpDpIyE--1020998322088--
+# Content-Type: : application/zip;; Name="COPY.ZIP"
+# Content-Transfer-Encoding: base64
+# Content-Disposition: attachment; filename="COPY.ZIP"
+#
+# UEsDBBQAAAAIALoaqiyj8d/bjwMAAKsaAAADAAAARklMrVjfa+JAEH4P5H8ISwrRU9EYfbheKBR6
+# xRcLvevbYbFtzsqJlBrpQr3722+zMWZ31pk1MaG0Q/m+nR87O9kvruM6/5p4XOc9WSTc05/l
+# +m2bSivhb8lzmrx43vw53c5X2f+etourHOc63XMe1wlmLQ8+g3AYjaTFD2ZplY9g+xRbWly3
+# NPastYMrQN9cs4DvHYz+dHbomY8SOTctGDlcQfXND1Uz6cK3EXcVdpY37ltSuB55u339cNtu
+# F76NPTudHYR0zS2RZ/sd1maHVLdYI/cp31b2PvFW72jkvIi2tLTI94nXY/eCfeZK8Ap7GO1b
+# u7QAO8+8FjsLfFx7OowtfW6dLYRv22wZ031uYYc7M/aK5xvEfjp7vDPnQxW2OZuqndDxWeyw
+# dt6y5rXPt5xrqG8bW9a8tm8ZN1q1UyYTXvNT2HjN7VWLLL3GR7pl9nlUkx1Z+5xm2/qcYsu4
+# z2KHtfOWNad6jR92jGN9jvm2sSNbn1vYlj4n2TLus9h4zW1s/tn/e3iHV55MOXumvUarsvVX
+# +OknNGfrr/AK7DbMulLkbZh1VTa8uFSLHF5cqlVt5tW9eWRsH2VbVY10rp+TCu9Q6Rxj2/Ju
+# SJE2KG5TqW57848/jS15fXM7mX66ztv7cp16j/FGGr8DdtEN+5uL7sD49WvNOkwGIv5KaS3+
+# FsJamLmyFkYmrFnLde6+/4hZl7mOH6yS9SJ9DR5bXwatmLHCrd/PivTxulwlwSJJV8t14n1j
+# abIRCfde5mm2iojx/ib2B5eTaeyHl3cPP2N/KNbsx5Op6yw226fg/qbDeIbNc/DoHAR6Mu2I
+# dTp+X/zEsTCvGPvK9j0govsrfxqqdJN9cKhMY0vilwdPOebmRwqIy4+x+Tni+Hrc/PKAAnGZ
+# 7pXH2fyaYK6X4+B9CcPBt/RRt9z8FoDhoOpH/QJ9j+KAkkf9As2O4oA6N/xy6RWo8OMoqLYN
+# 1DDipqo+joIqEGtQqDWJRibXK9oO6igMB1Uu2XeKZwwHlSuO0zue6idVGVE4VQPheeiVIc8F
+# sV6Bg6oRx+knkup3Kl8VR+Vb5qGru2N14SNTx2E4qNhwnH1/+chUYRROvfvjeejK6khdeLm/
+# +HoFDqolHGfdX17sG5WviqPyLXBQ1WB9D/ULjSvHH9ZXUJOgOKA+UL9AZ1A4dThTftXxTOWh
+# qgRs7kI9gF4gwM0fnVfgjo/F19A96T9QSwECFAAUAAAACAC6Gqoso/Hf248DAACrGgAAAwAA
+# AAAAAAABACAAAAAAAAAARklMUEsFBgAAAAABAAEAMQAAALADAAAAAA==
+# ----GgOuLpDpIyE--1020998322088----
+#
+#
+#
--- /dev/null
+(^) 12345 x12345
+($) 12345 12345x
+(^)|($) 12345 x12345x
+($)|(^) 12345 x12345x
+2 12345 1x345
+(^)|2 12345 x1x345
+2|(^) 12345 x1x345
+($)|2 12345 1x345x
+2|($) 12345 1x345x
+(2)|(^) 12345 x1x345
+(^)|(2) 12345 x1x345
+(2)|($) 12345 1x345x
+($)|(2) 12345 1x345x
+((2)|(^)). 12345 xx45
+((^)|(2)). 12345 xx45
+.((2)|($)) 12345 x34x
+.(($)|(2)) 12345 x34x
+(^)|6 12345 x12345
+6|(^) 12345 x12345
+($)|6 12345 12345x
+6|($) 12345 12345x
+2|6|(^) 12345 x1x345
+2|(^)|6 12345 x1x345
+6|2|(^) 12345 x1x345
+6|(^)|2 12345 x1x345
+(^)|6|2 12345 x1x345
+(^)|2|6 12345 x1x345
+2|6|($) 12345 1x345x
+2|($)|6 12345 1x345x
+6|2|($) 12345 1x345x
+6|($)|2 12345 1x345x
+($)|6|2 12345 1x345x
+($)|2|6 12345 1x345x
+2|4|(^) 12345 x1x3x5
+2|(^)|4 12345 x1x3x5
+4|2|(^) 12345 x1x3x5
+4|(^)|2 12345 x1x3x5
+(^)|4|2 12345 x1x3x5
+(^)|2|4 12345 x1x3x5
+2|4|($) 12345 1x3x5x
+2|($)|4 12345 1x3x5x
+4|2|($) 12345 1x3x5x
+4|($)|2 12345 1x3x5x
+($)|4|2 12345 1x3x5x
+($)|2|4 12345 1x3x5x
+x{0}((2)|(^)) 12345 x1x345
+x{0}((^)|(2)) 12345 x1x345
+x{0}((2)|($)) 12345 1x345x
+x{0}(($)|(2)) 12345 1x345x
+x*((2)|(^)) 12345 x1x345
+x*((^)|(2)) 12345 x1x345
+x*((2)|($)) 12345 1x345x
+x*(($)|(2)) 12345 1x345x
+x{0}^ 12345 x12345
+x{0}$ 12345 12345x
+(x{0}^)|2 12345 x1x345
+(x{0}$)|2 12345 1x345x
--- /dev/null
+regex input expected actual bug?
+
+-------------------------------------------------------------
+(^) 12345 x12345 x12345
+($) 12345 12345x 12345x
+(^)|($) 12345 x12345x x12345x
+($)|(^) 12345 x12345x x12345x
+2 12345 1x345 1x345
+(^)|2 12345 x1x345 x1x345
+2|(^) 12345 x1x345 x1x345
+($)|2 12345 1x345x 1x345x
+2|($) 12345 1x345x 1x345x
+(2)|(^) 12345 x1x345 x1x345
+(^)|(2) 12345 x1x345 x1x345
+(2)|($) 12345 1x345x 1x345x
+($)|(2) 12345 1x345x 1x345x
+((2)|(^)). 12345 xx45 xx45
+((^)|(2)). 12345 xx45 xx45
+.((2)|($)) 12345 x34x x34x
+.(($)|(2)) 12345 x34x x34x
+(^)|6 12345 x12345 x12345
+6|(^) 12345 x12345 x12345
+($)|6 12345 12345x 12345x
+6|($) 12345 12345x 12345x
+2|6|(^) 12345 x1x345 x1x345
+2|(^)|6 12345 x1x345 x1x345
+6|2|(^) 12345 x1x345 x1x345
+6|(^)|2 12345 x1x345 x1x345
+(^)|6|2 12345 x1x345 x1x345
+(^)|2|6 12345 x1x345 x1x345
+2|6|($) 12345 1x345x 1x345x
+2|($)|6 12345 1x345x 1x345x
+6|2|($) 12345 1x345x 1x345x
+6|($)|2 12345 1x345x 1x345x
+($)|6|2 12345 1x345x 1x345x
+($)|2|6 12345 1x345x 1x345x
+2|4|(^) 12345 x1x3x5 x1x3x5
+2|(^)|4 12345 x1x3x5 x1x3x5
+4|2|(^) 12345 x1x3x5 x1x3x5
+4|(^)|2 12345 x1x3x5 x1x3x5
+(^)|4|2 12345 x1x3x5 x1x3x5
+(^)|2|4 12345 x1x3x5 x1x3x5
+2|4|($) 12345 1x3x5x 1x3x5x
+2|($)|4 12345 1x3x5x 1x3x5x
+4|2|($) 12345 1x3x5x 1x3x5x
+4|($)|2 12345 1x3x5x 1x3x5x
+($)|4|2 12345 1x3x5x 1x3x5x
+($)|2|4 12345 1x3x5x 1x3x5x
+x{0}((2)|(^)) 12345 x1x345 x1x345
+x{0}((^)|(2)) 12345 x1x345 x1x345
+x{0}((2)|($)) 12345 1x345x 1x345x
+x{0}(($)|(2)) 12345 1x345x 1x345x
+x*((2)|(^)) 12345 x1x345 x1x345
+x*((^)|(2)) 12345 x1x345 x1x345
+x*((2)|($)) 12345 1x345x 1x345x
+x*(($)|(2)) 12345 1x345x 1x345x
+x{0}^ 12345 x12345 x12345
+x{0}$ 12345 12345x 12345x
+(x{0}^)|2 12345 x1x345 x1x345
+(x{0}$)|2 12345 1x345x 1x345x
--- /dev/null
+# From arnold Thu May 9 17:27:03 2002
+# Return-Path: <arnold@skeeve.com>
+# Received: (from arnold@localhost)
+# by skeeve.com (8.11.6/8.11.6) id g49ER3K27925
+# for arnold; Thu, 9 May 2002 17:27:03 +0300
+# Date: Thu, 9 May 2002 17:27:03 +0300
+# From: Aharon Robbins <arnold@skeeve.com>
+# Message-Id: <200205091427.g49ER3K27925@skeeve.com>
+# To: arnold@skeeve.com
+# Subject: fixme
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBRule: Pattern Match (Other Patterns) (Score: 4850)
+# X-SBRule: Pattern Match (Spam Phone #) (Score: 0)
+# X-SBClass: Blocked
+# Status: RO
+#
+# Path: ord-read.news.verio.net!dfw-artgen!iad-peer.news.verio.net!news.verio.net!fu-berlin.de!uni-berlin.de!host213-120-137-48.in-addr.btopenworld.COM!not-for-mail
+# From: laura@madonnaweb.com (laura fairhead)
+# Newsgroups: comp.lang.awk
+# Subject: bug in gawk3.1.0 regex code
+# Date: Wed, 08 May 2002 23:31:40 GMT
+# Organization: that'll be the daewooo :)
+# Lines: 211
+# Message-ID: <3cd9b0f7.29675926@NEWS.CIS.DFN.DE>
+# Reply-To: laura@madonnaweb.com
+# NNTP-Posting-Host: host213-120-137-48.in-addr.btopenworld.com (213.120.137.48)
+# X-Trace: fu-berlin.de 1020900891 18168286 213.120.137.48 (16 [53286])
+# X-Newsreader: Forte Free Agent 1.21/32.243
+# Xref: dfw-artgen comp.lang.awk:13059
+#
+#
+# I believe I've just found a bug in gawk3.1.0 implementation of
+# extended regular expressions. It seems to be down to the alternation
+# operator; when using an end anchor '$' as a subexpression in an
+# alternation and the entire matched RE is a nul-string it fails
+# to match the end of string, for example;
+#
+# gsub(/$|2/,"x")
+# print
+#
+# input = 12345
+# expected output = 1x345x
+# actual output = 1x345
+#
+# The start anchor '^' always works as expected;
+#
+# gsub(/^|2/,"x")
+# print
+#
+# input = 12345
+# expected output = x1x345
+# actual output = x1x345
+#
+# This was with POSIX compliance enabled althought that doesn't
+# effect the result.
+#
+# I checked on gawk3.0.6 and got exactly the same results however
+# gawk2.15.6 gives the expected results.
+#
+# I'm about to post a bug report about this into gnu.utils.bug
+# but I thought I'd post it here first in case anyone has
+# any input/comments/whatever ....
+#
+# Complete test results were as follows;
+#
+# input 12345
+# output gsub(/regex/,"x",input)
+#
+# regex output
+# (^) x12345
+# ($) 12345x
+# (^)|($) x12345x
+# ($)|(^) x12345x
+# (2) 1x345
+# (^)|2 x1x345
+# 2|(^) x1x345
+# ($)|2 1x345
+# 2|($) 1x345
+# (2)|(^) x1x345
+# (^)|(2) x1x345
+# (2)|($) 1x345
+# ($)|(2) 1x345
+# .((2)|(^)) x345
+# .((^)|(2)) x345
+# .((2)|($)) x34x
+# .(($)|(2)) x34x
+# x{0}((2)|(^)) x1x345
+# x{0}((^)|(2)) x1x345
+# x{0}((2)|($)) 1x345
+# x{0}(($)|(2)) 1x345
+# x*((2)|(^)) x1x345
+# x*((^)|(2)) x1x345
+# x*((2)|($)) 1x345
+# x*(($)|(2)) 1x345
+#
+# Here's the test program I used, a few of the cases use ERE {n[,[m]]}
+# operators so that will have to be commented out or have a check
+# added or something (should have put a conditional in I know... ;-)
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+BEGIN{
+
+TESTSTR="12345"
+
+print "input "TESTSTR
+print "output gsub(/regex/,\"x\",input)"
+print ""
+
+print "regex output"
+$0=TESTSTR
+gsub(/(^)/,"x")
+print "(^) "$0
+
+$0=TESTSTR
+gsub(/($)/,"x")
+print "($) "$0
+
+$0=TESTSTR
+gsub(/(^)|($)/,"x")
+print "(^)|($) "$0
+
+$0=TESTSTR
+gsub(/($)|(^)/,"x")
+print "($)|(^) "$0
+
+$0=TESTSTR
+gsub(/2/,"x")
+print "(2) "$0
+
+$0=TESTSTR
+gsub(/(^)|2/,"x")
+print "(^)|2 "$0
+
+$0=TESTSTR
+gsub(/2|(^)/,"x")
+print "2|(^) "$0
+
+$0=TESTSTR
+gsub(/($)|2/,"x")
+print "($)|2 "$0
+
+$0=TESTSTR
+gsub(/2|($)/,"x")
+print "2|($) "$0
+
+$0=TESTSTR
+gsub(/(2)|(^)/,"x")
+print "(2)|(^) "$0
+
+$0=TESTSTR
+gsub(/(^)|(2)/,"x")
+print "(^)|(2) "$0
+
+$0=TESTSTR
+gsub(/(2)|($)/,"x")
+print "(2)|($) "$0
+
+$0=TESTSTR
+gsub(/($)|(2)/,"x")
+print "($)|(2) "$0
+
+$0=TESTSTR
+gsub(/.((2)|(^))/,"x")
+print ".((2)|(^)) "$0
+
+$0=TESTSTR
+gsub(/.((^)|(2))/,"x")
+print ".((^)|(2)) "$0
+
+$0=TESTSTR
+gsub(/.((2)|($))/,"x")
+print ".((2)|($)) "$0
+
+$0=TESTSTR
+gsub(/.(($)|(2))/,"x")
+print ".(($)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x{0}((2)|(^))/,"x")
+print "x{0}((2)|(^)) "$0
+
+$0=TESTSTR
+gsub(/x{0}((^)|(2))/,"x")
+print "x{0}((^)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x{0}((2)|($))/,"x")
+print "x{0}((2)|($)) "$0
+
+$0=TESTSTR
+gsub(/x{0}(($)|(2))/,"x")
+print "x{0}(($)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x*((2)|(^))/,"x")
+print "x*((2)|(^)) "$0
+
+$0=TESTSTR
+gsub(/x*((^)|(2))/,"x")
+print "x*((^)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x*((2)|($))/,"x")
+print "x*((2)|($)) "$0
+
+$0=TESTSTR
+gsub(/x*(($)|(2))/,"x")
+print "x*(($)|(2)) "$0
+
+$0=TESTSTR
+gsub(/x{0}^/,"x")
+print "x{0}^ "$0
+
+$0=TESTSTR
+gsub(/x{0}$/,"x")
+print "x{0}$ "$0
+
+$0=TESTSTR
+gsub(/(x{0}^)|2/,"x")
+print "(x{0}^)|2 "$0
+
+$0=TESTSTR
+gsub(/(x{0}$)|2/,"x")
+print "(x{0}$)|2 "$0
+
+
+}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# byefrom
+#
+# --
+# laura fairhead # laura@madonnaweb.com http://lf.8k.com
+# # if you are bored crack my sig.
+# 1F8B0808CABB793C0000666667002D8E410E83300C04EF91F2877D00CA138A7A
+# EAA98F30C494480157B623C4EF1B508FDED1CEFA9152A23DE35D661593C5318E
+# 630C313CD701BE92E390563326EE17A3CA818F5266E4C2461547F1F5267659CA
+# 8EE2092F76C329ED02CA430C5373CC62FF94BAC6210B36D9F9BC4AB53378D978
+# 80F2978A1A6E5D6F5133B67B6113178DC1059526698AFE5C17A5187E7D930492
+#
--- /dev/null
+input 12345
+output gsub(/regex/,"x",input)
+
+regex output
+(^) x12345
+($) 12345x
+(^)|($) x12345x
+($)|(^) x12345x
+(2) 1x345
+(^)|2 x1x345
+2|(^) x1x345
+($)|2 1x345x
+2|($) 1x345x
+(2)|(^) x1x345
+(^)|(2) x1x345
+(2)|($) 1x345x
+($)|(2) 1x345x
+.((2)|(^)) x345
+.((^)|(2)) x345
+.((2)|($)) x34x
+.(($)|(2)) x34x
+x{0}((2)|(^)) 12345
+x{0}((^)|(2)) 12345
+x{0}((2)|($)) 12345
+x{0}(($)|(2)) 12345
+x*((2)|(^)) x1x345
+x*((^)|(2)) x1x345
+x*((2)|($)) 1x345x
+x*(($)|(2)) 1x345x
+x{0}^ 12345
+x{0}$ 12345
+(x{0}^)|2 1x345
+(x{0}$)|2 1x345
--- /dev/null
+# From jose@monkey.org Thu Jun 5 11:48:35 2003
+# Return-Path: <jose@monkey.org>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h558eVvA012655
+# for <arnold@localhost>; Thu, 5 Jun 2003 11:48:35 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Thu, 05 Jun 2003 11:48:35 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Thu Jun 5 11:47:59 2003)
+# X-From_: jose@monkey.org Thu Jun 5 07:14:45 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h554EdY08108 for <arobbins@actcom.co.il>;
+# Thu, 5 Jun 2003 07:14:41 +0300 (EET DST)
+# (rfc931-sender: smtp.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h554G3To008304
+# for <arobbins@actcom.co.il>; Thu, 5 Jun 2003 07:16:05 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7/8.11.6) with ESMTP id h554Ean08172
+# for <arnold@skeeve.com>; Thu, 5 Jun 2003 00:14:36 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.20)
+# id 19Nm96-0001xE-1i
+# for arnold@gnu.ai.mit.edu; Thu, 05 Jun 2003 00:14:36 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20)
+# id 19Nm8x-0005ge-Dz
+# for arnold@gnu.ai.mit.edu; Thu, 05 Jun 2003 00:14:28 -0400
+# Received: from naughty.monkey.org ([66.93.9.164])
+# by monty-python.gnu.org with esmtp (Exim 4.20)
+# id 19Nm8w-0005VM-Ko
+# for arnold@gnu.ai.mit.edu; Thu, 05 Jun 2003 00:14:26 -0400
+# Received: by naughty.monkey.org (Postfix, from userid 1203)
+# id C15511BA97B; Thu, 5 Jun 2003 00:14:19 -0400 (EDT)
+# Received: from localhost (localhost [127.0.0.1])
+# by naughty.monkey.org (Postfix) with ESMTP
+# id BF9821BA969; Thu, 5 Jun 2003 00:14:19 -0400 (EDT)
+# Date: Thu, 5 Jun 2003 00:14:19 -0400 (EDT)
+# From: Jose Nazario <jose@monkey.org>
+# To: bug-gnu-utils@prep.ai.mit.edu, arnold@gnu.ai.mit.edu,
+# netbsd-bugs@netbsd.org
+# Subject: bug in gawk/gsub() (not present in nawk)
+# Message-ID: <Pine.BSO.4.51.0306050007160.31577@naughty.monkey.org>
+# MIME-Version: 1.0
+# Content-Type: TEXT/PLAIN; charset=US-ASCII
+# X-Spam-Status: No, hits=-1.2 required=5.0
+# tests=SPAM_PHRASE_00_01,USER_AGENT_PINE
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: R
+#
+# while playing with some tools in data massaging, i had to migrate from an
+# openbsd/nawk system to a netbsd/gawk system. i found the folllowing
+# behavior, which seems to be a bug.
+#
+# the following gsub() pattern has a strange effect under gawk which is not
+# visible in nawk (at least as compiled on openbsd). the intention is to
+# take a string like "This Is a Title: My Title?" and turn it into a
+# normalized string: "ThisIsaTitleMyTitle". to do this, i wrote the
+# following gross gsub line in an awk script:
+#
+# gsub(/[\ \"-\/\\:;\[\]\@\?\.\,\$]/, "", $2)
+# print $2
+#
+# in gawk, as found in netbsd-macppc/1.5.2, this will drop the first letter
+# of every word. the resulting string will be "hissitleyitle", while in nawk
+# as built on openbsd-3.3 this will get it correct.
+#
+# any insights? the inconsistency with this relatively naive pattern seems a
+# bit odd. (i would up installing nawk built from openbsd sources.)
+#
+# thanks. sorry i didn't send a better bug report, netbsd folks, i'm not
+# much of a netbsd user, and i dont have send-pr set up. yes, this is a
+# slightly older version of netbsd and gawk:
+#
+# $ uname -a
+# NetBSD entropy 1.5.2 NetBSD 1.5.2 (GENERIC) #0: Sun Feb 10 02:00:04 EST
+# 2002 jose@entropy:/usr/src/sys/arch/macppc/compile/GENERIC macppc
+# $ awk --version
+# GNU Awk 3.0.3
+# Copyright (C) 1989, 1991-1997 Free Software Foundation.
+#
+#
+#
+# thanks.
+#
+# ___________________________
+# jose nazario, ph.d. jose@monkey.org
+# http://monkey.org/~jose/
+#
+#
+{
+ gsub(/[\ \"-\/\\:;\[\]\@\?\.\,\$]/, "")
+ print
+}
--- /dev/null
+This Is a Title: My Title?
--- /dev/null
+ThisIsaTitleMyTitle
--- /dev/null
+/@K@CODE/ { print ; getline temp ; print temp ;next }
+{print}
--- /dev/null
+# Test program from Paul Eggert, eggert@cs.ucla.edu, Jan. 14, 2005
+
+BEGIN {
+ e = "1(e)"
+ ex = "3e2(ex)"
+ x = "6e5(x)"
+
+ print e+0, x+0
+ print 0x
+ print 0e+x
+ print 0ex
+ print 010e2
+ print 0e9.3
+}
+
+# Expected results:
+# 1 600000
+# 06e5(x)
+# 0600001
+# 03e2(ex)
+# 1000
+# 00.3
--- /dev/null
+1 600000
+06e5(x)
+0600001
+03e2(ex)
+1000
+00.3
--- /dev/null
+# Test which attempts to repeat examples of formatted output
+# from "C a reference manual" by Harbison and Steele.
+#
+# In the second series of outputs formats of a type "%5%" are skipped
+# since my old copy of H&S explicitely requires padding ("...%05% will
+# print 0000%..."), whereas Standard says "...the complete conversion
+# specification shall be %%".
+#
+# Michal Jaegermann - michal@phys.ualberta.ca
+
+
+BEGIN {
+ zero = "0";
+ alt = "#";
+ spc = " ";
+ plus = "+";
+ just = "-";
+ value[0] = 45;
+ value[1] = 45;
+ value[2] = 45;
+ value[3] = 12.678;
+ value[4] = 12.678;
+ value[5] = 12.678;
+ value[6] = "zap";
+ value[7] = "*";
+ value[8] = -3.4567;
+ value[9] = -3.4567;
+ value[10]= -3.4567;
+ value[11]= -3.4567;
+ oper[0] = "5d";
+ oper[1] = "5o";
+ oper[2] = "5x";
+ oper[3] = "7.2f";
+ oper[4] = "10.2e";
+ oper[5] = "10.4g";
+ oper[6] = "5s";
+ oper[7] = "5c";
+ oper[8] = "7.1G";
+ oper[9] = "7.2f";
+ oper[10] = "10.2e";
+ oper[11] = "10.4g";
+
+
+ for (r = 0; r < 12; r += 6) {
+ for (j = 2; j > 0; --j) {
+ for (p = 2; p > 0; --p) {
+ for (s = 2; s > 0; --s) {
+ for (a = 2; a > 0; --a) {
+ for (z = 2; z > 0; --z) {
+ fmt = "%" substr(just,j,1) substr(plus,p,1) \
+ substr(spc,s,1) substr(alt,a,1) substr(zero,z,1);
+ fstr = sprintf(\
+ "%6s|%s%s|%s%s|%s%s|%s%s|%s%s|%s%s|\n",
+ fmt,
+ fmt, oper[r],
+ fmt, oper[r+1],
+ fmt, oper[r+2],
+ fmt, oper[r+3],
+ fmt, oper[r+4],
+ fmt, oper[r+5]);
+ printf(fstr, value[r], value[r+1],
+ value[r+2], value[r+3],
+ value[r+4], value[r+5]);
+ }
+ }
+ }
+ }
+ }
+ print "";
+ }
+}
+
+
+
--- /dev/null
+ %| 45| 55| 2d| 12.68| 1.27e+01| 12.68|
+ %0|00045|00055|0002d|0012.68|001.27e+01|0000012.68|
+ %#| 45| 055| 0x2d| 12.68| 1.27e+01| 12.68|
+ %#0|00045|00055|0x02d|0012.68|001.27e+01|0000012.68|
+ % | 45| 55| 2d| 12.68| 1.27e+01| 12.68|
+ % 0| 0045|00055|0002d| 012.68| 01.27e+01| 000012.68|
+ % #| 45| 055| 0x2d| 12.68| 1.27e+01| 12.68|
+ % #0| 0045|00055|0x02d| 012.68| 01.27e+01| 000012.68|
+ %+| +45| 55| 2d| +12.68| +1.27e+01| +12.68|
+ %+0|+0045|00055|0002d|+012.68|+01.27e+01|+000012.68|
+ %+#| +45| 055| 0x2d| +12.68| +1.27e+01| +12.68|
+ %+#0|+0045|00055|0x02d|+012.68|+01.27e+01|+000012.68|
+ %+ | +45| 55| 2d| +12.68| +1.27e+01| +12.68|
+ %+ 0|+0045|00055|0002d|+012.68|+01.27e+01|+000012.68|
+ %+ #| +45| 055| 0x2d| +12.68| +1.27e+01| +12.68|
+ %+ #0|+0045|00055|0x02d|+012.68|+01.27e+01|+000012.68|
+ %-|45 |55 |2d |12.68 |1.27e+01 |12.68 |
+ %-0|45 |55 |2d |12.68 |1.27e+01 |12.68 |
+ %-#|45 |055 |0x2d |12.68 |1.27e+01 |12.68 |
+ %-#0|45 |055 |0x2d |12.68 |1.27e+01 |12.68 |
+ %- | 45 |55 |2d | 12.68 | 1.27e+01 | 12.68 |
+ %- 0| 45 |55 |2d | 12.68 | 1.27e+01 | 12.68 |
+ %- #| 45 |055 |0x2d | 12.68 | 1.27e+01 | 12.68 |
+ %- #0| 45 |055 |0x2d | 12.68 | 1.27e+01 | 12.68 |
+ %-+|+45 |55 |2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+0|+45 |55 |2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+#|+45 |055 |0x2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+#0|+45 |055 |0x2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+ |+45 |55 |2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+ 0|+45 |55 |2d |+12.68 |+1.27e+01 |+12.68 |
+ %-+ #|+45 |055 |0x2d |+12.68 |+1.27e+01 |+12.68 |
+%-+ #0|+45 |055 |0x2d |+12.68 |+1.27e+01 |+12.68 |
+
+ %| zap| *| -3| -3.46| -3.46e+00| -3.457|
+ %0|00zap|0000*|-000003|-003.46|-03.46e+00|-00003.457|
+ %#| zap| *| -3.| -3.46| -3.46e+00| -3.457|
+ %#0|00zap|0000*|-00003.|-003.46|-03.46e+00|-00003.457|
+ % | zap| *| -3| -3.46| -3.46e+00| -3.457|
+ % 0|00zap|0000*|-000003|-003.46|-03.46e+00|-00003.457|
+ % #| zap| *| -3.| -3.46| -3.46e+00| -3.457|
+ % #0|00zap|0000*|-00003.|-003.46|-03.46e+00|-00003.457|
+ %+| zap| *| -3| -3.46| -3.46e+00| -3.457|
+ %+0|00zap|0000*|-000003|-003.46|-03.46e+00|-00003.457|
+ %+#| zap| *| -3.| -3.46| -3.46e+00| -3.457|
+ %+#0|00zap|0000*|-00003.|-003.46|-03.46e+00|-00003.457|
+ %+ | zap| *| -3| -3.46| -3.46e+00| -3.457|
+ %+ 0|00zap|0000*|-000003|-003.46|-03.46e+00|-00003.457|
+ %+ #| zap| *| -3.| -3.46| -3.46e+00| -3.457|
+ %+ #0|00zap|0000*|-00003.|-003.46|-03.46e+00|-00003.457|
+ %-|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-0|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-#|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %-#0|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %- |zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %- 0|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %- #|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %- #0|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %-+|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-+0|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-+#|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %-+#0|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+ %-+ |zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-+ 0|zap |* |-3 |-3.46 |-3.46e+00 |-3.457 |
+ %-+ #|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+%-+ #0|zap |* |-3. |-3.46 |-3.46e+00 |-3.457 |
+
--- /dev/null
+BEGIN {
+ # 1. Should print aCa
+ IGNORECASE = 1
+ FS = "[c]"
+ IGNORECASE = 0
+ $0 = "aCa"
+ print $1
+
+ # 2. Should print a
+ IGNORECASE = 1
+ FS = "[c]"
+ $0 = "aCa"
+ print $1
+
+ # 3. Should print a
+ IGNORECASE = 1
+ FS = "C"
+ IGNORECASE = 0
+ $0 = "aCa"
+ print $1
+
+ # 4. Should print aCa
+ IGNORECASE = 1
+ FS = "c"
+ $0 = "aCa"
+ print $1
+
+ # 5. Should print aCa
+ FS = "xy"
+ IGNORECASE = 0
+ FS = "c"
+ IGNORECASE = 1
+ $0 = "aCa"
+ print $1
+
+ # 6. Should print aCa
+ FS = "xy"
+ IGNORECASE = 0
+ FS = "c"
+ IGNORECASE = 1
+ split("aCa",a)
+ print a[1]
+}
--- /dev/null
+aCa
+a
+a
+aCa
+aCa
+aCa
--- /dev/null
+BEGIN { RS = "[[:upper:]]+" }
+{ print ; IGNORECASE = ! IGNORECASE }
--- /dev/null
+1111AAAA2222bbbb
\ No newline at end of file
--- /dev/null
+1111
+2222
--- /dev/null
+#From Jeffrey.B.Woodward@Hitchcock.ORG Mon Feb 21 09:33:32 2000
+#Message-id: <12901034@mailbox2.Hitchcock.ORG>
+#Date: 20 Feb 2000 18:14:11 EST
+#From: Jeffrey.B.Woodward@Hitchcock.ORG (Jeffrey B. Woodward)
+#Subject: gawk 3.0.4 bug
+#To: bug-gnu-utils@gnu.org
+#Cc: arnold@gnu.org
+#
+#O/S: Digital UNIX 4.0D
+#
+#C Compiler: DEC C
+#
+#gawk version: 3.0.4
+#
+#Sample Program:
+#gawk '
+ BEGIN {
+ pattern[1] = "bar" ; ignore[1] = 1
+ pattern[2] = "foo" ; ignore[2] = 0
+ }
+
+ {
+ for (i = 1 ; i <= 2 ; i++) {
+ IGNORECASE = ignore[i]
+ print match($0, pattern[i]) " " pattern[i] ":" $0
+ }
+ }
+#' << -EOF-
+#This is foo
+#This is bar
+#-EOF-
+#
+#Program Output:
+#0 bar:This is foo
+#0 foo:This is foo
+#9 bar:This is bar
+#9 foo:This is bar
+#
+#
+#**Expected** Output:
+#0 bar:This is foo
+#9 foo:This is foo
+#9 bar:This is bar
+#0 foo:This is bar
+#
+#
+#This problem appears to be directly related to IGNORECASE. If
+#IGNORECASE remains constant, the program behaves as expected;
+#however, switching IGNORECASE seems to causes problems - it is
+#almost as though the pattern stored in the variable is treated
+#as a constant and the regexp() is not recompiled(?) - just a
+#guess...
+#
+#
+#Thanks,
+#-Jeff Woodward
--- /dev/null
+This is foo
+This is bar
--- /dev/null
+0 bar:This is foo
+9 foo:This is foo
+9 bar:This is bar
+0 foo:This is bar
--- /dev/null
+BEGIN {
+ IGNORECASE=1
+ FS="[^a-z]+"
+}
+{
+ for (i=1; i<NF; i++) printf "%s, ", $i
+ printf "%s\n", $NF
+}
--- /dev/null
+this is handled ok
+This is Not hanDLed Well
--- /dev/null
+this, is, handled, ok
+This, is, Not, hanDLed, Well
--- /dev/null
+# Based on test program submitted by:
+# Date: Sun, 7 Sep 2003 23:11:51 +0200
+# From: Michael Mauch <michael.mauch@gmx.de>
+# To: bug-gawk@gnu.org
+# Subject: Internal error in gawk-3.1.3 with character class
+
+BEGIN {
+ IGNORECASE = 1
+ if ("a" ~ /[[:alnum:]]/)
+ print "OK"
+ else
+ print "NOT OK"
+}
--- /dev/null
+BEGIN { IGNORECASE = 1 }
+{ sub(/y/, ""); print }
--- /dev/null
+BEGIN {
+ k = 0
+ x = 100
+ # Added k limit test after finding some systems that didn't terminate
+ # the loop correctly, sigh...
+ do { k++; y = x ; x *= 1000; print x,y } while ( y < x && k < 1700)
+ print "loop terminated"
+}
--- /dev/null
+100000 100
+100000000 100000
+1e+11 100000000
+1e+14 1e+11
+1e+17 1e+14
+1e+20 1e+17
+1e+23 1e+20
+1e+26 1e+23
+1e+29 1e+26
+1e+32 1e+29
+1e+35 1e+32
+1e+38 1e+35
+1e+41 1e+38
+1e+44 1e+41
+1e+47 1e+44
+1e+50 1e+47
+1e+53 1e+50
+1e+56 1e+53
+1e+59 1e+56
+1e+62 1e+59
+1e+65 1e+62
+1e+68 1e+65
+1e+71 1e+68
+1e+74 1e+71
+1e+77 1e+74
+1e+80 1e+77
+1e+83 1e+80
+1e+86 1e+83
+1e+89 1e+86
+1e+92 1e+89
+1e+95 1e+92
+1e+98 1e+95
+1e+101 1e+98
+1e+104 1e+101
+1e+107 1e+104
+1e+110 1e+107
+1e+113 1e+110
+1e+116 1e+113
+1e+119 1e+116
+1e+122 1e+119
+1e+125 1e+122
+1e+128 1e+125
+1e+131 1e+128
+1e+134 1e+131
+1e+137 1e+134
+1e+140 1e+137
+1e+143 1e+140
+1e+146 1e+143
+1e+149 1e+146
+1e+152 1e+149
+1e+155 1e+152
+1e+158 1e+155
+1e+161 1e+158
+1e+164 1e+161
+1e+167 1e+164
+1e+170 1e+167
+1e+173 1e+170
+1e+176 1e+173
+1e+179 1e+176
+1e+182 1e+179
+1e+185 1e+182
+1e+188 1e+185
+1e+191 1e+188
+1e+194 1e+191
+1e+197 1e+194
+1e+200 1e+197
+1e+203 1e+200
+1e+206 1e+203
+1e+209 1e+206
+1e+212 1e+209
+1e+215 1e+212
+1e+218 1e+215
+1e+221 1e+218
+1e+224 1e+221
+1e+227 1e+224
+1e+230 1e+227
+1e+233 1e+230
+1e+236 1e+233
+1e+239 1e+236
+1e+242 1e+239
+1e+245 1e+242
+1e+248 1e+245
+1e+251 1e+248
+1e+254 1e+251
+1e+257 1e+254
+1e+260 1e+257
+1e+263 1e+260
+1e+266 1e+263
+1e+269 1e+266
+1e+272 1e+269
+1e+275 1e+272
+1e+278 1e+275
+1e+281 1e+278
+1e+284 1e+281
+1e+287 1e+284
+1e+290 1e+287
+1e+293 1e+290
+1e+296 1e+293
+1e+299 1e+296
+1e+302 1e+299
+1e+305 1e+302
+1e+308 1e+305
+Inf 1e+308
+Inf Inf
+loop terminated
--- /dev/null
+BEGIN { print getline < "file" ".txt" }
--- /dev/null
+BEGIN {
+ bool = ((b = 1) in c);
+ print bool, b # gawk-3.0.1 prints "0 "; should print "0 1"
+}
--- /dev/null
+BEGIN { printf "%.10d:%.10x\n", 5, 14 }
--- /dev/null
+0000000005:000000000e
--- /dev/null
+# From arnold@f7.net Fri Nov 26 11:53:12 2004
+# X-Envelope-From: james@nocrew.org
+# X-Envelope-To: <arnold@skeeve.com>
+# To: bug-gawk@gnu.org
+# Subject: gawk 3.1.4: reproducible hang, regression from 3.1.3
+# From: James Troup <james@nocrew.org>
+# Date: Fri, 26 Nov 2004 03:14:05 +0000
+# Message-ID: <877jo9qp36.fsf@shiri.gloaming.local>
+# User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)
+# MIME-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+#
+#
+# Hi,
+#
+# A Debian user reported[0] gawk 3.1.4 broke a (relatively) complex
+# program that makes extensive use of awk, called 'apt-move'. I finally
+# managed to reduced the problem down to a 3 line test case, enclosed
+# below[1].
+#
+# I believe the problem comes from the following code, introduced in
+# 3.1.4:
+#
+# [io.c, line 560]
+# | for (rp = red_head; rp != NULL; rp = rp->next) {
+# | if ((rp->flag & RED_EOF) && tree->type == Node_redirect_pipein) {
+# | if (rp->pid != -1)
+# | wait_any(0);
+# | }
+#
+# The problem is that, if we have an existing redirect which is a simple
+# file redirect[b] and it's hit EOF and we try to create a new '|'
+# redirect[c], this new code will try to wait(2) and if there are any
+# other redirects which _did_ spawn a child (like [a]) the wait() will
+# hang indefinitely waiting for it to exit.
+#
+# Hope that makes sense :)
+#
+# --
+# James
+#
+# [0] http://bugs.debian.org/263964
+#
+# [1]
+# ================================================================================
+#!/usr/bin/gawk -f
+
+BEGIN {
+ printf "" | "cat" # [a]
+ getline line < "/dev/null" # [b]
+ "true" | getline line # [c]
+}
+# ================================================================================
--- /dev/null
+# check that values with leading digits get converted the
+# right way, based on a note in comp.lang.awk.
+#
+# run with gawk -v x=2E -f leaddig.awk
+BEGIN {
+ print "x =", x, (x == 2), (x == 2E0), (x == 2E), (x == 2D)
+}
--- /dev/null
+x = 2E 0 0 0 0
--- /dev/null
+BEGIN {
+ RS = ""; FS = "\n"
+}
+
+{
+ print "Name is: ", $1
+ print "Address is: ", $2
+ print "City and State are: ", $3
+ print ""
+}
--- /dev/null
+
+Jane Doe
+123 Main Street
+Anywhere, SE 12345-6789
+
+John Smith
+456 Tree-lined Avenue
+Smallville, MW 98765-4321
+
--- /dev/null
+Name is: Jane Doe
+Address is: 123 Main Street
+City and State are: Anywhere, SE 12345-6789
+
+Name is: John Smith
+Address is: 456 Tree-lined Avenue
+City and State are: Smallville, MW 98765-4321
+
--- /dev/null
+BEGIN { print "Found it." }
--- /dev/null
+# lint.awk --- test lint variable
+
+BEGIN {
+ a[1] = 1
+ LINT = 1
+ delete a[2]
+ LINT = ""
+ delete a[3]
+ LINT = "true"
+ delete a[4]
+ LINT = 0
+ delete a[5]
+ print "done"
+}
--- /dev/null
+gawk: lint.awk:6: warning: delete: index `2' not in array `a'
+gawk: lint.awk:7: warning: turning off `--lint' due to assignment to `LINT'
+gawk: lint.awk:10: warning: delete: index `4' not in array `a'
+gawk: lint.awk:11: warning: turning off `--lint' due to assignment to `LINT'
+done
--- /dev/null
+{ if (/a\52b/) print "match" ; else print "no match" }
--- /dev/null
+# From arnold@f7.net Wed Apr 27 09:48:37 2005
+# Return-Path: <arnold@f7.net>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.11/8.12.11) with ESMTP id j3R6mZVm015791
+# for <arnold@localhost>; Wed, 27 Apr 2005 09:48:37 +0300
+# Received: from pop.012.net.il [84.95.5.221]
+# by localhost with POP3 (fetchmail-6.2.5)
+# for arnold@localhost (single-drop); Wed, 27 Apr 2005 09:48:37 +0300 (IDT)
+# Received: from mtain3.012.net.il ([10.220.5.7])
+# by i_mss3.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0IFK00L1DIZ02530@i_mss3.012.net.il> for arobbins@012.net.il;
+# Tue, 26 Apr 2005 22:18:36 +0300 (IDT)
+# Received: from VScan3 ([10.220.20.3])
+# by i_mtain3.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0IFK007U1IZ0U980@i_mtain3.012.net.il> for arobbins@012.net.il
+# (ORCPT arobbins@012.net.il); Tue, 26 Apr 2005 22:18:36 +0300 (IDT)
+# Received: from i_mtain1.012.net.il ([10.220.5.1])
+# by VScan3 with InterScan Messaging Security Suite; Tue,
+# 26 Apr 2005 22:15:22 +0300
+# Received: from f7.net ([209.61.216.22])
+# by i_mtain1.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0IFK009SIIYRN7G0@i_mtain1.012.net.il> for arobbins@012.net.il;
+# Tue, 26 Apr 2005 22:18:33 +0300 (IDT)
+# Received: (from arnold@localhost) by f7.net (8.11.7-20030920/8.11.7)
+# id j3QJFAg18376 for arobbins@012.net.il; Tue, 26 Apr 2005 15:15:10 -0400
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7-20030920/8.11.7) with ESMTP id j3QJF5J18304 for
+# <arnold@skeeve.com>; Tue, 26 Apr 2005 15:15:06 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.34)
+# id 1DQVVh-0004gD-CH for bug-gawk@gnu.org; Tue, 26 Apr 2005 15:14:17 -0400
+# Received: from Debian-exim by monty-python.gnu.org with spam-scanned
+# (Exim 4.34) id 1DQVYa-0002PR-2b for bug-gawk@gnu.org; Tue,
+# 26 Apr 2005 15:17:56 -0400
+# Received: from [129.183.4.8] (helo=ecfrec.frec.bull.fr)
+# by monty-python.gnu.org with esmtp (Exim 4.34)
+# id 1DQVYZ-0002Lr-EF for bug-gawk@gnu.org; Tue, 26 Apr 2005 15:17:15 -0400
+# Received: from localhost (localhost [127.0.0.1])
+# by ecfrec.frec.bull.fr (Postfix) with ESMTP id 5782819D907 for
+# <bug-gawk@gnu.org>; Tue, 26 Apr 2005 21:12:53 +0200 (CEST)
+# Received: from ecfrec.frec.bull.fr ([127.0.0.1])
+# by localhost (ecfrec.frec.bull.fr [127.0.0.1]) (amavisd-new, port 10024)
+# with ESMTP id 06763-10 for <bug-gawk@gnu.org>; Tue,
+# 26 Apr 2005 21:12:51 +0200 (CEST)
+# Received: from ecn002.frec.bull.fr (ecn002.frec.bull.fr [129.183.4.6])
+# by ecfrec.frec.bull.fr (Postfix) with ESMTP id 4488B19D906 for
+# <bug-gawk@gnu.org>; Tue, 26 Apr 2005 21:12:51 +0200 (CEST)
+# Received: from daphne ([129.183.192.6])
+# by ecn002.frec.bull.fr (Lotus Domino Release 5.0.12)
+# with ESMTP id 2005042621231613:3312 ; Tue, 26 Apr 2005 21:23:16 +0200
+# Date: Tue, 26 Apr 2005 21:12:49 +0200 (CEST)
+# From: Jean-Marc Saffroy <jean-marc.saffroy@ext.bull.net>
+# Subject: GNU awk unable to handle 64-bit ints on IA64
+# X-X-Sender: saffroyj@daphne.frec.bull.fr
+# To: bug-gawk@gnu.org
+# Message-id: <Pine.LNX.4.61.0504261916140.22370@daphne.frec.bull.fr>
+# MIME-version: 1.0
+# Content-type: TEXT/PLAIN; charset=US-ASCII; format=flowed
+# X-MIMETrack: Itemize by SMTP Server on ECN002/FR/BULL(Release 5.0.12 |February
+# 13, 2003) at 26/04/2005 21:23:16,
+# Serialize by Router on ECN002/FR/BULL(Release 5.0.12 |February 13,
+# 2003) at 26/04/2005 21:23:16, Serialize complete at 26/04/2005 21:23:16
+# X-Virus-Scanned: by amavisd-new at frec.bull.fr
+# Original-recipient: rfc822;arobbins@012.net.il
+# X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on skeeve.com
+# X-Spam-Level:
+# X-Spam-Status: No, hits=-4.9 required=5.0 tests=BAYES_00 autolearn=ham
+# version=2.63
+# Status: RO
+#
+#
+# Hello,
+#
+# I have rounding problems when manipulating 64-bit ints (actually they are
+# addresses) on Linux/IA64:
+#
+# $ echo 0xa000000100000813|./gawk '{printf("0x%lx\n",strtonum($1));}'
+# 0xa000000100000800
+# $ echo 0xffffffffffffffff|./gawk '{printf("0x%lx\n",strtonum($1));}'
+# 0x8000000000000000
+# $ ./gawk --version|head -1
+# GNU Awk 3.1.4
+#
+# The problem seems to be that AWKNUM is defined to be a double, which has a
+# 53-bit mantissa. On IA64 with gcc 3.2.3 (maybe other compilers as well)
+# there is a long double type with a larger mantissa:
+#
+# $ grep define.*LDBL_MANT_DIG /usr/lib/gcc-lib/ia64-redhat-linux/3.2.3/include/float.h
+# #define LDBL_MANT_DIG 64
+#
+# So I changed AWKNUM to be a long double; this does not seem to be
+# sufficient, because of some dubious casts to double (there may be others
+# left, I didn't check), see patch below. Now it's much nicer:
+#
+# $ echo 0xa000000100000813|./gawk '{printf("0x%lx\n",strtonum($1));}'
+# 0xa000000100000813
+# $ echo 0xffffffffffffffff|./gawk '{printf("0x%lx\n",strtonum($1));}'
+# 0xffffffffffffffff
+#
+# Maybe the gawk configure script should set AWKNUM to be a long double on
+# Linux/IA64?
+#
+#
+# Regards,
+#
+# --
+# Jean-Marc Saffroy - jean-marc.saffroy@ext.bull.net
+#
+#
+# diff -ru gawk-3.1.4/awk.h gawk/awk.h
+# --- gawk-3.1.4/awk.h 2004-07-26 16:11:05.000000000 +0200
+# +++ gawk/awk.h 2005-04-26 19:19:10.545419273 +0200
+# @@ -273,7 +273,7 @@
+# /* ------------------ Constants, Structures, Typedefs ------------------ */
+#
+# #ifndef AWKNUM
+# -#define AWKNUM double
+# +#define AWKNUM long double
+# #endif
+#
+# #ifndef TRUE
+# diff -ru gawk-3.1.4/builtin.c gawk/builtin.c
+# --- gawk-3.1.4/builtin.c 2004-07-13 09:55:28.000000000 +0200
+# +++ gawk/builtin.c 2005-04-26 20:53:41.211365432 +0200
+# @@ -578,7 +578,7 @@
+# char *cend = &cpbuf[30];/* chars, we lose, but seems unlikely */
+# char *cp;
+# const char *fill;
+# - double tmpval;
+# + AWKNUM tmpval;
+# char signchar = FALSE;
+# size_t len;
+# int zero_flag = FALSE;
+# @@ -2773,16 +2773,16 @@
+# do_strtonum(NODE *tree)
+# {
+# NODE *tmp;
+# - double d;
+# + AWKNUM d;
+#
+# tmp = tree_eval(tree->lnode);
+#
+# if ((tmp->flags & (NUMBER|NUMCUR)) != 0)
+# - d = (double) force_number(tmp);
+# + d = (AWKNUM) force_number(tmp);
+# else if (isnondecimal(tmp->stptr))
+# d = nondec2awknum(tmp->stptr, tmp->stlen);
+# else
+# - d = (double) force_number(tmp);
+# + d = (AWKNUM) force_number(tmp);
+#
+# free_temp(tmp);
+# return tmp_number((AWKNUM) d);
+#
+#
+# #####################################################################################
+# This Mail Was Scanned by 012.net Anti Virus Service - Powered by TrendMicro Interscan
+#
+{ printf("0x%lx\n",strtonum($1)); }
--- /dev/null
+0xa000000100000813
+0xffffffffffffffff
--- /dev/null
+0xa000000100000813
+0xffffffffffffffff
--- /dev/null
+{sub( "^.*AA", "BB"); print}
--- /dev/null
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
--- /dev/null
+BB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
--- /dev/null
+# From Gawk Manual modified by bug fix and removal of punctuation
+
+# Invoker can customize sort command if necessary.
+BEGIN {
+ if (!SORT) SORT = "LC_ALL=C sort"
+}
+
+# Record every word which is used at least once
+{
+ for (i = 1; i <= NF; i++) {
+ tmp = tolower($i)
+ if (0 != (pos = match(tmp, /([a-z]|-)+/)))
+ used[substr(tmp, pos, RLENGTH)] = 1
+ }
+}
+
+#Find a number of distinct words longer than 10 characters
+END {
+ num_long_words = 0
+ for (x in used)
+ if (length(x) > 10) {
+ ++num_long_words
+ print x | SORT
+ }
+ print(num_long_words, "long words") | SORT
+ close(SORT)
+}
--- /dev/null
+.ds PX \s-1POSIX\s+1
+.ds UX \s-1UNIX\s+1
+.ds AN \s-1ANSI\s+1
+.TH GAWK 1 "May 28 1991" "Free Software Foundation" "Utility Commands"
+.SH NAME
+gawk \- pattern scanning and processing language
+.SH SYNOPSIS
+.B gawk
+[
+.B \-W
+.I gawk-options
+] [
+.BI \-F\^ fs
+] [
+.B \-v
+.IR var = val
+]
+.B \-f
+.I program-file
+[
+.B \-\^\-
+] file .\^.\^.
+.br
+.B gawk
+[
+.B \-W
+.I gawk-options
+] [
+.BI \-F\^ fs
+] [
+.B \-v
+.IR var = val
+] [
+.B \-\^\-
+]
+.I program-text
+file .\^.\^.
+.SH DESCRIPTION
+.I Gawk
+is the GNU Project's implementation of the AWK programming language.
+It conforms to the definition of the language in
+the \*(PX 1003.2 Command Language And Utilities Standard
+(draft 11).
+This version in turn is based on the description in
+.IR "The AWK Programming Language" ,
+by Aho, Kernighan, and Weinberger,
+with the additional features defined in the System V Release 4 version
+of \*(UX
+.IR awk .
+.I Gawk
+also provides some GNU-specific extensions.
+.PP
+The command line consists of options to
+.I gawk
+itself, the AWK program text (if not supplied via the
+.B \-f
+option), and values to be made
+available in the
+.B ARGC
+and
+.B ARGV
+pre-defined AWK variables.
+.SH OPTIONS
+.PP
+.I Gawk
+accepts the following options, which should be available on any implementation
+of the AWK language.
+.TP
+.BI \-F fs
+Use
+.I fs
+for the input field separator (the value of the
+.B FS
+predefined
+variable).
+.TP
+\fB\-v\fI var\fR\^=\^\fIval\fR
+Assign the value
+.IR val ,
+to the variable
+.IR var ,
+before execution of the program begins.
+Such variable values are available to the
+.B BEGIN
+block of an AWK program.
+.TP
+.BI \-f " program-file"
+Read the AWK program source from the file
+.IR program-file ,
+instead of from the first command line argument.
+Multiple
+.B \-f
+options may be used.
+.TP
+.B \-\^\-
+Signal the end of options. This is useful to allow further arguments to the
+AWK program itself to start with a ``\-''.
+This is mainly for consistency with the argument parsing convention used
+by most other \*(PX programs.
+.PP
+Following the \*(PX standard,
+.IR gawk -specific
+options are supplied via arguments to the
+.B \-W
+option. Multiple
+.B \-W
+options may be supplied, or multiple arguments may be supplied together
+if they are separated by commas, or enclosed in quotes and separated
+by white space.
+Case is ignored in arguments to the
+.B \-W
+option.
+.PP
+The
+.B \-W
+option accepts the following arguments:
+.TP \w'\fBcopyright\fR'u+1n
+.B compat
+Run in
+.I compatibility
+mode. In compatibility mode,
+.I gawk
+behaves identically to \*(UX
+.IR awk ;
+none of the GNU-specific extensions are recognized.
+.TP
+.PD 0
+.B copyleft
+.TP
+.PD
+.B copyright
+Print the short version of the GNU copyright information message on
+the error output.
+.TP
+.B lint
+Provide warnings about constructs that are
+dubious or non-portable to other AWK implementations.
+.TP
+.B posix
+This turns on
+.I compatibility
+mode, with the following additional restrictions:
+.RS
+.TP \w'\(bu'u+1n
+\(bu
+.B \ex
+escape sequences are not recognized.
+.TP
+\(bu
+The synonym
+.B func
+for the keyword
+.B function
+is not recognized.
+.TP
+\(bu
+The operators
+.B **
+and
+.B **=
+cannot be used in place of
+.B ^
+and
+.BR ^= .
+.RE
+.TP
+.B version
+Print version information for this particular copy of
+.I gawk
+on the error output.
+This is useful mainly for knowing if the current copy of
+.I gawk
+on your system
+is up to date with respect to whatever the Free Software Foundation
+is distributing.
+.PP
+Any other options are flagged as illegal, but are otherwise ignored.
+.SH AWK PROGRAM EXECUTION
+.PP
+An AWK program consists of a sequence of pattern-action statements
+and optional function definitions.
+.RS
+.PP
+\fIpattern\fB { \fIaction statements\fB }\fR
+.br
+\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements\fB }\fR
+.RE
+.PP
+.I Gawk
+first reads the program source from the
+.IR program-file (s)
+if specified, or from the first non-option argument on the command line.
+The
+.B \-f
+option may be used multiple times on the command line.
+.I Gawk
+will read the program text as if all the
+.IR program-file s
+had been concatenated together. This is useful for building libraries
+of AWK functions, without having to include them in each new AWK
--- /dev/null
+20 long words
+compatibility
+concatenated
+consistency
+definitions
+description
+distributing
+fistatements
+gawk-options
+gnu-specific
+identically
+implementation
+implementations
+information
+non-portable
+pattern-action
+pre-defined
+program-file
+program-text
+programming
+restrictions
--- /dev/null
+# From beebe@sunshine.math.utah.edu Thu Jul 10 00:36:16 2003
+# Date: Wed, 9 Jul 2003 06:42:54 -0600 (MDT)
+# From: "Nelson H. F. Beebe" <beebe@math.utah.edu>
+# To: "Arnold Robbins" <arnold@skeeve.com>
+# Cc: beebe@math.utah.edu
+# X-US-Mail: "Center for Scientific Computing, Department of Mathematics, 110
+# LCB, University of Utah, 155 S 1400 E RM 233, Salt Lake City, UT
+# 84112-0090, USA"
+# X-Telephone: +1 801 581 5254
+# X-FAX: +1 801 585 1640, +1 801 581 4148
+# X-URL: http://www.math.utah.edu/~beebe
+# Subject: gawk-3.1.3 (and earlier): reproducible core dump
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+#
+# I have a reproducible core dump in gawk-3.1.3, and recent gawk
+# versions.
+#
+# Consider the following test program, reduced from a much larger one:
+#
+# % cat gawk-dump.awk
+
+ { process($0) }
+
+ function out_debug(s)
+ {
+ print s
+ }
+
+ function process(s, n,parts)
+ {
+ out_debug("Buffer = [" protect(Buffer) "]")
+ Buffer = Buffer s
+ n = split(Buffer,parts,"\n")
+ }
+
+ function protect(s)
+ {
+ gsub("\n", "\\n", s)
+ return (s)
+ }
--- /dev/null
+Buffer = []
--- /dev/null
+{ print $2 > ("junk/" $1) }
--- /dev/null
+BEGIN {
+ data = "foooobazbarrrrr"
+ match(data, /(fo+).+(bar*)/, arr)
+ for (i = 0; i in arr; i++) {
+ printf("arr[%d] = \"%s\"\n", i, arr[i])
+ printf("arr[%d, \"start\"] = %s, arr[%d, \"length\"] = %s\n",
+ i, arr[i, "start"], i, arr[i, "length"])
+ }
+}
--- /dev/null
+arr[0] = "foooobazbarrrrr"
+arr[0, "start"] = 1, arr[0, "length"] = 15
+arr[1] = "foooo"
+arr[1, "start"] = 1, arr[1, "length"] = 5
+arr[2] = "barrrrr"
+arr[2, "start"] = 9, arr[2, "length"] = 7
--- /dev/null
+function f(a, b, c)
+{
+ print match("foo", "bar", f)
+}
+
+BEGIN { f(1, 2, 3) }
--- /dev/null
+gawk: match2.awk:3: fatal: match: third argument is not an array
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ pi = 3.1415927
+ printf "cos(%f) = %f\n", pi/4, cos(pi/4)
+ printf "sin(%f) = %f\n", pi/4, sin(pi/4)
+ e = exp(1)
+ printf "e = %f\n", e
+ printf "log(e) = %f\n", log(e)
+ printf "sqrt(pi ^ 2) = %f\n", sqrt(pi ^ 2)
+ printf "atan2(1, 1) = %f\n", atan2(1, 1)
+}
--- /dev/null
+cos(0.785398) = 0.707107
+sin(0.785398) = 0.707107
+e = 2.718282
+log(e) = 1.000000
+sqrt(pi ^ 2) = 3.141593
+atan2(1, 1) = 0.785398
--- /dev/null
+{ one != one = $1 }
--- /dev/null
+# This is a demo of different ways of printing with gawk. Try it
+# with and without -c (compatibility) flag, redirecting output
+# from gawk to a file or not. Some results can be quite unexpected.
+BEGIN {
+ print "Goes to a file out1" > "out1"
+ print "Normal print statement"
+ print "This printed on stdout" > "/dev/stdout"
+ print "You blew it!" > "/dev/stderr"
+}
--- /dev/null
+BEGIN { print-"6" }
--- /dev/null
+XXXXXXXX.com ALTERNET 9305 930528 1500.00 startup
+XXXXXXXX.com ALTERNET 9305 930624 94.38 Line-9305
+XXXXXXXX.com ALTERNET 9306 930624 104.49 Line-9306
+XXXXXXXX.com ALTERNET 9306 930624 649.16 Line-install
+XXXXXXXX.com ALTERNET 9306 930624 166.67 TCP-slip
+XXXXXXXX.com ALTERNET 9307 930624 104.49 Line-9307
+XXXXXXXX.com ALTERNET 9307 930624 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9308 930701 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9308 930701 104.49 line-9308
+XXXXXXXX.com PAYMENT 9307 930731 1500.00 1870
+XXXXXXXX.com ALTERNET 9309 930801 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9309 930801 104.49 line-9309
+XXXXXXXX.com INTEREST 9307 930801 22.50
+XXXXXXXX.com CREDADJ 9308 930805 22.50 waive interest
+XXXXXXXX.com PAYMENT 9308 930820 1723.68 1982
+XXXXXXXX.com ALTERNET 9310 930901 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9310 930901 104.49 line-9310
+XXXXXXXX.com PAYMENT 9310 931001 708.98 2313
+XXXXXXXX.com ALTERNET 9311 931001 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9311 931001 104.49 line-9311
+XXXXXXXX.com INTEREST 9309 931001 5.32
+XXXXXXXX.com CREDADJ 9310 931007 5.32 waive int-9309
+XXXXXXXX.com ALTERNET 9312 931101 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9312 931101 104.49 line-9312
+XXXXXXXX.com PAYMENT 9311 931120 354.49 002701
+XXXXXXXX.com ALTERNET 9401 931201 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9401 931201 104.49 line-9401
+XXXXXXXX.com PAYMENT 9312 931218 354.49 2884
+XXXXXXXX.com ALTERNET 9402 940101 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9402 940101 104.49 line-9402
+XXXXXXXX.com INTEREST 9312 940101 5.32
+XXXXXXXX.com PAYMENT 9401 940122 354.49 3084
+XXXXXXXX.com ALTERNET 9403 940201 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9403 940201 104.49 line-9403
+XXXXXXXX.com INTEREST 9401 940201 5.40
+XXXXXXXX.com PAYMENT 9402 940207 354.49 3140
+XXXXXXXX.com CREDADJ 9402 940211 5.32 interest-9402
+XXXXXXXX.com CREDADJ 9402 940211 5.40 interest-9403
+XXXXXXXX.com ALTERNET 9404 940301 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9404 940301 104.49 line-9404
+XXXXXXXX.com INTEREST 9402 940301 5.32
+XXXXXXXX.com PAYMENT 9403 940310 354.49 003307
+XXXXXXXX.com PAYMENT 9403 940324 354.49 3446
+XXXXXXXX.com ALTERNET 9405 940401 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9405 940401 104.49 line-9405
+XXXXXXXX.com ALTERNET 9406 940501 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9406 940501 104.49 line-9406
+XXXXXXXX.com INTEREST 9404 940501 5.40
+XXXXXXXX.com PAYMENT 9405 940509 359.81 003819
+XXXXXXXX.com ALTERNET 9407 940601 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9407 940601 104.49 line-9407
+XXXXXXXX.com INTEREST 9405 940601 5.40
+XXXXXXXX.com PAYMENT 9406 940603 354.49 004025
+XXXXXXXX.com ALTERNET 9408 940701 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9408 940701 104.49 line-9408
+XXXXXXXX.com INTEREST 9406 940701 5.48
+XXXXXXXX.com PAYMENT 9407 940725 354.49 004350
+XXXXXXXX.com ALTERNET 9409 940801 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9409 940801 104.49 line-9409
+XXXXXXXX.com INTEREST 9407 940801 5.56
+XXXXXXXX.com PAYMENT 9408 940808 354.49 004454
+XXXXXXXX.com ALTERNET 9409 940811 0.00 startup
+XXXXXXXX.com EQUIPMENT 9408 940831 399.00 ATL6402-1
+XXXXXXXX.com EQUIPMENT 9408 940831 2295.00 NBClassicPac-1
+XXXXXXXX.com EQUIPMENT 9408 940831 1060.00 Syn35-1+ship
+XXXXXXXX.com ALTERNET 9410 940901 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9410 940901 104.49 line-9410
+XXXXXXXX.com INTEREST 9408 940901 5.64
+XXXXXXXX.com PAYMENT 9409 940906 354.49 004677
+XXXXXXXX.com CREDADJ 9409 940921 124.95 TCP-slip-9409
+XXXXXXXX.com CREDADJ 9409 940921 52.20 line-9409
+XXXXXXXX.com CREDADJ 9410 940921 250.00 TCP-slip-9410
+XXXXXXXX.com CREDADJ 9410 940921 104.49 line-9410
+XXXXXXXX.com ALTERNET 9409 940921 397.50 TCP-56k-local recon
+XXXXXXXX.com ALTERNET 9409 940921 87.45 line-9409 recon
+XXXXXXXX.com ALTERNET 9410 940921 795.00 TCP-56k-local recon
+XXXXXXXX.com ALTERNET 9410 940921 174.90 line-9410 recon
+XXXXXXXX.com ALTERNET 9411 941001 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9411 941001 174.90 line-9411
+XXXXXXXX.com INTEREST 9409 941001 54.06
+XXXXXXXX.com PAYMENT 9410 941017 354.49 5026
+XXXXXXXX.com ALTERNET 9412 941101 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9412 941101 174.90 line-9412
+XXXXXXXX.com INTEREST 9410 941101 85.93
+XXXXXXXX.com PAYMENT 9411 941114 969.90 005274
+XXXXXXXX.com ALTERNET 9501 941201 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9501 941201 174.90 line-9501
+XXXXXXXX.com INTEREST 9411 941201 87.22
+XXXXXXXX.com PAYMENT 9412 941219 4723.90 5590
+XXXXXXXX.com ALTERNET 9502 950101 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9502 950101 174.90 line-9502
+XXXXXXXX.com INTEREST 9412 950101 32.22
+XXXXXXXX.com PAYMENT 9501 950103 1893.11 5766
+XXXXXXXX.com ALTERNET 9503 950201 795.00 TCP-56k-local-old
+XXXXXXXX.com ALTERNET 9503 950201 174.90 line-9503
+XXXXXXXX.com INTEREST 9501 950201 18.85
+XXXXXXXX.com PAYMENT 9502 950207 969.90 6044
+XXXXXXXX.com ALTERNET 9504 950301 795.00 TCP-56k-local-old
+XXXXXXXX.com ALTERNET 9504 950301 174.90 line-9504
+XXXXXXXX.com INTEREST 9502 950301 19.13
+XXXXXXXX.com PAYMENT 9503 950307 969.90 6408
+XXXXXXXX.com ALTERNET 9504 950316 3000.00 startup TCP-bt1-128k%5
+XXXXXXXX.com PAYMENT 9503 950327 969.90 6594
+XXXXXXXX.com ALTERNET 9505 950401 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9505 950401 556.60 line-9505
+XXXXXXXX.com EQUIPMENT 9504 950410 1595.00 cisco2501-1
+XXXXXXXX.com CREDADJ 9504 950417 503.50 TCP-56k-local
+XXXXXXXX.com CREDADJ 9504 950417 116.60 line-9504
+XXXXXXXX.com ALTERNET 9504 950417 448.80 line-install
+XXXXXXXX.com ALTERNET 9504 950417 752.02 TCP-bt1-128k%5 recon
+XXXXXXXX.com ALTERNET 9504 950417 371.00 line-9504 recon
+XXXXXXXX.com PAYMENT 9504 950424 3000.00 6841
+XXXXXXXX.com ALTERNET 9506 950501 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9506 950501 556.60 line-9506
+XXXXXXXX.com PAYMENT 9505 950505 2049.86 6985
+XXXXXXXX.com PAYMENT 9505 950531 3924.22 7179
+XXXXXXXX.com ALTERNET 9507 950601 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9507 950601 556.60 line-9507
+XXXXXXXX.com PAYMENT 9506 950607 1744.10 7232
+XXXXXXXX.com ALTERNET 9508 950701 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9508 950701 556.60 line-9508
+XXXXXXXX.com PAYMENT 9507 950705 1744.10 7641
+XXXXXXXX.com ALTERNET 9509 950801 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9509 950801 556.60 line-9509
+XXXXXXXX.com PAYMENT 9508 950803 1744.10 7914
+XXXXXXXX.com ALTERNET 9510 950901 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9510 950901 556.60 line-9510
+XXXXXXXX.com PAYMENT 9509 950905 1744.10 8203
+XXXXXXXX.com ALTERNET 9511 951001 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9511 951001 556.60 line-9511
+XXXXXXXX.com PAYMENT 9510 951003 1744.10 8508
+XXXXXXXX.com ALTERNET 9512 951101 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9512 951101 556.60 line-9512
+XXXXXXXX.com PAYMENT 9511 951103 2129.83 8837
+XXXXXXXX.com ALTERNET 9601 951201 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9601 951201 556.60 line-9601
+XXXXXXXX.com PAYMENT 9512 951204 2129.83 9131
+XXXXXXXX.com ALTERNET 9602 960101 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9602 960101 556.60 line-9602
+XXXXXXXX.com PAYMENT 9601 960103 1744.10 9456
+XXXXXXXX.com ALTERNET 9603 960201 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9603 960201 556.60 line-9603
+XXXXXXXX.com PAYMENT 9602 960205 1358.37 9834
--- /dev/null
+#From hankedr@manatee.dms.auburn.edu Tue Oct 13 22:15:59 1998
+#Return-Path: <hankedr@manatee.dms.auburn.edu>
+#Received: from cssun.mathcs.emory.edu (cssun.mathcs.emory.edu [170.140.150.1])
+# by dmx.netvision.net.il (8.9.0.Beta5/8.8.6) with ESMTP id PAA03924
+# for <arobbins@netvision.net.il>; Tue, 13 Oct 1998 15:32:13 +0200 (IST)
+#Received: from mescaline.gnu.org (we-refuse-to-spy-on-our-users@mescaline.gnu.org [158.121.106.21]) by cssun.mathcs.emory.edu (8.7.5/8.6.9-940818.01cssun) with ESMTP id KAA11644 for <arnold@mathcs.emory.edu>; Tue, 13 Oct 1998 10:22:32 -0400 (EDT)
+#Received: from manatee.dms.auburn.edu (manatee.dms.auburn.edu [131.204.53.104])
+# by mescaline.gnu.org (8.9.1a/8.9.1) with ESMTP id KAA03250
+# for <arnold@gnu.org>; Tue, 13 Oct 1998 10:25:32 -0400
+#Received: (from hankedr@localhost)
+# by manatee.dms.auburn.edu (8.9.1a/8.9.1) id JAA13348;
+# Tue, 13 Oct 1998 09:22:29 -0500 (CDT)
+#Date: Tue, 13 Oct 1998 09:22:29 -0500 (CDT)
+#Message-Id: <199810131422.JAA13348@manatee.dms.auburn.edu>
+#From: Darrel Hankerson <hankedr@dms.auburn.edu>
+#To: arnold@gnu.org
+#In-reply-to: <199810131313.QAA31784@alpha.netvision.net.il> (message from
+# Aharon Robbins on Tue, 13 Oct 1998 16:10:36 +0200)
+#Subject: Re: full text of bug report?
+#Mime-Version: 1.0
+#Content-Type: text/plain; charset=US-ASCII
+#X-UIDL: bf3fce492dad4ab030c561e7b2f27d0a
+#Status: RO
+#
+# Do you have the full text of the a = a "\n" f() bug report?
+# I can't find it.... I'm not sure there really is a bug.
+#
+#Yes, see below.
+#
+#His example has unnecessary fragments (in particular, the use of
+#gensub is irrelevant). As I wrote to you earlier, the interesting
+#question for me is:
+#
+# Is the concatenation result undefined? If the result is defined or
+# implementation-dependent, then gawk has a bug.
+#
+#
+#=== Original report =====================================================
+#From: Attila Torcsvari <arcdev@mail.matav.hu>
+#To: "'bug-gnu-utils@prep.ai.mit.edu'" <bug-gnu-utils@gnu.org>
+#Subject: gawk 3.0.3 bug
+#Date: Thu, 17 Sep 1998 18:12:13 +0200
+#MIME-Version: 1.0
+#Content-Transfer-Encoding: 7bit
+#Resent-From: bug-gnu-utils@gnu.org
+#X-Mailing-List: <bug-gnu-utils@gnu.org> archive/latest/3396
+#X-Loop: bug-gnu-utils@gnu.org
+#Precedence: list
+#Resent-Sender: bug-gnu-utils-request@gnu.org
+#Content-Transfer-Encoding: 7bit
+#Content-Type: text/plain; charset="us-ascii"
+#Content-Length: 618
+#
+#Bug-gnuers,
+#please pass it to the responsible.
+#
+#The following generates something interesting:
+#
+BEGIN{
+a="aaaaa"
+a=a a #10
+a=a a #20
+a=a a #40
+a=a a #80
+a=a a #160
+a=a a # i.e. a is long enough
+
+a=a"\n"f() # this causes the trouble
+print a # guess the result
+}
+
+function f()
+{
+#print "a before: ", a
+#a=gensub("a","123,","g",a) # 'a' will be just a bit longer (4 times, but still should fit: 4*160=640)
+gsub(/a/, "123", a)
+#print "a after: ", a
+return "X"
+}
+#
+#Possible reason:
+#during f the a is modified,
+#it can be even freed, because gensub modifies its size
+#the printout contains trash.
+#
+#Used version: VC compiled WinNT 32 bit Intel.
+#
+#Regards,
+#
+#Attila Torcsvari
+#Arcanum Development
+#
--- /dev/null
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X
--- /dev/null
+# Based on nasty.awk, test same thing for printf
+#
+BEGIN {
+a="aaaaa"
+a=a a #10
+a=a a #20
+a=a a #40
+a=a a #80
+a=a a #160
+a=a a # i.e. a is long enough
+
+printf("a = %s, f() = %s\n", a, f())
+print a
+}
+
+function f()
+{
+gsub(/a/, "123", a)
+return "X"
+}
--- /dev/null
+a = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, f() = X
+123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123
--- /dev/null
+BEGIN { a = -2; print 10^a }
--- /dev/null
+# From james@ruari-quinn.demon.co.uk Thu Jun 5 11:43:58 2003
+# Return-Path: <james@ruari-quinn.demon.co.uk>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h558eVui012655
+# for <arnold@localhost>; Thu, 5 Jun 2003 11:43:58 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Thu, 05 Jun 2003 11:43:58 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Thu Jun 5 11:43:29 2003)
+# X-From_: james@ruari-quinn.demon.co.uk Wed Jun 4 20:09:54 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h54H9oY05088 for <arobbins@actcom.co.il>;
+# Wed, 4 Jun 2003 20:09:52 +0300 (EET DST)
+# (rfc931-sender: smtp.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h54HB8To002721
+# for <arobbins@actcom.co.il>; Wed, 4 Jun 2003 20:11:09 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7/8.11.6) with ESMTP id h54H9li15411
+# for <arnold@skeeve.com>; Wed, 4 Jun 2003 13:09:47 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.20)
+# id 19Nbli-0001kD-BL
+# for bug-gawk@gnu.org; Wed, 04 Jun 2003 13:09:46 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20)
+# id 19NbZ5-0004V2-71
+# for bug-gawk@gnu.org; Wed, 04 Jun 2003 12:56:43 -0400
+# Received: from cicero.e-mis.co.uk ([212.240.194.162])
+# by monty-python.gnu.org with esmtp (Exim 4.20)
+# id 19NbYK-0003c7-AP
+# for bug-gawk@gnu.org; Wed, 04 Jun 2003 12:55:56 -0400
+# Received: from [10.139.58.254] (helo=tacitus)
+# by cicero.e-mis.co.uk with esmtp (Exim 3.35 #1 (Debian))
+# id 19NbWO-0007Qv-00
+# for <bug-gawk@gnu.org>; Wed, 04 Jun 2003 17:53:56 +0100
+# Received: from james by tacitus with local (Exim 3.36 #1 (Debian))
+# id 19NbWO-0000cK-00
+# for <bug-gawk@gnu.org>; Wed, 04 Jun 2003 17:53:56 +0100
+# To: bug-gawk@gnu.org
+# Subject: 3.1.0 regression
+# Mail-Copies-To: never
+# From: James Troup <james@nocrew.org>
+# User-Agent: Gnus/5.090017 (Oort Gnus v0.17) Emacs/20.7 (gnu/linux)
+# Date: Wed, 04 Jun 2003 17:53:56 +0100
+# Message-ID: <874r35wzq3.fsf@nocrew.org>
+# MIME-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Sender: James Troup <james@ruari-quinn.demon.co.uk>
+# X-Spam-Status: No, hits=-3.9 required=5.0
+# tests=EMAIL_ATTRIBUTION,SIGNATURE_SHORT_DENSE,SPAM_PHRASE_00_01,
+# USER_AGENT
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: R
+#
+# Hi Aharon,
+#
+# This bug report comes from the Debian bug tracking system. You can
+# view the full log at:
+#
+# http://bugs.debian.org/188345
+#
+# Like my other bug, this is a regression from 3.1.0 and I've reproduced
+# this problem with 3.1.2d.
+#
+# "Nikita V. Youshchenko" <yoush@cs.msu.su> writes:
+#
+# | Package: gawk
+# | Version: 1:3.1.2-2
+# | Severity: normal
+# | Tags: sid
+# |
+# | After upgrading gawk from woody to sid, I found one of my scripts not
+# | working. I explored this a little and found minimal script to reproduce
+# | the problem.
+# |
+# | File bug.awk is the following:
+# |
+BEGIN {
+ WI_total = 0
+}
+{
+ WI_total++
+ {
+ split ( $1, sws, "_" )
+ a = sws[1]
+ }
+ print(sws[1])
+ print(a)
+}
+# |
+# | The second print should output the same what first print poutputs, but
+# | with gawk 3.1.2-2 it outputs nothing:
+# | > echo a_b | gawk -f bug.awk
+# | a
+# |
+# | >
+# |
+# | With gawk from stable I get what expexted:
+# | > echo a_b | gawk -f bug.awk
+# | a
+# | a
+# | >
+# |
+# | If I remove "WI_total++" line, bug disapperas
+# |
+# | -- System Information:
+# | Debian Release: 3.0
+# | Architecture: i386
+# | Kernel: Linux zigzag 2.4.19 16:49:13 MSK 2003 i686
+# | Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R
+# |
+# | Versions of packages gawk depends on:
+# | ii libc6 2.3.1-16 GNU C Library: Shared libraries an
+# |
+# | -- no debconf information
+#
+# --
+# James
+#
--- /dev/null
+$1 == 0 {
+ print "bug"
+}
+{
+ $0 = "0"
+ if (!$0)
+ print "another bug"
+ $0 = a = "0"
+ if (!$0)
+ print "yet another bug"
+ if ($1)
+ print "a buggie"
+}
--- /dev/null
+BEGIN { NF -= 2 ; print }
--- /dev/null
+gawk: nfneg.awk:1: fatal: NF set to negative value
+EXIT CODE: 2
--- /dev/null
+{ NF = 5 ; print }
--- /dev/null
+1 2
+1 2 3 4
+1 2 3 4 5
+1 2 3 4 5 6 7 8
+1
--- /dev/null
+1 2
+1 2 3 4
+1 2 3 4 5
+1 2 3 4 5
+1
--- /dev/null
+BEGIN { RS = "A" }
+{print NF; for (i = 1; i <= NF; i++) print $i ; print ""}
--- /dev/null
+some stuff
+more stuffA
+junk
+stuffA
+final
--- /dev/null
+4
+some
+stuff
+more
+stuff
+
+2
+junk
+stuff
+
+1
+final
+
--- /dev/null
+BEGIN { RS = "" }
+
+{
+ if (/^@/)
+ print "not ok"
+ else
+ print "ok"
+}
--- /dev/null
+line 1
+@line 2
--- /dev/null
+# From E.Ab@chem.rug.nl Wed Aug 2 13:16:53 2000
+# Received: from mail.actcom.co.il
+# by localhost with POP3 (fetchmail-5.1.2)
+# for arnold@localhost (single-drop); Wed, 02 Aug 2000 13:16:53 -0400 (EDT)
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id MAA21699 for <arobbins@actcom.co.il>;
+# Wed, 2 Aug 2000 12:20:38 +0300 (EET DST)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from freefriends.org (freefriends.org [63.85.55.109])
+# by lmail.actcom.co.il (8.9.3/8.9.1) with ESMTP id LAA22723
+# for <arobbins@actcom.co.il>; Wed, 2 Aug 2000 11:23:22 +0300
+# Received: from mescaline.gnu.org (mescaline.gnu.org [158.121.106.21])
+# by freefriends.org (8.9.3/8.9.3) with ESMTP id FAA23582
+# for <arnold@skeeve.com>; Wed, 2 Aug 2000 05:18:59 -0400
+# Received: from dep.chem.rug.nl (dep.chem.rug.nl [129.125.7.81])
+# by mescaline.gnu.org (8.9.1a/8.9.1) with ESMTP id FAA30670;
+# Wed, 2 Aug 2000 05:20:24 -0400
+# Received: from rugmd34.chem.rug.nl (rugmd34.chem.rug.nl [129.125.42.34])
+# by dep.chem.rug.nl (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id LAA17089;
+# Wed, 2 Aug 2000 11:20:23 +0200
+# Received: from chem.rug.nl (localhost [127.0.0.1]) by rugmd34.chem.rug.nl (980427.SGI.8.8.8/980728.SGI.AUTOCF) via ESMTP id LAA25392; Wed, 2 Aug 2000 11:20:22 +0200 (MDT)
+# Sender: E.Ab@chem.rug.nl
+# Message-ID: <3987E7D5.2BDC5FD3@chem.rug.nl>
+# Date: Wed, 02 Aug 2000 11:20:21 +0200
+# From: Eiso AB <E.Ab@chem.rug.nl>
+# X-Mailer: Mozilla 4.72C-SGI [en] (X11; I; IRIX 6.5 IP32)
+# X-Accept-Language: en
+# MIME-Version: 1.0
+# To: bug-gnu-utils@gnu.org, arnold@gnu.org
+# Subject: bug? [GNU Awk 3.0.5]
+#
+# Content-Type: text/plain; charset=us-ascii
+# Content-Transfer-Encoding: 7bit
+# X-UIDL: \f8"!(8G!!ZL$#!h>X!!
+# Status: R
+#
+# hi Arnold,
+#
+#
+# Please try the script beneath...
+# I'm not sure if this is a bug or not, but I would expect
+# the empty string as an array index just to be treated
+# like any other string
+#
+# so if ("" in ta) would be true, and for ( i in ta ) should loop only once.
+#
+BEGIN {
+ v=""
+ ta[v]++
+ if ( v in ta) print "a",v,++ta[v],ta[v]
+ print "b",v,++ta[v],ta[v]
+ for( i in ta) print "c",++c,i,ta[i]
+}
+#
+# goodluck, Eiso
+#
+# --
+# _________
+# _______________________________/ Eiso AB \_________________________
+#
+# o
+#
+# o Dept. of Biochemistry
+# University of Groningen
+# The Netherlands
+# o
+# . .
+# o ^ mailto:eiso@chem.rug.nl
+# | - _ mailto:eiso@dds.nl
+# \__|__/ http://md.chem.rug.nl/~eiso
+# | tel 4326
+# |
+# / \
+# / \
+# | |
+# ________ ._| |_. ________________________________________________
+#
--- /dev/null
+a 2 2
+b 3 3
+c 1 3
--- /dev/null
+BEGIN {
+ s == "hello, world";
+ s + 1
+ ;;
+}
--- /dev/null
+gawk: noeffect.awk:3: warning: statement may have no effect
+gawk: noeffect.awk:4: warning: statement may have no effect
+gawk: noeffect.awk:2: warning: reference to uninitialized variable `s'
+gawk: noeffect.awk:3: warning: reference to uninitialized variable `s'
--- /dev/null
+BEGIN { printf "%3\n" }
--- /dev/null
+gawk: nofmtch.awk:1: warning: [s]printf: format specifier does not have control letter
+%3
--- /dev/null
+# From jhart@avcnet.bates.edu Sun Oct 6 16:05:21 2002
+# Return-Path: <jhart@avcnet.bates.edu>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.11.6/8.11.6) with ESMTP id g96D5Jf28053
+# for <arnold@localhost>; Sun, 6 Oct 2002 16:05:21 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Sun, 06 Oct 2002 16:05:21 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Sun Oct 6 16:06:39 2002)
+# X-From_: jhart@avcnet.bates.edu Sun Oct 6 15:31:59 2002
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id g96CVrS27315 for <arobbins@actcom.co.il>;
+# Sun, 6 Oct 2002 15:31:54 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by lmail.actcom.co.il (8.11.6/8.11.6) with ESMTP id g96CVqY01629
+# for <arobbins@actcom.co.il>; Sun, 6 Oct 2002 15:31:52 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.6/8.11.6) with ESMTP id g96CVp418974
+# for <arnold@skeeve.com>; Sun, 6 Oct 2002 08:31:51 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.10)
+# id 17yAZa-00055o-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:50 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10)
+# id 17yAZE-0007eB-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:29 -0400
+# Received: from avcnet.bates.edu ([134.181.128.62])
+# by monty-python.gnu.org with esmtp (Exim 4.10)
+# id 17yAZ9-0007X3-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:23 -0400
+# Received: from a5514a.bates.edu (www.bates.edu [134.181.128.62])
+# by avcnet.bates.edu (8.9.3/8.9.3) with ESMTP id IAA05400
+# for <bug-gawk@gnu.org>; Sun, 6 Oct 2002 08:31:20 -0400
+# Date: Sun, 6 Oct 2002 08:36:54 -0400
+# Mime-Version: 1.0 (Apple Message framework v482)
+# Content-Type: text/plain; charset=US-ASCII; format=flowed
+# Subject: Infinite loop in sub/gsub
+# From: jhart@avcnet.bates.edu
+# To: bug-gawk@gnu.org
+# Content-Transfer-Encoding: 7bit
+# Message-Id: <4BC4A4F0-D928-11D6-8E78-00039384A9CC@mail.avcnet.org>
+# X-Mailer: Apple Mail (2.482)
+# X-Spam-Status: No, hits=0.3 required=5.0
+# tests=NO_REAL_NAME,SPAM_PHRASE_00_01,USER_AGENT_APPLEMAIL
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# This command line:
+#
+# echo "''Italics with an apostrophe'' embedded''"|gawk -f test.awk
+#
+# where test.awk contains this instruction:
+#
+/''/ { sub(/''(.?[^']+)*''/, "<em>&</em>"); }
+#
+# puts gawk 3.11 into an infinite loop. Whereas, this command works:
+#
+# echo "''Italics with an apostrophe' embedded''"|gawk -f test.awk
+#
+#
+#
+# Platform: Mac OS X 10.1.5/Darwin Kernel Version 5.5: Thu May 30 14:51:26
+# PDT 2002; root:xnu/xnu-201.42.3.obj~1/RELEASE_PPC
+#
+#
--- /dev/null
+''Italics with an apostrophe'' embedded''
--- /dev/null
+# From jhart@avcnet.bates.edu Sun Oct 6 16:05:21 2002
+# Return-Path: <jhart@avcnet.bates.edu>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.11.6/8.11.6) with ESMTP id g96D5Jf28053
+# for <arnold@localhost>; Sun, 6 Oct 2002 16:05:21 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Sun, 06 Oct 2002 16:05:21 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Sun Oct 6 16:06:39 2002)
+# X-From_: jhart@avcnet.bates.edu Sun Oct 6 15:31:59 2002
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id g96CVrS27315 for <arobbins@actcom.co.il>;
+# Sun, 6 Oct 2002 15:31:54 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by lmail.actcom.co.il (8.11.6/8.11.6) with ESMTP id g96CVqY01629
+# for <arobbins@actcom.co.il>; Sun, 6 Oct 2002 15:31:52 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.6/8.11.6) with ESMTP id g96CVp418974
+# for <arnold@skeeve.com>; Sun, 6 Oct 2002 08:31:51 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.10)
+# id 17yAZa-00055o-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:50 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10)
+# id 17yAZE-0007eB-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:29 -0400
+# Received: from avcnet.bates.edu ([134.181.128.62])
+# by monty-python.gnu.org with esmtp (Exim 4.10)
+# id 17yAZ9-0007X3-00
+# for bug-gawk@gnu.org; Sun, 06 Oct 2002 08:31:23 -0400
+# Received: from a5514a.bates.edu (www.bates.edu [134.181.128.62])
+# by avcnet.bates.edu (8.9.3/8.9.3) with ESMTP id IAA05400
+# for <bug-gawk@gnu.org>; Sun, 6 Oct 2002 08:31:20 -0400
+# Date: Sun, 6 Oct 2002 08:36:54 -0400
+# Mime-Version: 1.0 (Apple Message framework v482)
+# Content-Type: text/plain; charset=US-ASCII; format=flowed
+# Subject: Infinite loop in sub/gsub
+# From: jhart@avcnet.bates.edu
+# To: bug-gawk@gnu.org
+# Content-Transfer-Encoding: 7bit
+# Message-Id: <4BC4A4F0-D928-11D6-8E78-00039384A9CC@mail.avcnet.org>
+# X-Mailer: Apple Mail (2.482)
+# X-Spam-Status: No, hits=0.3 required=5.0
+# tests=NO_REAL_NAME,SPAM_PHRASE_00_01,USER_AGENT_APPLEMAIL
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# This command line:
+#
+# echo "''Italics with an apostrophe'' embedded''"|gawk -f test.awk
+#
+# where test.awk contains this instruction:
+#
+/''/ { sub(/''(.?[^']+)*''/, "<em>&</em>"); }
+#
+# puts gawk 3.11 into an infinite loop. Whereas, this command works:
+#
+# echo "''Italics with an apostrophe' embedded''"|gawk -f test.awk
+#
+#
+#
+# Platform: Mac OS X 10.1.5/Darwin Kernel Version 5.5: Thu May 30 14:51:26
+# PDT 2002; root:xnu/xnu-201.42.3.obj~1/RELEASE_PPC
+#
+#
--- /dev/null
+''Italics with an apostrophe' embedded''
--- /dev/null
+BEGIN { print 0x81c3e8, 0x744018, 00.34 }
--- /dev/null
+8504296 7618584 0.34
--- /dev/null
+# From arnold@f7.net Wed Jun 15 08:25:21 2005
+# Return-Path: <arnold@f7.net>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.11/8.12.11) with ESMTP id j5F5P3VC014658
+# for <arnold@localhost>; Wed, 15 Jun 2005 08:25:21 +0300
+# Received: from pop.012.net.il [84.95.5.221]
+# by localhost with POP3 (fetchmail-6.2.5)
+# for arnold@localhost (single-drop); Wed, 15 Jun 2005 08:25:21 +0300 (IDT)
+# Received: from mtain2.012.net.il ([10.220.5.4])
+# by i_mss3.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0II300LQOPS7DA10@i_mss3.012.net.il> for arobbins@012.net.il;
+# Wed, 15 Jun 2005 04:07:19 +0300 (IDT)
+# Received: from VSCAN1 ([10.220.20.1])
+# by i_mtain2.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0II300ETQPS7IEZ4@i_mtain2.012.net.il> for arobbins@012.net.il
+# (ORCPT arobbins@012.net.il); Wed, 15 Jun 2005 04:07:19 +0300 (IDT)
+# Received: from i_mtain2.012.net.il ([10.220.5.4])
+# by VSCAN1 with InterScan Messaging Security Suite; Wed,
+# 15 Jun 2005 04:03:15 +0300
+# Received: from f7.net ([209.61.216.22])
+# by i_mtain2.012.net.il (HyperSendmail v2004.12)
+# with ESMTP id <0II300H7VPS5P1O2@i_mtain2.012.net.il> for arobbins@012.net.il;
+# Wed, 15 Jun 2005 04:07:18 +0300 (IDT)
+# Received: (from arnold@localhost) by f7.net (8.11.7-20030920/8.11.7)
+# id j5F13DT21530 for arobbins@012.net.il; Tue, 14 Jun 2005 21:03:14 -0400
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7-20030920/8.11.7) with ESMTP id j5F136p21454 for
+# <arnold@skeeve.com>; Tue, 14 Jun 2005 21:03:06 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.34)
+# id 1DiMJ6-0002fe-Av for bug-gawk@gnu.org; Tue, 14 Jun 2005 21:03:04 -0400
+# Received: from Debian-exim by monty-python.gnu.org with spam-scanned
+# (Exim 4.34) id 1DiMIp-0003lM-I4 for bug-gawk@gnu.org; Tue,
+# 14 Jun 2005 21:02:47 -0400
+# Received: from [66.187.233.31] (helo=mx1.redhat.com)
+# by monty-python.gnu.org with esmtp (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24)
+# (Exim 4.34) id 1DiMIp-0003l4-8g for bug-gawk@gnu.org; Tue,
+# 14 Jun 2005 21:02:47 -0400
+# Received: from int-mx1.corp.redhat.com
+# (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.11)
+# with ESMTP id j5F11EGn027669 for <bug-gawk@gnu.org>; Tue,
+# 14 Jun 2005 21:01:14 -0400
+# Received: from lacrosse.corp.redhat.com
+# (lacrosse.corp.redhat.com [172.16.52.154]) by int-mx1.corp.redhat.com
+# (8.11.6/8.11.6) with ESMTP id j5F11Eu01536 for <bug-gawk@gnu.org>; Tue,
+# 14 Jun 2005 21:01:14 -0400
+# Received: from [192.168.7.71] (vpn50-10.rdu.redhat.com [172.16.50.10])
+# by lacrosse.corp.redhat.com (8.11.6/8.11.6) with ESMTP id j5F118s03225 for
+# <bug-gawk@gnu.org>; Tue, 14 Jun 2005 21:01:09 -0400
+# Date: Tue, 14 Jun 2005 17:57:55 -0700
+# From: Ulrich Drepper <drepper@redhat.com>
+# Subject: non-decimal variable parameters cause crashes
+# To: bug-gawk@gnu.org
+# Message-id: <42AF7D13.5010901@redhat.com>
+# Organization: Red Hat, Inc.
+# MIME-version: 1.0
+# Content-type: multipart/signed; micalg=pgp-sha1;
+# protocol="application/pgp-signature";
+# boundary=------------enig9DEC74140126C224E7DE3E54
+# X-Accept-Language: en-us, en
+# X-Enigmail-Version: 0.91.0.0
+# User-Agent: Mozilla Thunderbird 1.0.2-6 (X11/20050513)
+# Original-recipient: rfc822;arobbins@012.net.il
+# X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on skeeve.com
+# X-Spam-Level:
+# X-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL,BAYES_00 autolearn=ham
+# version=2.63
+# Status: R
+#
+# This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
+# --------------enig9DEC74140126C224E7DE3E54
+# Content-Type: text/plain; charset=UTF-8
+# Content-Transfer-Encoding: quoted-printable
+#
+# Running
+#
+# gawk --non-decimal-data -v a=3D0x1 'BEGIN { print a+0 }'
+#
+# currently crashes. More details including a patch at
+#
+# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=3D160421
+#
+# --=20
+# =E2=9E=A7 Ulrich Drepper =E2=9E=A7 Red Hat, Inc. =E2=9E=A7 444 Castro St =
+# =E2=9E=A7 Mountain View, CA =E2=9D=96
+#
+#
+# --------------enig9DEC74140126C224E7DE3E54
+# Content-Type: application/pgp-signature; name="signature.asc"
+# Content-Description: OpenPGP digital signature
+# Content-Disposition: attachment; filename="signature.asc"
+#
+# -----BEGIN PGP SIGNATURE-----
+# Version: GnuPG v1.4.1 (GNU/Linux)
+# Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
+#
+# iD8DBQFCr30T2ijCOnn/RHQRAp9LAKC+w/vhXW73ps1Pxcy+VGPrT1Su+ACguPnV
+# VstZcFJgJ5GZ1YvDExsOZZI=
+# =xmXh
+# -----END PGP SIGNATURE-----
+#
+# --------------enig9DEC74140126C224E7DE3E54--
+#
+BEGIN { print a+0 }
--- /dev/null
+0
\ No newline at end of file
--- /dev/null
+gawk: nonl.awk:1: warning: source file does not end in newline
--- /dev/null
+function x(a, b, c , ,) {}
--- /dev/null
+gawk: noparms.awk:1: function x(a, b, c , ,) {}
+gawk: noparms.awk:1: ^ syntax error
+gawk: noparms.awk:1: function x(a, b, c , ,) {}
+gawk: noparms.awk:1: ^ syntax error
+EXIT CODE: 1
--- /dev/null
+A B C D E
\ No newline at end of file
--- /dev/null
+# From murata@nips.ac.jp Tue Aug 6 08:02:14 2002
+# Return-Path: <murata@nips.ac.jp>
+# Received: from localhost (aahz [127.0.0.1])
+# by skeeve.com (8.11.2/8.11.2) with ESMTP id g7652Ej01784
+# for <arnold@localhost>; Tue, 6 Aug 2002 08:02:14 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.7.4)
+# for arnold@localhost (single-drop); Mon, 05 Aug 2002 22:02:14 -0700 (PDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Tue Aug 6 08:13:06 2002)
+# X-From_: murata@nips.ac.jp Tue Aug 6 07:26:32 2002
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id g764QTu27770 for <arobbins@actcom.co.il>;
+# Tue, 6 Aug 2002 07:26:30 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by lmail.actcom.co.il (8.11.6/8.11.6) with ESMTP id g764QRi04673
+# for <arobbins@actcom.co.il>; Tue, 6 Aug 2002 07:26:28 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.6/8.11.6) with ESMTP id g764QQ920486
+# for <arnold@skeeve.com>; Tue, 6 Aug 2002 00:26:26 -0400
+# Received: from ccms.nips.ac.jp ([133.48.72.2])
+# by fencepost.gnu.org with smtp (Exim 3.35 #1 (Debian))
+# id 17bvvL-00011b-00
+# for <bug-gawk@gnu.org>; Tue, 06 Aug 2002 00:26:23 -0400
+# Received: (from murata@localhost)
+# by ccms.nips.ac.jp (8.9.3+3.2W/3.7W) id NAA01026;
+# Tue, 6 Aug 2002 13:26:21 +0900
+# Date: Tue, 6 Aug 2002 13:26:21 +0900
+# Message-Id: <200208060426.NAA01026@ccms.nips.ac.jp>
+# To: bug-gawk@gnu.org
+# Cc: murata@nips.ac.jp
+# Subject: Bug Report (gawk)
+# From: murata@nips.ac.jp (MURATA Yasuhisa)
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=US-ASCII
+# X-Mailer: mnews [version 1.21PL5] 1999-04/04(Sun)
+#
+# Hello, I report a bug.
+#
+#
+# == PROGRAM (filename: atest.awk) ==
+BEGIN {
+ RS=""
+}
+
+NR==1 {
+ print 1
+ RS="\n"
+ next
+}
+
+NR==2 {
+ print 2
+ RS=""
+ next
+}
+
+NR==3 {
+ print 3
+ RS="\n"
+ next
+}
+# ====
+#
+# == DATA (filename: atest.txt) ==
+# 1111
+#
+# 2222
+#
+# ====
+# note: last line is "\n".
+#
+#
+# == RUN (gawk) ==
+# > gawk -f atest.awk atest.txt
+# 1
+# 2
+# (no stop!)
+# ====
+#
+# == RUN (nawk) ==
+# > nawk -f atest.awk atest.txt
+# 1
+# 2
+# 3
+# ====
+#
+# == VERSION ==
+# > gawk --version
+# GNU Awk 3.1.1
+# Copyright (C) 1989, 1991-2002 Free Software Foundation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# ==
+#
+# --
+# MURATA Yasuhisa, Technical Staff
+# National Institute for Physiological Sciences
+# E-mail: murata@nips.ac.jp
--- /dev/null
+1111
+
+2222
+
--- /dev/null
+#To: bug-gnu-utils@gnu.org
+#cc: arnold@gnu.org
+#Subject: Possible bug in GNU Awk 3.0.4
+#Date: Wed, 24 Nov 1999 21:47:24 +0000
+#From: Daniel Elphick <de397@ecs.soton.ac.uk>
+#Message-Id: <E11qkG4-0000l0-00@cameron>
+#
+#This is a multipart MIME message.
+#
+#--==_Exmh_-11192982200
+#Content-Type: text/plain; charset=us-ascii
+#
+#
+#When I use the attached awk script unique on the attached data file, it
+#reports that all 4 lines of the data are the same. Using mawk it correctly
+#reports that there are no repeats.
+#
+#I don't know if there are limits on the size of associative array keys for the
+#purposes of reliable indexing but if there is then it is not (obviously)
+#documented.
+#
+#
+#--==_Exmh_-11192982200
+#Content-Type: text/plain ; name="data"; charset=us-ascii
+#Content-Description: data
+#Content-Disposition: attachment; filename="data"
+#
+#322322111111112232231111
+#322322111111112213223111
+#322322111111112211132231
+#322322111111112211113223
+#
+#--==_Exmh_-11192982200
+#Content-Type: text/plain ; name="unique"; charset=us-ascii
+#Content-Description: unique
+#Content-Disposition: attachment; filename="unique"
+#
+{
+ if($0 in a)
+ {
+ printf("line %d has been seen before at line %d\n", NR, a[$0])
+ repeat_count += 1
+ }
+ else
+ {
+ a[$0] = NR
+ }
+ count += 1
+}
+END {
+# printf("%d %f%%\n", repeat_count, (float)repeat_count / count * 100)
+ printf("%d %f%%\n", repeat_count, repeat_count / count * 100)
+}
+#
+#--==_Exmh_-11192982200--
--- /dev/null
+322322111111112232231111
+322322111111112213223111
+322322111111112211132231
+322322111111112211113223
--- /dev/null
+0 0.000000%
--- /dev/null
+{ print substr(1000+$1, 2) }
--- /dev/null
+5000
+10000
+5000
--- /dev/null
+000
+1000
+000
--- /dev/null
+BEGIN{ ++x[03]; print "/" x[0] "/" x[3] "/"}
--- /dev/null
+# From dragon!knorke.saar.de!florian Wed Jul 16 10:47:27 1997
+# Return-Path: <dragon!knorke.saar.de!florian>
+# Message-ID: <19970716164451.63610@knorke.saar.de>
+# Date: Wed, 16 Jul 1997 16:44:51 +0200
+# From: Florian La Roche <florian@knorke.saar.de>
+# To: bug-gnu-utils@prep.ai.mit.edu
+# CC: arnold@gnu.ai.mit.edu
+# Subject: bug in gawk 3.0.3
+# MIME-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# X-Mailer: Mutt 0.76
+# Status: R
+# Content-Length: 1725
+# X-Lines: 177
+# X-Display-Position: 0
+#
+# I have a problem with gawk 3.0.3 on linux with libc 5.4.33.
+# The memory is corrupted, if I use OFMT = "%.12g".
+# With OFMT = "%.6g" evrything works fine, but I don't have enough
+# digits for the computation.
+#
+# Thanks a lot,
+# Florian La Roche
+#
+# Here is the sample awk-Script together with sample data:
+#
+BEGIN {
+ OFMT = "%.12g"
+ big = 99999999999
+ lowest = big
+ small = 0
+ highest = small
+ dir = ""
+ }
+$0 ~ /^[0-9]+$/ {
+ # some old awks do not think $0 is numeric, so use $1
+ if ($1 < lowest)
+ lowest = $1
+ if ($1 > highest)
+ highest = $1
+ next
+}
+$0 ~ /\/\.:$/ {
+ if (dir != "") {
+ if (highest != small)
+ print dir, highest, lowest
+ else
+ print dir, "-", "-"
+ }
+ dir = substr($0, 1, length($0)-3) # trim off /.:
+ lowest = big
+ highest = small
+}
--- /dev/null
+alt/binaries/warez/crypto/.:
+..
+...
+
+alt/fan/douglas-adams/.:
+..
+...
+7478
+7479
+7480
+7481
+7482
+7483
+7484
+7485
+7486
+7490
+7488
+7489
+7491
+7407
+7408
+7409
+7410
+7411
+7412
+7413
+7414
+7415
+7416
+7417
+7418
+7419
+7420
+7421
+7422
+7423
+7424
+7425
+7426
+7427
+7428
+7429
+7430
+7431
+7432
+7433
+7434
+7435
+7436
+7437
+7438
+7439
+7440
+7441
+7442
+7443
+7444
+7445
+7446
+7447
+7455
+7449
+7450
+7451
+7452
+7453
+7454
+7456
+7457
+7458
+7459
+7460
+7461
+7462
+7463
+7464
+7465
+7466
+7467
+7468
+7469
+7470
+7471
+7472
+7473
+7475
+7477
+
+alt/os/linux/.:
+..
+...
+
+
+alt/security/.:
+..
+...
+pgp
+ripem
+keydist
+index
+9617
+9618
+9619
+9620
+9625
+9621
+9626
+9622
+9623
+9624
+9627
+9628
+9629
+9630
+9631
+9632
+9633
+9634
+9636
+9637
+9638
+9639
+9640
+9641
+
+alt/security/index/.:
+..
+...
+
+alt/security/keydist/.:
+..
+...
+253
+
+/.:
--- /dev/null
+alt/binaries/warez/crypto - -
+alt/fan/douglas-adams 7491 7407
+alt/os/linux - -
+alt/security 9641 9617
+alt/security/index - -
+alt/security/keydist 253 253
--- /dev/null
+#
+# [USEMAP]
+#
+# Problem Report gnu/7821
+#
+# awk in free(): warning: chunk is already free.
+#
+# Confidential
+# no
+#
+# Severity
+# serious
+#
+# Priority
+# medium
+#
+# Responsible
+# freebsd-bugs@freebsd.org
+#
+# State
+# suspended
+#
+# Class
+# sw-bug
+#
+# Submitter-Id
+# current-users
+#
+# Arrival-Date
+# Thu Sep 3 10:30:00 PDT 1998
+#
+# Last-Modified
+# Thu Sep 17 02:04:26 PDT 1998
+#
+# Originator
+# Alexander Litvin archer@lucky.net
+#
+# Organization
+#
+#
+#Lucky Net ltd.
+#
+# Release
+# FreeBSD 3.0-CURRENT i386
+#
+# Environment
+#
+#
+#FreeBSD grape.carrier.kiev.ua 3.0-CURRENT FreeBSD 3.0-CURRENT #121: Thu Sep 3
+#1
+#1:21:44 EEST 1998 archer@grape.carrier.kiev.ua:/usr/src/sys/compile/GRAPE
+#i
+#386
+#
+# Description
+#
+#
+#The problem first appeared when GNU awk in 3.0-CURRENT was apgraded to
+#3.0.3. I run C-News, which uses awk extensively. After awk apgrade C-News
+#expire stopped to work. It appeared that some GNU awk 3.0.3 programms when
+#given absolutely legitimate input fail, giving out a number of messages:
+#
+#awk in free(): warning: chunk is already free.
+#
+# How-To-Repeat
+#
+#
+#Run the following awk program (it is cut out of C-News expire scripts).
+#I was not able to cut it down more -- omitting some portions of the
+#code (e.g. OFMT line), make error go away in this case, though it
+#certainly does not fix awk.
+#
+#----------------cut-here----------------
+#!/usr/bin/awk -f
+BEGIN {
+ OFMT = "%.12g"
+ big = 99999999999
+ lowest = big
+ small = 0
+ highest = small
+}
+
+$0 ~ /^[0-9]+$/ {
+ if ($1 < lowest)
+ lowest = $1
+ if ($1 > highest)
+ highest = $1
+ next
+}
+
+$0 ~ /^[a-z]+/ {
+ print dir, highest, lowest
+ dir = $0
+ lowest = big
+ highest = small
+}
+#----------------cut-here----------------
+#
+#To get the error, just give this script the following input:
+#----------------cut-here----------------
+#a
+#1
+#b
+#----------------cut-here----------------
+#
+# Fix
+#
+#
+#I was not able to track the error in awk sources. As a workaround,
+#I just reverted to GNU awk 2.15.5.
+#
+# Audit-Trail
+#
+#
+#State-Changed-From-To: open-suspended
+#State-Changed-By: phk
+#State-Changed-When: Thu Sep 17 02:04:08 PDT 1998
+#State-Changed-Why:
+#reported to GNU maintainer.
+#
+# Submit Followup
+# _________________________________________________________________
+#
+#
+# www@freebsd.org
--- /dev/null
+ 0 99999999999
+a 1 1
--- /dev/null
+# From djones@zoonami.com Wed Jun 13 17:46:27 2001
+# Received: from mail.actcom.co.il [192.114.47.13]
+# by localhost with POP3 (fetchmail-5.5.0)
+# for arnold@localhost (single-drop); Wed, 13 Jun 2001 17:46:27 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Wed Jun 13 17:47:09 2001)
+# X-From_: djones@zoonami.com Wed Jun 13 17:45:40 2001
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id RAA07057 for <arobbins@actcom.co.il>;
+# Wed, 13 Jun 2001 17:45:34 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from billohost.com (www.billohost.com [209.196.35.10])
+# by lmail.actcom.co.il (8.11.2/8.11.2) with ESMTP id f5DEjSO24028
+# for <arobbins@actcom.co.il>; Wed, 13 Jun 2001 17:45:33 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id KAA24625
+# for <arnold@skeeve.com>; Wed, 13 Jun 2001 10:44:43 -0400
+# Received: from topcat.zoonami.com ([193.112.141.198])
+# by fencepost.gnu.org with esmtp (Exim 3.16 #1 (Debian))
+# id 15ABtZ-0000FQ-00
+# for <bug-gawk@gnu.org>; Wed, 13 Jun 2001 10:45:21 -0400
+# Received: from topcat.zoonami.com (localhost [127.0.0.1])
+# by topcat.zoonami.com (8.9.3/8.9.3) with ESMTP id OAA28329;
+# Wed, 13 Jun 2001 14:45:54 GMT
+# (envelope-from djones@topcat.zoonami.com)
+# Message-Id: <200106131445.OAA28329@topcat.zoonami.com>
+# To: bug-gawk@gnu.org
+# cc: David Jones <drj@pobox.com>
+# Subject: 3.1.0 core dumps. Fiddling with OFMT?
+# Date: Wed, 13 Jun 2001 14:45:54 +0000
+# From: David Jones <djones@zoonami.com>
+# Status: R
+#
+# The following program causes gawk to dump core:
+#
+# jot 10|./gawk '{OFMT="%."NR"f";print NR}'
+#
+# 'jot 10', if you didn't know, produces the numbers 1 to 10 each on its
+# own line (ie it's like awk 'BEGIN{for(i=1;i<=10;++i)print i}')
+#
+# Here's an example run:
+#
+# -- run being
+# 1
+# 2
+# 3
+# 4
+# gawk: cmd. line:1: (FILENAME=- FNR=5) fatal error: internal error
+# Abort trap - core dumped
+# -- run end
+#
+# Ah. print NR appears to be not interesting. The following program also
+# has the same problem:
+#
+# jot 10|./gawk '{OFMT="%."NR"f"}'
+#
+# Cheers,
+# djones
+# (version info follows)
+#
+# I'm running on FreeBSD 4.1, here's the output of uname -a
+#
+# FreeBSD topcat.zoonami.com 4.1-RELEASE FreeBSD 4.1-RELEASE #0: Fri Jul 28 14:30:31 GMT 2000 jkh@ref4.freebsd.org:/usr/src/sys/compile/GENERIC i386
+#
+# And ./gnu --version
+#
+# GNU Awk 3.1.0
+# Copyright (C) 1989, 1991-2001 Free Software Foundation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+{ OFMT="%."NR"f"; print NR }
--- /dev/null
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
--- /dev/null
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
--- /dev/null
+BEGIN { OFMT= "%s" }
+{ $1 + $2; print $1, $2 }
--- /dev/null
+BEGIN { RS = "" }
+{ print "got", $0 }
--- /dev/null
+BEGIN { b = 1; a[b] = 2; a[b++] += 1; print b,a[1] }
--- /dev/null
+BEGIN {
+ print b += b += 1
+ b = 6
+ print b += b++
+ print b
+}
--- /dev/null
+Goes to a file out1
--- /dev/null
+Normal print statement
+This printed on stdout
--- /dev/null
+You blew it!
--- /dev/null
+BEGIN { foo(0, 1, 2) }
+
+function foo(a, b, c, b, a)
+{
+ print "a =", a
+ print "b =", b
+ print "c =", c
+}
--- /dev/null
+gawk: paramdup.awk:4: error: function `foo': parameter #4, `b', duplicates parameter #2
+gawk: paramdup.awk:4: error: function `foo': parameter #5, `a', duplicates parameter #1
+EXIT CODE: 1
--- /dev/null
+# Sun Apr 25 13:28:58 IDT 1999
+# from Juegen Khars. This program should not core dump.
+ function ReadPGM(f, d) {
+print "ReadPGM"
+ d[1] = 1
+ }
+
+ function WritePGM(f, d) {
+print "WritePGM"
+ d[1] = 0
+ }
+
+ BEGIN {
+print "before ReadPGM"
+ ReadPGM("", d)
+print "after ReadPGM"
+print "before WritePGM"
+ WritePGM("", d)
+print "after WritePGM"
+ }
--- /dev/null
+before ReadPGM
+ReadPGM
+after ReadPGM
+before WritePGM
+WritePGM
+after WritePGM
--- /dev/null
+BEGIN { toupper(substr*line,1,12)) }
--- /dev/null
+gawk: parseme.awk:1: BEGIN { toupper(substr*line,1,12)) }
+gawk: parseme.awk:1: ^ syntax error
+gawk: parseme.awk:1: fatal: 0 is invalid as number of arguments for toupper
+EXIT CODE: 2
--- /dev/null
+BEGIN { printf "%+d %d\n", 3, 4 }
--- /dev/null
+# From: John C. Oppenheimer <jco@slinky.convex.com>
+# Subject: gawk-3.0.2 pid test
+# To: arnold@skeeve.atl.ga.us
+# Date: Mon, 10 Feb 1997 08:31:55 -0600 (CST)
+#
+# Thanks for the very quick reply.
+#
+# This all started when I was looking for how to do the equivalent of
+# "nextfile." I was after documentation and found our gawk down a few
+# revs.
+#
+# Looks like the nextfile functionality was added somewhere around
+# 2.15.5. There wasn't a way to do it, until now! Thanks for the
+# functionality!
+#
+# Saw the /dev/xxx capability and just tried it.
+#
+# Anyway, I wrote a pid test. I hope that it is portable. Wanted to
+# make a user test, but looks like id(1) is not very portable. But a
+# little test is better than none.
+#
+# John
+#
+# pid.ok is a zero length file
+#
+# ================== pid.awk ============
+BEGIN {
+ getline pid <"/dev/pid"
+ getline ppid <"/dev/ppid"
+}
+NR == 1 {
+ if (pid != $0) {
+ printf "Bad pid %d, wanted %d\n", $0, pid
+ }
+}
+NR == 2 {
+ if (ppid != $0) {
+ printf "Bad ppid %d, wanted %d\n", $0, ppid
+ }
+}
+END { # ADR --- added
+ close("/dev/pid")
+ close("/dev/ppid")
+}
--- /dev/null
+#! /bin/sh
+AWK=${AWK-../gawk}
+echo $$ > _pid.in
+echo $1 >> _pid.in
+exec $AWK -f pid.awk _pid.in 2>/dev/null
--- /dev/null
+# From dragon!gamgee.acad.emich.edu!dhw Tue Mar 18 01:12:15 1997
+# Return-Path: <dragon!gamgee.acad.emich.edu!dhw>
+# Message-ID: <m0w6owW-000IDSC@gamgee.acad.emich.edu>
+# Date: Mon, 17 Mar 97 20:48 CST
+# From: dhw@gamgee.acad.emich.edu (David H. West)
+# To: arnold@gnu.ai.mit.edu
+# Subject: gawk 3.0.2 bug report (cc of msg to bug-gnu-utils)
+# Status: OR
+# Content-Length: 869
+# X-Lines: 20
+# X-Display-Position: 2
+#
+# Nature of bug: operation on a pipe side-effects a different pipe.
+# Observed-With: gawk 3.0.2, Linux kernel 2.0.28
+# Reproduce-By: running the following script, without and with the "close"
+# statement uncommented.
+# -----------------cut here--------------------------
+BEGIN {FILE1="test1"; FILE2="test2";
+ print "1\n" > FILE1; close(FILE1);
+ print "2\n" > FILE2; close(FILE2);
+ cmd1="cat " FILE1; cmd2="cat " FILE2;
+ #end of preparing commands which give easily-predictable output
+
+ while( (cmd1 | getline)==1) { #terminates as file has only 1 line
+ #and we never close cmd1
+ cmd2 | getline L;
+ #BUG: uncommenting the following line causes an infinite loop
+ close(cmd2);
+ print $0,L;
+ }
+ }
--- /dev/null
+# From: megaadm@rina.quantum.de
+# Subject: Bug report - closing down pipes which read from shell com
+# To: bug-gnu-utils@prep.ai.mit.edu
+# Date: Thu, 27 Feb 1997 23:19:16 +0100 (CET)
+# CC: arnold@gnu.ai.mit.edu
+#
+# Hello people,
+#
+# i think i found a bug or something mysterious behaviour in
+# gawk Version 3.0 patchlevel 0.
+#
+# I am running on linux 2.0.25 under bash.
+#
+# Could you please have a look at the following awk program
+# an let me please know, if this is what i expect it to,
+# namely a bug.
+#
+# ----------- cut here --------------------------------------------
+BEGIN {
+ # OS is linux 2.0.25
+ # shell is bash
+ # Gnu Awk (gawk) 3.0, patchlevel 0
+ # The command i typed on the shell was "gawk -f <this_prog> -"
+
+ #com = "cal 01 1997"
+ com = ("cat " SRCDIR "/pipeio2.in")
+
+ while ((com | getline fnam) > 0) {
+
+# com_tr = "echo " fnam " | tr [0-9]. ..........."
+# com_tr = "echo " fnam " | sed 's/[0-9]/./g'"
+ com_tr = "echo " fnam " | sed \"s/[0-9]/./g\""
+ # print "\'" com_tr "\'"
+ print "'" com_tr "'"
+
+ com_tr | getline nam
+ print nam
+
+ # please run that program and take a look at the
+ # output. I think this is what was expected.
+
+ # Then comment in the following 4 lines and see
+ # what happens. I expect the first pipe "com | getline"
+ # not to be close, but i think this is exactly what happens
+ # So, is this ok ?
+
+ if (close(com_tr) < 0) {
+ print ERRNO
+ break
+ }
+ }
+
+ close(com)
+ }
+# ----------- cut here --------------------------------------------
+#
+# There is another thing i do not understand.
+# Why doesn't the awk - command "close" reports an
+# error, if i would say close("abc") which i had never
+# openend ?
+#
+# Regards,
+# Ulrich Gvbel
+# --
+# /********************************************************\
+# * Ulrich Gvbel, goebel@quantum.de *
+# * Quantum Gesellschaft f|r Software mbH, Dortmund *
+# * phone : +49-231-9749-201 fax: +49-231-9749-3 *
+# * private: +49-231-803994 fax: +49-231-803994 *
+# \********************************************************/
--- /dev/null
+ January 1997
+ S M Tu W Th F S
+ 1 2 3 4
+ 5 6 7 8 9 10 11
+12 13 14 15 16 17 18
+19 20 21 22 23 24 25
+26 27 28 29 30 31
+
--- /dev/null
+'echo January 1997 | sed "s/[0-9]/./g"'
+January ....
+'echo S M Tu W Th F S | sed "s/[0-9]/./g"'
+S M Tu W Th F S
+'echo 1 2 3 4 | sed "s/[0-9]/./g"'
+. . . .
+'echo 5 6 7 8 9 10 11 | sed "s/[0-9]/./g"'
+. . . . . .. ..
+'echo 12 13 14 15 16 17 18 | sed "s/[0-9]/./g"'
+.. .. .. .. .. .. ..
+'echo 19 20 21 22 23 24 25 | sed "s/[0-9]/./g"'
+.. .. .. .. .. .. ..
+'echo 26 27 28 29 30 31 | sed "s/[0-9]/./g"'
+.. .. .. .. .. ..
+'echo | sed "s/[0-9]/./g"'
+
--- /dev/null
+BEGIN {
+ a = "+2"; b = 2; c = "+2a"; d = "+2 "; e = " 2"
+
+ printf "Test #1: "
+ if (b == a) print "\"" a "\"" " compares as a number"
+ else print "\"" a "\"" " compares as a string"
+
+ printf "Test #2: "
+ if (b == c) print "\"" c "\"" " compares as a number"
+ else print "\"" c "\"" " compares as a string"
+
+ printf "Test #3: "
+ if (b == d) print "\"" d "\"" " compares as a number"
+ else print "\"" d "\"" " compares as a string"
+
+ printf "Test #4: "
+ if (b == e) print "\"" e "\"" " compares as a number"
+ else print "\"" e "\"" " compares as a string"
+
+ f = a + b + c + d + e
+ print "after addition"
+
+ printf "Test #5: "
+ if (b == a) print "\"" a "\"" " compares as a number"
+ else print "\"" a "\"" " compares as a string"
+
+ printf "Test #6: "
+ if (b == c) print "\"" c "\"" " compares as a number"
+ else print "\"" c "\"" " compares as a string"
+
+ printf "Test #7: "
+ if (b == d) print "\"" d "\"" " compares as a number"
+ else print "\"" d "\"" " compares as a string"
+
+ printf "Test #8: "
+ if (b == e) print "\"" e "\"" " compares as a number"
+ else print "\"" e "\"" " compares as a string"
+
+ printf "Test #9: "
+ if ("3e5" > "5") print "\"3e5\" > \"5\""
+ else print "\"3e5\" <= \"5\""
+
+ printf "Test #10: "
+ x = 32.14
+ y[x] = "test"
+ OFMT = "%e"
+ print y[x]
+
+ printf "Test #11: "
+ x = x + 0
+ print y[x]
+
+ printf "Test #12: "
+ OFMT="%f"
+ CONVFMT="%e"
+ print 1.5, 1.5 ""
+
+ printf "Test #13: "
+ if ( 1000000 "" == 1000001 "") print "match"
+ else print "nomatch"
+}
+{
+ printf "Test #14: "
+ FS = ":"
+ print $1
+ FS = ","
+ printf "Test #15: "
+ print $2
+}
--- /dev/null
+Test #1: "+2" compares as a string
+Test #2: "+2a" compares as a string
+Test #3: "+2 " compares as a string
+Test #4: " 2" compares as a string
+after addition
+Test #5: "+2" compares as a string
+Test #6: "+2a" compares as a string
+Test #7: "+2 " compares as a string
+Test #8: " 2" compares as a string
+Test #9: "3e5" <= "5"
+Test #10: test
+Test #11: test
+Test #12: 1.500000 1.500000e+00
+Test #13: nomatch
+Test #14: 1:2,3
+Test #15: 4
--- /dev/null
+#! /tmp/gawk -f
+{ print }
--- /dev/null
+{ print NF, $NF, "abc" $NF }
--- /dev/null
+1 one abcone
--- /dev/null
+# check the precedence of operators:
+BEGIN {
+ $1 = i = 1
+ $+i++
+ $- -i++
+ print
+}
--- /dev/null
+BEGIN {
+ # bwk accepts this silently:
+ printf
+ print "X"
+}
--- /dev/null
+# Tue May 25 16:36:16 IDT 1999
+#
+# Test cases based on email from Andreas Schwab, schwab@gnu.org
+
+BEGIN {
+ fmt[1] = "%8.5d"; data[1] = 100
+ fmt[2] = "%#o"; data[2] = 0
+ fmt[3] = "%#.1o"; data[3] = 0
+ fmt[4] = "%#.0o"; data[4] = 0
+ fmt[5] = "%#x"; data[5] = 0
+ fmt[6] = "%.0d"; data[6] = 0
+ fmt[7] = "%5.0d"; data[7] = 0
+
+ for (i = 1; i <= 7; i++) {
+ format = "%s, %d --- |" fmt[i] "|\n"
+ printf(format, fmt[i], data[i], data[i])
+ }
+
+}
--- /dev/null
+%8.5d, 100 --- | 00100|
+%#o, 0 --- |0|
+%#.1o, 0 --- |0|
+%#.0o, 0 --- |0|
+%#x, 0 --- |0|
+%.0d, 0 --- ||
+%5.0d, 0 --- | |
--- /dev/null
+#Date: Mon, 7 Jun 2004 10:40:28 -0500
+#From: mary1john8@earthlink.net
+#To: arnold@skeeve.com
+#Subject: gawk internal errors
+#Message-ID: <20040607154028.GA2457@apollo>
+#
+#Hello,
+#
+# gawk-3.1.3i internal errors:
+#
+#[1]
+#
+#$> ./gawk 'BEGIN { for (i in a) delete a; }'
+#gawk: fatal error: internal error
+#Aborted
+#
+#------------------------------------------------------------------
+#--- awkgram.y.orig 2004-06-07 09:42:14.000000000 -0500
+#+++ awkgram.y 2004-06-07 09:45:58.000000000 -0500
+#@@ -387,7 +387,7 @@
+# * Check that the body is a `delete a[i]' statement,
+# * and that both the loop var and array names match.
+# */
+#- if ($8 != NULL && $8->type == Node_K_delete) {
+#+ if ($8 != NULL && $8->type == Node_K_delete && $8->rnode != NULL) {
+# NODE *arr, *sub;
+#
+# assert($8->rnode->type == Node_expression_list);
+#------------------------------------------------------------------
+#
+#
+#[2]
+#
+#$> ./gawk 'BEGIN { printf("%3$*10$.*1$s\n", 20, 10, "hello"); }'
+BEGIN { printf("%3$*10$.*1$s\n", 20, 10, "hello"); }
+#gawk: fatal error: internal error
+#Aborted
+#
+#------------------------------------------------------------------
+#--- builtin.c.orig 2004-06-07 10:04:20.000000000 -0500
+#+++ builtin.c 2004-06-07 10:06:08.000000000 -0500
+#@@ -780,7 +780,10 @@
+# s1++;
+# n0--;
+# }
+#-
+#+ if (val >= num_args) {
+#+ toofew = TRUE;
+#+ break;
+#+ }
+# arg = the_args[val];
+# } else {
+# parse_next_arg();
+#------------------------------------------------------------------
+#
+#
+# Finally, a test for the rewritten get_src_buf():
+#
+#$> AWKBUFSIZE=2 make check
+#
+#I get 3 failed tests. Not sure this is of any interest.
+#
+#
+#Thanks,
+#John
--- /dev/null
+gawk: printfbad1.awk:35: fatal: not enough arguments to satisfy format string
+ `%3$*10$.*1$s
+'
+ ^ ran out for this one
+EXIT CODE: 2
--- /dev/null
+# Test program for checking sprintf operation with various floating
+# point formats
+#
+# Watch out - full output of this program will have 3000 * tot lines,
+# which will take a chunk of space if you will write it to your disk.
+# --mj
+
+BEGIN {
+ just = "-"
+ plus = "+ "
+ alt = "#"
+ zero = "0"
+ spec = "feEgG"
+ fw[1] = ""
+ fw[2] = "1"
+ fw[3] = "5"
+ fw[4] = "10"
+ fw[5] = "15"
+ prec[1] = ".-1"
+ prec[2] = ""
+ prec[3] = ".2"
+ prec[4] = ".5"
+ prec[5] = ".10"
+
+ num = 123.6
+ factor = 1.0e-12
+ tot = 8
+ data[1] = 0
+ data[2] = 1
+ for (i = 3; i <= tot; i++) {
+ data[i] = num * factor
+ factor *= 1000
+ }
+
+ for (j = 1; j <= 2; j++) {
+ for (p = 1; p <= 3; p++) {
+ for (a = 1; a <= 2; a++) {
+ for (z = 1; z <= 2; z++) {
+ for (s = 1; s <= 5; s++) {
+ for (w = 1; w <= 5; w++) {
+ for (r = 1; r <= 5; r++) {
+ frmt = "|%" substr(just, j, 1)
+ frmt = frmt substr(plus, p, 1)
+ frmt = frmt substr(alt, a, 1)
+ frmt = frmt substr(zero, z, 1)
+ frmt = frmt fw[w] prec[r]
+ frmt = frmt substr(spec, s, 1) "|"
+ for (i = 1; i <= tot; i++) {
+ result = sprintf(frmt, data[i])
+# "normalize" if you must
+# sub(/\|\./, "|0.", result)
+ printf("%-16s %-25s\t%g\n", frmt,
+ result,data[i])
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+BEGIN {
+ printf "\nLocale environment:\n\tLC_ALL=\"%s\" LANG=\"%s\"\n\n",
+ ENVIRON["LC_ALL"], ENVIRON["LANG"]
+}
--- /dev/null
+function test(a)
+{
+ print a[1]
+}
+
+BEGIN { j = 4; test(j) }
--- /dev/null
+gawk: prmarscl.awk:3: fatal: attempt to use scalar parameter `a' as an array
+EXIT CODE: 2
--- /dev/null
+# from Pat Rankin, rankin@eql.caltech.edu, now rankin@pactechdata.com
+
+BEGIN { dummy(1); legit(); exit }
+
+function dummy(arg)
+{
+ return arg
+}
+
+function legit( scratch)
+{
+ split("1 2 3", scratch)
+ return ""
+}
--- /dev/null
+BEGIN {
+ printf "Initially, PROCINFO[\"FS\"] = %s\n", PROCINFO["FS"]
+ FIELDWIDTHS = "3 4 5 6"
+ printf "After assign to FIELDWIDTHS, PROCINFO[\"FS\"] = %s\n", PROCINFO["FS"]
+ FS = FS
+ printf "After assign to FS, PROCINFO[\"FS\"] = %s\n", PROCINFO["FS"]
+}
--- /dev/null
+Initially, PROCINFO["FS"] = FS
+After assign to FIELDWIDTHS, PROCINFO["FS"] = FIELDWIDTHS
+After assign to FS, PROCINFO["FS"] = FS
--- /dev/null
+function tst () {
+ sum += 1
+ return sum
+}
+
+BEGIN { OFMT = "%.0f" ; print tst() }
--- /dev/null
+function returns_a_str() { print "<in function>" ; return "'A STRING'" }
+BEGIN {
+ print "partial line:", returns_a_str()
+}
--- /dev/null
+<in function>
+partial line: 'A STRING'
--- /dev/null
+BEGIN {
+ text = "here is some text"
+ repl = "<FOO&BAR \\q \\ \\\\ \\& \\\\& \\\\\\&>"
+ printf "orig = \"%s\", repl = \"%s\"\n", text, repl
+ sub(/some/, repl, text)
+ printf "result is \"%s\"\n", text
+}
--- /dev/null
+orig = "here is some text", repl = "<FOO&BAR \q \ \\ \& \\& \\\&>"
+result is "here is <FOOsomeBAR \q \ \\ & \some \&> text"
--- /dev/null
+BEGIN {
+ srand(2)
+ for (i = 0; i < 19; i++)
+ printf "%3d ", (1 + int(100 * rand()))
+ print ""
+}
--- /dev/null
+ 62 67 88 6 35 77 3 68 30 96 90 26 35 8 88 93 49 53 37
--- /dev/null
+# From hankedr@dms.auburn.edu Sun Jan 28 12:25:43 2001
+# Received: from mail.actcom.co.il [192.114.47.13]
+# by localhost with POP3 (fetchmail-5.5.0)
+# for arnold@localhost (single-drop); Sun, 28 Jan 2001 12:25:43 +0200 (IST)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Sun Jan 28 12:27:08 2001)
+# X-From_: hankedr@dms.auburn.edu Sat Jan 27 15:15:57 2001
+# Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id PAA23801 for <arobbins@actcom.co.il>;
+# Sat, 27 Jan 2001 15:15:55 +0200 (EET)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from billohost.com (www.billohost.com [209.196.35.10])
+# by lmail.actcom.co.il (8.9.3/8.9.1) with ESMTP id PAA15998
+# for <arobbins@actcom.co.il>; Sat, 27 Jan 2001 15:16:27 +0200
+# Received: from yak.dms.auburn.edu (yak.dms.auburn.edu [131.204.53.2])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id IAA00467
+# for <arnold@skeeve.com>; Sat, 27 Jan 2001 08:15:52 -0500
+# Received: (from hankedr@localhost)
+# by yak.dms.auburn.edu (8.9.3/8.9.3/Debian/GNU) id HAA24441;
+# Sat, 27 Jan 2001 07:15:44 -0600
+# Date: Sat, 27 Jan 2001 07:15:44 -0600
+# Message-Id: <200101271315.HAA24441@yak.dms.auburn.edu>
+# From: Darrel Hankerson <hankedr@dms.auburn.edu>
+# To: arnold@skeeve.com
+# Subject: [stolfi@ic.unicamp.br: Bug in [...]* matching with acute-u]
+# Mime-Version: 1.0 (generated by tm-edit 7.106)
+# Content-Type: message/rfc822
+# Status: R
+#
+# From: Jorge Stolfi <stolfi@ic.unicamp.br>
+# To: bug-gnu-utils@gnu.org
+# Subject: Bug in [...]* matching with acute-u
+# MIME-Version: 1.0
+# Reply-To: stolfi@ic.unicamp.br
+# X-MIME-Autoconverted: from 8bit to quoted-printable by grande.dcc.unicamp.br id GAA10716
+# Sender: bug-gnu-utils-admin@gnu.org
+# Errors-To: bug-gnu-utils-admin@gnu.org
+# X-BeenThere: bug-gnu-utils@gnu.org
+# X-Mailman-Version: 2.0
+# Precedence: bulk
+# List-Help: <mailto:bug-gnu-utils-request@gnu.org?subject=help>
+# List-Post: <mailto:bug-gnu-utils@gnu.org>
+# List-Subscribe: <http://mail.gnu.org/mailman/listinfo/bug-gnu-utils>,
+# <mailto:bug-gnu-utils-request@gnu.org?subject=subscribe>
+# List-Id: Bug reports for the GNU utilities <bug-gnu-utils.gnu.org>
+# List-Unsubscribe: <http://mail.gnu.org/mailman/listinfo/bug-gnu-utils>,
+# <mailto:bug-gnu-utils-request@gnu.org?subject=unsubscribe>
+# List-Archive: <http://mail.gnu.org/pipermail/bug-gnu-utils/>
+# Date: Sat, 27 Jan 2001 06:46:11 -0200 (EDT)
+# Content-Transfer-Encoding: 8bit
+# X-MIME-Autoconverted: from quoted-printable to 8bit by manatee.dms.auburn.edu id CAA14936
+# Content-Type: text/plain; charset=iso-8859-1
+# <mailto:bug-gnu-utils-request@gnu.org?subject=subscribe>
+# <mailto:bug-gnu-utils-request@gnu.org?subject=uns
+# Content-Length: 3137
+#
+#
+#
+# Hi,
+#
+# I think I have run into a bug in gawk's handling of REs of the
+# form [...]* when the bracketed list includes certain 8-bit characters,
+# specifically u-acute (octal \372).
+#
+# The problem occurs in GNU Awk 3.0.4, both under
+# Linux 2.2.14-5.0 (intel i686) and SunOS 5.5 (Sun sparc).
+#
+# Here is a program that illustrates the bug, and its output.
+# The first two lines of the output should be equal, shouldn't they?
+#
+# ----------------------------------------------------------------------
+#! /usr/bin/gawk -f
+
+BEGIN {
+ s = "bananas and ananases in canaan";
+ t = s; gsub(/[an]*n/, "AN", t); printf "%-8s %s\n", "[an]*n", t;
+ t = s; gsub(/[anú]*n/, "AN", t); printf "%-8s %s\n", "[anú]*n", t;
+ print "";
+ t = s; gsub(/[aú]*n/, "AN", t); printf "%-8s %s\n", "[aú]*n", t;
+ print "";
+ t = s; gsub(/[an]n/, "AN", t); printf "%-8s %s\n", "[an]n", t;
+ t = s; gsub(/[aú]n/, "AN", t); printf "%-8s %s\n", "[aú]n", t;
+ t = s; gsub(/[anú]n/, "AN", t); printf "%-8s %s\n", "[anú]n", t;
+ print "";
+ t = s; gsub(/[an]?n/, "AN", t); printf "%-8s %s\n", "[an]?n", t;
+ t = s; gsub(/[aú]?n/, "AN", t); printf "%-8s %s\n", "[aú]?n", t;
+ t = s; gsub(/[anú]?n/, "AN", t); printf "%-8s %s\n", "[anú]?n", t;
+ print "";
+ t = s; gsub(/[an]+n/, "AN", t); printf "%-8s %s\n", "[an]+n", t;
+ t = s; gsub(/[aú]+n/, "AN", t); printf "%-8s %s\n", "[aú]+n", t;
+ t = s; gsub(/[anú]+n/, "AN", t); printf "%-8s %s\n", "[anú]+n", t;
+}
+# ----------------------------------------------------------------------
+# [an]*n bANas ANd ANases iAN cAN
+# [anú]*n bananas and ananases in canaan
+#
+# [aú]*n bANANas ANd ANANases iAN cANAN
+#
+# [an]n bANANas ANd ANANases in cANaAN
+# [aú]n bANANas ANd ANANases in cANaAN
+# [anú]n bANANas ANd ANANases in cANaAN
+#
+# [an]?n bANANas ANd ANANases iAN cANaAN
+# [aú]?n bANANas ANd ANANases iAN cANaAN
+# [anú]?n bANANas ANd ANANases iAN cANaAN
+#
+# [an]+n bANas ANd ANases in cAN
+# [aú]+n bANANas ANd ANANases in cANAN
+# [anú]+n bananas and ananases in canaan
+# ----------------------------------------------------------------------
+#
+# Apparently the problem is specific to u-acute; I've tried several
+# other 8-bit characters and they seem to behave as expected.
+#
+# By comparing the second and third output lines, it would seem that the
+# problem involves backtracking out of a partial match of [...]* in
+# order to match the next sub-expression, when the latter begins with
+# one of the given characters.
+#
+#
+# All the best,
+#
+# --stolfi
+#
+# ------------------------------------------------------------------------
+# Jorge Stolfi | http://www.dcc.unicamp.br/~stolfi | stolfi@dcc.unicamp.br
+# Institute of Computing (formerly DCC-IMECC) | Wrk +55 (19)3788-5858
+# Universidade Estadual de Campinas (UNICAMP) | +55 (19)3788-5840
+# Av. Albert Einstein 1251 - Caixa Postal 6176 | Fax +55 (19)3788-5847
+# 13083-970 Campinas, SP -- Brazil | Hom +55 (19)3287-4069
+# ------------------------------------------------------------------------
+#
+# _______________________________________________
+# Bug-gnu-utils mailing list
+# Bug-gnu-utils@gnu.org
+# http://mail.gnu.org/mailman/listinfo/bug-gnu-utils
+#
+#
--- /dev/null
+[an]*n bANas ANd ANases iAN cAN
+[anú]*n bANas ANd ANases iAN cAN
+
+[aú]*n bANANas ANd ANANases iAN cANAN
+
+[an]n bANANas ANd ANANases in cANaAN
+[aú]n bANANas ANd ANANases in cANaAN
+[anú]n bANANas ANd ANANases in cANaAN
+
+[an]?n bANANas ANd ANANases iAN cANaAN
+[aú]?n bANANas ANd ANANases iAN cANaAN
+[anú]?n bANANas ANd ANANases iAN cANaAN
+
+[an]+n bANas ANd ANases in cAN
+[aú]+n bANANas ANd ANANases in cANAN
+[anú]+n bANas ANd ANases in cAN
--- /dev/null
+#From stolfi@ic.unicamp.br Sun Jan 28 19:02:09 2001
+#Received: from mail.actcom.co.il [192.114.47.13]
+# by localhost with POP3 (fetchmail-5.5.0)
+# for arnold@localhost (single-drop); Sun, 28 Jan 2001 19:02:09 +0200 (IST)
+#Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Sun Jan 28 19:03:34 2001)
+#X-From_: stolfi@ic.unicamp.br Sun Jan 28 18:46:02 2001
+#Received: from lmail.actcom.co.il by actcom.co.il with ESMTP
+# (8.9.1a/actcom-0.2) id SAA22932 for <arobbins@actcom.co.il>;
+# Sun, 28 Jan 2001 18:46:00 +0200 (EET)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+#Received: from billohost.com (www.billohost.com [209.196.35.10])
+# by lmail.actcom.co.il (8.9.3/8.9.1) with ESMTP id SAA18523
+# for <arobbins@actcom.co.il>; Sun, 28 Jan 2001 18:46:35 +0200
+#Received: from grande.dcc.unicamp.br (grande.dcc.unicamp.br [143.106.7.8])
+# by billohost.com (8.9.3/8.9.3) with ESMTP id LAA20063
+# for <arnold@skeeve.com>; Sun, 28 Jan 2001 11:45:54 -0500
+#Received: from amazonas.dcc.unicamp.br (amazonas.dcc.unicamp.br [143.106.7.11])
+# by grande.dcc.unicamp.br (8.9.3/8.9.3) with ESMTP id OAA29726;
+# Sun, 28 Jan 2001 14:45:47 -0200 (EDT)
+#Received: from coruja.dcc.unicamp.br (coruja.dcc.unicamp.br [143.106.24.80])
+# by amazonas.dcc.unicamp.br (8.8.5/8.8.5) with ESMTP id OAA06542;
+# Sun, 28 Jan 2001 14:45:45 -0200 (EDT)
+#Received: (from stolfi@localhost)
+# by coruja.dcc.unicamp.br (8.11.0/8.11.0) id f0SGjib16703;
+# Sun, 28 Jan 2001 14:45:44 -0200 (EDT)
+#Date: Sun, 28 Jan 2001 14:45:44 -0200 (EDT)
+#Message-Id: <200101281645.f0SGjib16703@coruja.dcc.unicamp.br>
+#From: Jorge Stolfi <stolfi@ic.unicamp.br>
+#To: Michal Jaegermann <michal@ellpspace.math.ualberta.ca>
+#Cc: Aharon Robbins <arnold@skeeve.com>, oliva@ic.unicamp.br,
+# celio@ic.unicamp.br, ducatte@ic.unicamp.br, machado@ic.unicamp.br
+#Subject: Re: a regex.c problem
+#MIME-Version: 1.0
+#Content-Transfer-Encoding: 8bit
+#Content-Type: text/plain; charset=iso-8859-1
+#In-Reply-To: <20010128090314.A5820@ellpspace.math.ualberta.ca>
+#References: <200101281207.f0SC7Un08435@skeeve.com>
+# <20010128090314.A5820@ellpspace.math.ualberta.ca>
+#Reply-To: stolfi@ic.unicamp.br
+#Status: RO
+#
+#
+# > [Michal] Are there any other examples of "certain characters"
+# > which would throw this regex engine off?
+#
+#I now tested [anX]*n for X ranging trough all characters from \000 and
+#\377, and got that unexpected result only for the following ones:
+#
+# \370 | =F8 | ø | Small o, slash
+# \371 | =F9 | ù | Small u, grave accent
+# \372 | =FA | ú | Small u, acute accent
+# \373 | =FB | û | Small u, circumflex accent
+# \374 | =FC | ü | Small u, dieresis or umlaut mark
+# \375 | =FD | ý | Small y, acute accent
+# \376 | =FE | þ | Small thorn, Icelandic
+# \377 | =FF | ÿ | Small y, dieresis or umlaut mark
+#
+#I have also tried those offending REs from inside emacs (20.7.1), with
+#query-replace-regexp, and it seems to be working fine. So presumably
+#the bug lies in gawk itself, or in the RE parsing code, rather than in
+#the matching engine?
+#
+#Could it be an underdimensioned table somewhere?
+#
+#Thanks for the help, and all the best
+#
+#--stolfi
+#
+# ----------------------------------------------------------------------
+ #! /usr/bin/gawk -f
+
+ BEGIN {
+ for (c = 0; c < 256; c++)
+ { do_test(c); }
+ }
+
+ function do_test(char, pat,s,t)
+ {
+ if (char == 92) { printf "(error for \\%03o)\n", char; return; }
+ pat = sprintf("[an\\%03o]*n", char);
+ s = "bananas and ananases in canaan";
+ t = s; gsub(pat, "AN", t); printf "%-8s %s\n", pat, t;
+# ADR: Added:
+ if (s ~ pat) printf "\tmatch\n" ; else printf "\tno-match\n"
+ }
+
+# ----------------------------------------------------------------------
--- /dev/null
+[an\000]*n bANas ANd ANases iAN cAN
+ match
+[an\001]*n bANas ANd ANases iAN cAN
+ match
+[an\002]*n bANas ANd ANases iAN cAN
+ match
+[an\003]*n bANas ANd ANases iAN cAN
+ match
+[an\004]*n bANas ANd ANases iAN cAN
+ match
+[an\005]*n bANas ANd ANases iAN cAN
+ match
+[an\006]*n bANas ANd ANases iAN cAN
+ match
+[an\007]*n bANas ANd ANases iAN cAN
+ match
+[an\010]*n bANas ANd ANases iAN cAN
+ match
+[an\011]*n bANas ANd ANases iAN cAN
+ match
+[an\012]*n bANas ANd ANases iAN cAN
+ match
+[an\013]*n bANas ANd ANases iAN cAN
+ match
+[an\014]*n bANas ANd ANases iAN cAN
+ match
+[an\015]*n bANas ANd ANases iAN cAN
+ match
+[an\016]*n bANas ANd ANases iAN cAN
+ match
+[an\017]*n bANas ANd ANases iAN cAN
+ match
+[an\020]*n bANas ANd ANases iAN cAN
+ match
+[an\021]*n bANas ANd ANases iAN cAN
+ match
+[an\022]*n bANas ANd ANases iAN cAN
+ match
+[an\023]*n bANas ANd ANases iAN cAN
+ match
+[an\024]*n bANas ANd ANases iAN cAN
+ match
+[an\025]*n bANas ANd ANases iAN cAN
+ match
+[an\026]*n bANas ANd ANases iAN cAN
+ match
+[an\027]*n bANas ANd ANases iAN cAN
+ match
+[an\030]*n bANas ANd ANases iAN cAN
+ match
+[an\031]*n bANas ANd ANases iAN cAN
+ match
+[an\032]*n bANas ANd ANases iAN cAN
+ match
+[an\033]*n bANas ANd ANases iAN cAN
+ match
+[an\034]*n bANas ANd ANases iAN cAN
+ match
+[an\035]*n bANas ANd ANases iAN cAN
+ match
+[an\036]*n bANas ANd ANases iAN cAN
+ match
+[an\037]*n bANas ANd ANases iAN cAN
+ match
+[an\040]*n bANasANdANases iAN cAN
+ match
+[an\041]*n bANas ANd ANases iAN cAN
+ match
+[an\042]*n bANas ANd ANases iAN cAN
+ match
+[an\043]*n bANas ANd ANases iAN cAN
+ match
+[an\044]*n bANas ANd ANases iAN cAN
+ match
+[an\045]*n bANas ANd ANases iAN cAN
+ match
+[an\046]*n bANas ANd ANases iAN cAN
+ match
+[an\047]*n bANas ANd ANases iAN cAN
+ match
+[an\050]*n bANas ANd ANases iAN cAN
+ match
+[an\051]*n bANas ANd ANases iAN cAN
+ match
+[an\052]*n bANas ANd ANases iAN cAN
+ match
+[an\053]*n bANas ANd ANases iAN cAN
+ match
+[an\054]*n bANas ANd ANases iAN cAN
+ match
+[an\055]*n bANas ANd ANases iAN cAN
+ match
+[an\056]*n bANas ANd ANases iAN cAN
+ match
+[an\057]*n bANas ANd ANases iAN cAN
+ match
+[an\060]*n bANas ANd ANases iAN cAN
+ match
+[an\061]*n bANas ANd ANases iAN cAN
+ match
+[an\062]*n bANas ANd ANases iAN cAN
+ match
+[an\063]*n bANas ANd ANases iAN cAN
+ match
+[an\064]*n bANas ANd ANases iAN cAN
+ match
+[an\065]*n bANas ANd ANases iAN cAN
+ match
+[an\066]*n bANas ANd ANases iAN cAN
+ match
+[an\067]*n bANas ANd ANases iAN cAN
+ match
+[an\070]*n bANas ANd ANases iAN cAN
+ match
+[an\071]*n bANas ANd ANases iAN cAN
+ match
+[an\072]*n bANas ANd ANases iAN cAN
+ match
+[an\073]*n bANas ANd ANases iAN cAN
+ match
+[an\074]*n bANas ANd ANases iAN cAN
+ match
+[an\075]*n bANas ANd ANases iAN cAN
+ match
+[an\076]*n bANas ANd ANases iAN cAN
+ match
+[an\077]*n bANas ANd ANases iAN cAN
+ match
+[an\100]*n bANas ANd ANases iAN cAN
+ match
+[an\101]*n bANas ANd ANases iAN cAN
+ match
+[an\102]*n bANas ANd ANases iAN cAN
+ match
+[an\103]*n bANas ANd ANases iAN cAN
+ match
+[an\104]*n bANas ANd ANases iAN cAN
+ match
+[an\105]*n bANas ANd ANases iAN cAN
+ match
+[an\106]*n bANas ANd ANases iAN cAN
+ match
+[an\107]*n bANas ANd ANases iAN cAN
+ match
+[an\110]*n bANas ANd ANases iAN cAN
+ match
+[an\111]*n bANas ANd ANases iAN cAN
+ match
+[an\112]*n bANas ANd ANases iAN cAN
+ match
+[an\113]*n bANas ANd ANases iAN cAN
+ match
+[an\114]*n bANas ANd ANases iAN cAN
+ match
+[an\115]*n bANas ANd ANases iAN cAN
+ match
+[an\116]*n bANas ANd ANases iAN cAN
+ match
+[an\117]*n bANas ANd ANases iAN cAN
+ match
+[an\120]*n bANas ANd ANases iAN cAN
+ match
+[an\121]*n bANas ANd ANases iAN cAN
+ match
+[an\122]*n bANas ANd ANases iAN cAN
+ match
+[an\123]*n bANas ANd ANases iAN cAN
+ match
+[an\124]*n bANas ANd ANases iAN cAN
+ match
+[an\125]*n bANas ANd ANases iAN cAN
+ match
+[an\126]*n bANas ANd ANases iAN cAN
+ match
+[an\127]*n bANas ANd ANases iAN cAN
+ match
+[an\130]*n bANas ANd ANases iAN cAN
+ match
+[an\131]*n bANas ANd ANases iAN cAN
+ match
+[an\132]*n bANas ANd ANases iAN cAN
+ match
+[an\133]*n bANas ANd ANases iAN cAN
+ match
+(error for \134)
+[an\135]*n bANANas ANd ANANases in cANaAN
+ match
+[an\136]*n bANas ANd ANases iAN cAN
+ match
+[an\137]*n bANas ANd ANases iAN cAN
+ match
+[an\140]*n bANas ANd ANases iAN cAN
+ match
+[an\141]*n bANas ANd ANases iAN cAN
+ match
+[an\142]*n ANas ANd ANases iAN cAN
+ match
+[an\143]*n bANas ANd ANases iAN AN
+ match
+[an\144]*n bANas ANd ANases iAN cAN
+ match
+[an\145]*n bANas ANd ANases iAN cAN
+ match
+[an\146]*n bANas ANd ANases iAN cAN
+ match
+[an\147]*n bANas ANd ANases iAN cAN
+ match
+[an\150]*n bANas ANd ANases iAN cAN
+ match
+[an\151]*n bANas ANd ANases AN cAN
+ match
+[an\152]*n bANas ANd ANases iAN cAN
+ match
+[an\153]*n bANas ANd ANases iAN cAN
+ match
+[an\154]*n bANas ANd ANases iAN cAN
+ match
+[an\155]*n bANas ANd ANases iAN cAN
+ match
+[an\156]*n bANas ANd ANases iAN cAN
+ match
+[an\157]*n bANas ANd ANases iAN cAN
+ match
+[an\160]*n bANas ANd ANases iAN cAN
+ match
+[an\161]*n bANas ANd ANases iAN cAN
+ match
+[an\162]*n bANas ANd ANases iAN cAN
+ match
+[an\163]*n bANas ANd ANases iAN cAN
+ match
+[an\164]*n bANas ANd ANases iAN cAN
+ match
+[an\165]*n bANas ANd ANases iAN cAN
+ match
+[an\166]*n bANas ANd ANases iAN cAN
+ match
+[an\167]*n bANas ANd ANases iAN cAN
+ match
+[an\170]*n bANas ANd ANases iAN cAN
+ match
+[an\171]*n bANas ANd ANases iAN cAN
+ match
+[an\172]*n bANas ANd ANases iAN cAN
+ match
+[an\173]*n bANas ANd ANases iAN cAN
+ match
+[an\174]*n bANas ANd ANases iAN cAN
+ match
+[an\175]*n bANas ANd ANases iAN cAN
+ match
+[an\176]*n bANas ANd ANases iAN cAN
+ match
+[an\177]*n bANas ANd ANases iAN cAN
+ match
+[an\200]*n bANas ANd ANases iAN cAN
+ match
+[an\201]*n bANas ANd ANases iAN cAN
+ match
+[an\202]*n bANas ANd ANases iAN cAN
+ match
+[an\203]*n bANas ANd ANases iAN cAN
+ match
+[an\204]*n bANas ANd ANases iAN cAN
+ match
+[an\205]*n bANas ANd ANases iAN cAN
+ match
+[an\206]*n bANas ANd ANases iAN cAN
+ match
+[an\207]*n bANas ANd ANases iAN cAN
+ match
+[an\210]*n bANas ANd ANases iAN cAN
+ match
+[an\211]*n bANas ANd ANases iAN cAN
+ match
+[an\212]*n bANas ANd ANases iAN cAN
+ match
+[an\213]*n bANas ANd ANases iAN cAN
+ match
+[an\214]*n bANas ANd ANases iAN cAN
+ match
+[an\215]*n bANas ANd ANases iAN cAN
+ match
+[an\216]*n bANas ANd ANases iAN cAN
+ match
+[an\217]*n bANas ANd ANases iAN cAN
+ match
+[an\220]*n bANas ANd ANases iAN cAN
+ match
+[an\221]*n bANas ANd ANases iAN cAN
+ match
+[an\222]*n bANas ANd ANases iAN cAN
+ match
+[an\223]*n bANas ANd ANases iAN cAN
+ match
+[an\224]*n bANas ANd ANases iAN cAN
+ match
+[an\225]*n bANas ANd ANases iAN cAN
+ match
+[an\226]*n bANas ANd ANases iAN cAN
+ match
+[an\227]*n bANas ANd ANases iAN cAN
+ match
+[an\230]*n bANas ANd ANases iAN cAN
+ match
+[an\231]*n bANas ANd ANases iAN cAN
+ match
+[an\232]*n bANas ANd ANases iAN cAN
+ match
+[an\233]*n bANas ANd ANases iAN cAN
+ match
+[an\234]*n bANas ANd ANases iAN cAN
+ match
+[an\235]*n bANas ANd ANases iAN cAN
+ match
+[an\236]*n bANas ANd ANases iAN cAN
+ match
+[an\237]*n bANas ANd ANases iAN cAN
+ match
+[an\240]*n bANas ANd ANases iAN cAN
+ match
+[an\241]*n bANas ANd ANases iAN cAN
+ match
+[an\242]*n bANas ANd ANases iAN cAN
+ match
+[an\243]*n bANas ANd ANases iAN cAN
+ match
+[an\244]*n bANas ANd ANases iAN cAN
+ match
+[an\245]*n bANas ANd ANases iAN cAN
+ match
+[an\246]*n bANas ANd ANases iAN cAN
+ match
+[an\247]*n bANas ANd ANases iAN cAN
+ match
+[an\250]*n bANas ANd ANases iAN cAN
+ match
+[an\251]*n bANas ANd ANases iAN cAN
+ match
+[an\252]*n bANas ANd ANases iAN cAN
+ match
+[an\253]*n bANas ANd ANases iAN cAN
+ match
+[an\254]*n bANas ANd ANases iAN cAN
+ match
+[an\255]*n bANas ANd ANases iAN cAN
+ match
+[an\256]*n bANas ANd ANases iAN cAN
+ match
+[an\257]*n bANas ANd ANases iAN cAN
+ match
+[an\260]*n bANas ANd ANases iAN cAN
+ match
+[an\261]*n bANas ANd ANases iAN cAN
+ match
+[an\262]*n bANas ANd ANases iAN cAN
+ match
+[an\263]*n bANas ANd ANases iAN cAN
+ match
+[an\264]*n bANas ANd ANases iAN cAN
+ match
+[an\265]*n bANas ANd ANases iAN cAN
+ match
+[an\266]*n bANas ANd ANases iAN cAN
+ match
+[an\267]*n bANas ANd ANases iAN cAN
+ match
+[an\270]*n bANas ANd ANases iAN cAN
+ match
+[an\271]*n bANas ANd ANases iAN cAN
+ match
+[an\272]*n bANas ANd ANases iAN cAN
+ match
+[an\273]*n bANas ANd ANases iAN cAN
+ match
+[an\274]*n bANas ANd ANases iAN cAN
+ match
+[an\275]*n bANas ANd ANases iAN cAN
+ match
+[an\276]*n bANas ANd ANases iAN cAN
+ match
+[an\277]*n bANas ANd ANases iAN cAN
+ match
+[an\300]*n bANas ANd ANases iAN cAN
+ match
+[an\301]*n bANas ANd ANases iAN cAN
+ match
+[an\302]*n bANas ANd ANases iAN cAN
+ match
+[an\303]*n bANas ANd ANases iAN cAN
+ match
+[an\304]*n bANas ANd ANases iAN cAN
+ match
+[an\305]*n bANas ANd ANases iAN cAN
+ match
+[an\306]*n bANas ANd ANases iAN cAN
+ match
+[an\307]*n bANas ANd ANases iAN cAN
+ match
+[an\310]*n bANas ANd ANases iAN cAN
+ match
+[an\311]*n bANas ANd ANases iAN cAN
+ match
+[an\312]*n bANas ANd ANases iAN cAN
+ match
+[an\313]*n bANas ANd ANases iAN cAN
+ match
+[an\314]*n bANas ANd ANases iAN cAN
+ match
+[an\315]*n bANas ANd ANases iAN cAN
+ match
+[an\316]*n bANas ANd ANases iAN cAN
+ match
+[an\317]*n bANas ANd ANases iAN cAN
+ match
+[an\320]*n bANas ANd ANases iAN cAN
+ match
+[an\321]*n bANas ANd ANases iAN cAN
+ match
+[an\322]*n bANas ANd ANases iAN cAN
+ match
+[an\323]*n bANas ANd ANases iAN cAN
+ match
+[an\324]*n bANas ANd ANases iAN cAN
+ match
+[an\325]*n bANas ANd ANases iAN cAN
+ match
+[an\326]*n bANas ANd ANases iAN cAN
+ match
+[an\327]*n bANas ANd ANases iAN cAN
+ match
+[an\330]*n bANas ANd ANases iAN cAN
+ match
+[an\331]*n bANas ANd ANases iAN cAN
+ match
+[an\332]*n bANas ANd ANases iAN cAN
+ match
+[an\333]*n bANas ANd ANases iAN cAN
+ match
+[an\334]*n bANas ANd ANases iAN cAN
+ match
+[an\335]*n bANas ANd ANases iAN cAN
+ match
+[an\336]*n bANas ANd ANases iAN cAN
+ match
+[an\337]*n bANas ANd ANases iAN cAN
+ match
+[an\340]*n bANas ANd ANases iAN cAN
+ match
+[an\341]*n bANas ANd ANases iAN cAN
+ match
+[an\342]*n bANas ANd ANases iAN cAN
+ match
+[an\343]*n bANas ANd ANases iAN cAN
+ match
+[an\344]*n bANas ANd ANases iAN cAN
+ match
+[an\345]*n bANas ANd ANases iAN cAN
+ match
+[an\346]*n bANas ANd ANases iAN cAN
+ match
+[an\347]*n bANas ANd ANases iAN cAN
+ match
+[an\350]*n bANas ANd ANases iAN cAN
+ match
+[an\351]*n bANas ANd ANases iAN cAN
+ match
+[an\352]*n bANas ANd ANases iAN cAN
+ match
+[an\353]*n bANas ANd ANases iAN cAN
+ match
+[an\354]*n bANas ANd ANases iAN cAN
+ match
+[an\355]*n bANas ANd ANases iAN cAN
+ match
+[an\356]*n bANas ANd ANases iAN cAN
+ match
+[an\357]*n bANas ANd ANases iAN cAN
+ match
+[an\360]*n bANas ANd ANases iAN cAN
+ match
+[an\361]*n bANas ANd ANases iAN cAN
+ match
+[an\362]*n bANas ANd ANases iAN cAN
+ match
+[an\363]*n bANas ANd ANases iAN cAN
+ match
+[an\364]*n bANas ANd ANases iAN cAN
+ match
+[an\365]*n bANas ANd ANases iAN cAN
+ match
+[an\366]*n bANas ANd ANases iAN cAN
+ match
+[an\367]*n bANas ANd ANases iAN cAN
+ match
+[an\370]*n bANas ANd ANases iAN cAN
+ match
+[an\371]*n bANas ANd ANases iAN cAN
+ match
+[an\372]*n bANas ANd ANases iAN cAN
+ match
+[an\373]*n bANas ANd ANases iAN cAN
+ match
+[an\374]*n bANas ANd ANases iAN cAN
+ match
+[an\375]*n bANas ANd ANases iAN cAN
+ match
+[an\376]*n bANas ANd ANases iAN cAN
+ match
+[an\377]*n bANas ANd ANases iAN cAN
+ match
--- /dev/null
+# From lole@epost.de Wed Sep 4 09:54:19 IDT 2002
+# Article: 14288 of comp.lang.awk
+# Path: iad-read.news.verio.net!dfw-artgen!iad-peer.news.verio.net!news.verio.net!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!213.70.124.113!not-for-mail
+# From: LorenzAtWork <familie.lenhardt@epost.de>
+# Newsgroups: comp.lang.awk
+# Subject: bug in gawk 3.1.1?
+# Date: Wed, 28 Aug 2002 10:34:50 +0200
+# Lines: 45
+# Message-ID: <7g1pmukv07c56ep3qav3uebnipdaohqh2l@4ax.com>
+# Reply-To: lole@epost.de
+# NNTP-Posting-Host: 213.70.124.113
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Transfer-Encoding: 7bit
+# X-Trace: fu-berlin.de 1030523788 53278293 213.70.124.113 (16 [68559])
+# X-Newsreader: Forte Agent 1.91/32.564
+# Xref: dfw-artgen comp.lang.awk:14288
+#
+# hello all,
+#
+# I'm using the following script
+#
+BEGIN {
+ RS="ti1\n(dwv,)?"
+ s = 0
+ i = 0
+}
+{
+ if ($1 != "")
+ s = $1
+ print ++i, s
+}
+#
+# to extract values from a file of the form
+#
+# ti1
+# dwv,98.22
+# ti1
+# dwv,103.08
+# ti1
+# ti1
+# dwv,196.25
+# ti1
+# dwv,210.62
+# ti1
+# dwv,223.53
+#
+# The desired result for this example looks like
+#
+# 1 0
+# 2 98.22
+# 3 103.08
+# 4 103.08
+# 5 196.25
+# 6 210.62
+# 7 223.53
+#
+# The script work fine the most time, but when run on the attached file
+# (sorry for the size, but the error would not appear with less data) I
+# get some (three with the attached file) lines that look like
+#
+# 1262 dwv,212.97
+# 1277 dwv,174.33
+# 1279 dwv,151.79
+#
+# I can't think of a other reason for this than a bug in gawk!
+#
+# I'm running gawk 3.1.1 on winnt 4.0
+#
+# best regards
+# Lorenz
+#
+#
--- /dev/null
+ti1
+dwv,214.59
+ti1
+dwv,230.31
+ti1
+dwv,242.64
+ti1
+dwv,253.94
+ti1
+dwv,264.33
+ti1
+dwv,270.94
+ti1
+dwv,273.52
+ti1
+dwv,270.08
+ti1
+dwv,263.19
+ti1
+dwv,254.45
+ti1
+dwv,244.91
+ti1
+dwv,234.55
+ti1
+dwv,222.49
+ti1
+dwv,209.94
+ti1
+dwv,197.17
+ti1
+dwv,182.89
+ti1
+dwv,169.76
+ti1
+dwv,158.59
+ti1
+dwv,145.37
+ti1
+dwv,135.46
+ti1
+dwv,124.77
+ti1
+dwv,115.98
+ti1
+dwv,108.77
+ti1
+dwv,101.12
+ti1
+dwv,94.45
+ti1
+dwv,89.08
+ti1
+dwv,84.63
+ti1
+dwv,81.05
+ti1
+dwv,78.93
+ti1
+dwv,76.65
+ti1
+dwv,75.59
+ti1
+ti1
+ti1
+dwv,77.47
+ti1
+dwv,80.17
+ti1
+dwv,83.90
+ti1
+dwv,88.56
+ti1
+dwv,95.69
+ti1
+dwv,97.48
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,203.08
+ti1
+dwv,218.22
+ti1
+dwv,229.37
+ti1
+dwv,238.49
+ti1
+dwv,247.43
+ti1
+dwv,255.22
+ti1
+dwv,261.31
+ti1
+dwv,262.36
+ti1
+dwv,260.66
+ti1
+dwv,256.33
+ti1
+dwv,249.34
+ti1
+dwv,240.03
+ti1
+dwv,228.55
+ti1
+dwv,215.42
+ti1
+dwv,203.37
+ti1
+dwv,190.01
+ti1
+dwv,177.81
+ti1
+dwv,165.44
+ti1
+dwv,152.92
+ti1
+dwv,142.03
+ti1
+dwv,132.91
+ti1
+dwv,124.48
+ti1
+dwv,116.45
+ti1
+dwv,109.06
+ti1
+dwv,103.27
+ti1
+dwv,98.87
+ti1
+dwv,94.95
+ti1
+dwv,92.56
+ti1
+dwv,90.47
+ti1
+dwv,89.48
+ti1
+ti1
+dwv,90.53
+ti1
+dwv,93.07
+ti1
+dwv,97.12
+ti1
+dwv,101.82
+ti1
+dwv,108.18
+ti1
+dwv,109.73
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,202.97
+ti1
+dwv,217.38
+ti1
+dwv,231.73
+ti1
+dwv,243.11
+ti1
+dwv,255.37
+ti1
+dwv,264.12
+ti1
+dwv,269.64
+ti1
+dwv,270.98
+ti1
+dwv,269.65
+ti1
+dwv,264.55
+ti1
+dwv,257.16
+ti1
+dwv,246.01
+ti1
+dwv,232.88
+ti1
+dwv,219.85
+ti1
+dwv,208.79
+ti1
+dwv,197.00
+ti1
+dwv,183.93
+ti1
+dwv,172.00
+ti1
+dwv,160.55
+ti1
+dwv,150.59
+ti1
+dwv,141.47
+ti1
+dwv,133.02
+ti1
+dwv,126.21
+ti1
+dwv,120.64
+ti1
+dwv,115.79
+ti1
+dwv,111.62
+ti1
+dwv,108.41
+ti1
+dwv,106.41
+ti1
+ti1
+ti1
+dwv,109.08
+ti1
+dwv,113.23
+ti1
+dwv,118.57
+ti1
+dwv,122.57
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,208.07
+ti1
+dwv,224.14
+ti1
+dwv,236.28
+ti1
+dwv,248.12
+ti1
+dwv,258.97
+ti1
+dwv,267.74
+ti1
+dwv,272.47
+ti1
+dwv,271.52
+ti1
+dwv,266.80
+ti1
+dwv,258.61
+ti1
+dwv,249.30
+ti1
+dwv,239.19
+ti1
+dwv,228.28
+ti1
+dwv,215.79
+ti1
+dwv,203.86
+ti1
+dwv,190.08
+ti1
+dwv,177.40
+ti1
+dwv,163.81
+ti1
+dwv,152.60
+ti1
+dwv,141.33
+ti1
+dwv,130.98
+ti1
+dwv,121.98
+ti1
+dwv,114.08
+ti1
+dwv,106.61
+ti1
+dwv,99.75
+ti1
+dwv,93.10
+ti1
+dwv,86.57
+ti1
+dwv,80.62
+ti1
+dwv,76.05
+ti1
+dwv,71.52
+ti1
+dwv,68.85
+ti1
+dwv,67.46
+ti1
+dwv,66.86
+ti1
+dwv,67.51
+ti1
+dwv,69.75
+ti1
+dwv,72.85
+ti1
+dwv,76.23
+ti1
+dwv,82.85
+ti1
+dwv,89.33
+ti1
+dwv,93.39
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,188.37
+ti1
+dwv,204.42
+ti1
+dwv,217.16
+ti1
+dwv,228.89
+ti1
+dwv,238.83
+ti1
+dwv,247.70
+ti1
+dwv,253.59
+ti1
+dwv,257.17
+ti1
+ti1
+dwv,254.00
+ti1
+dwv,248.24
+ti1
+dwv,240.14
+ti1
+dwv,229.42
+ti1
+dwv,218.97
+ti1
+dwv,205.09
+ti1
+dwv,192.61
+ti1
+dwv,179.74
+ti1
+dwv,166.76
+ti1
+dwv,155.36
+ti1
+dwv,143.58
+ti1
+dwv,131.40
+ti1
+dwv,121.84
+ti1
+dwv,112.46
+ti1
+dwv,105.41
+ti1
+dwv,97.15
+ti1
+dwv,90.09
+ti1
+dwv,84.79
+ti1
+dwv,80.52
+ti1
+dwv,75.58
+ti1
+dwv,72.59
+ti1
+dwv,69.39
+ti1
+dwv,67.51
+ti1
+dwv,66.42
+ti1
+ti1
+ti1
+dwv,67.82
+ti1
+dwv,69.76
+ti1
+dwv,73.19
+ti1
+dwv,77.35
+ti1
+dwv,82.36
+ti1
+dwv,87.82
+ti1
+dwv,93.30
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,190.58
+ti1
+dwv,203.43
+ti1
+dwv,216.48
+ti1
+dwv,228.89
+ti1
+dwv,241.91
+ti1
+dwv,251.60
+ti1
+dwv,257.78
+ti1
+dwv,262.18
+ti1
+dwv,263.13
+ti1
+dwv,260.91
+ti1
+dwv,255.34
+ti1
+dwv,247.17
+ti1
+dwv,236.85
+ti1
+dwv,225.24
+ti1
+dwv,213.39
+ti1
+dwv,201.46
+ti1
+dwv,187.77
+ti1
+dwv,175.31
+ti1
+dwv,162.95
+ti1
+dwv,152.55
+ti1
+dwv,142.56
+ti1
+dwv,132.94
+ti1
+dwv,125.00
+ti1
+dwv,117.69
+ti1
+dwv,110.96
+ti1
+dwv,105.02
+ti1
+dwv,101.78
+ti1
+dwv,98.48
+ti1
+dwv,97.06
+ti1
+dwv,96.50
+ti1
+ti1
+dwv,98.48
+ti1
+dwv,101.18
+ti1
+dwv,104.56
+ti1
+dwv,109.67
+ti1
+dwv,115.86
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,200.02
+ti1
+dwv,217.51
+ti1
+dwv,233.21
+ti1
+dwv,245.72
+ti1
+dwv,258.21
+ti1
+dwv,267.24
+ti1
+dwv,273.79
+ti1
+dwv,273.20
+ti1
+dwv,270.38
+ti1
+dwv,260.76
+ti1
+dwv,250.05
+ti1
+dwv,241.32
+ti1
+dwv,231.14
+ti1
+dwv,219.83
+ti1
+dwv,206.13
+ti1
+dwv,193.24
+ti1
+dwv,180.73
+ti1
+dwv,167.82
+ti1
+dwv,156.94
+ti1
+dwv,144.13
+ti1
+dwv,134.40
+ti1
+dwv,125.23
+ti1
+dwv,116.13
+ti1
+dwv,107.34
+ti1
+dwv,99.71
+ti1
+dwv,94.11
+ti1
+dwv,88.91
+ti1
+dwv,84.51
+ti1
+dwv,81.50
+ti1
+dwv,78.66
+ti1
+dwv,76.57
+ti1
+dwv,75.82
+ti1
+ti1
+dwv,76.88
+ti1
+dwv,79.03
+ti1
+dwv,82.12
+ti1
+dwv,85.73
+ti1
+dwv,91.05
+ti1
+dwv,96.31
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,184.18
+ti1
+dwv,201.10
+ti1
+dwv,214.21
+ti1
+dwv,226.18
+ti1
+dwv,237.72
+ti1
+dwv,247.57
+ti1
+dwv,254.36
+ti1
+dwv,258.34
+ti1
+dwv,259.80
+ti1
+dwv,257.76
+ti1
+dwv,253.17
+ti1
+dwv,246.51
+ti1
+dwv,237.92
+ti1
+dwv,227.09
+ti1
+dwv,214.13
+ti1
+dwv,202.20
+ti1
+dwv,189.21
+ti1
+dwv,177.65
+ti1
+dwv,166.18
+ti1
+dwv,154.03
+ti1
+dwv,142.21
+ti1
+dwv,131.51
+ti1
+dwv,121.28
+ti1
+dwv,111.80
+ti1
+dwv,104.47
+ti1
+dwv,98.80
+ti1
+dwv,94.76
+ti1
+dwv,91.81
+ti1
+dwv,89.17
+ti1
+dwv,88.00
+ti1
+ti1
+ti1
+dwv,89.20
+ti1
+dwv,91.17
+ti1
+dwv,94.35
+ti1
+dwv,99.00
+ti1
+dwv,105.43
+ti1
+dwv,109.34
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,194.84
+ti1
+dwv,212.05
+ti1
+dwv,226.30
+ti1
+dwv,239.03
+ti1
+dwv,250.94
+ti1
+dwv,259.73
+ti1
+dwv,266.64
+ti1
+dwv,269.67
+ti1
+dwv,269.03
+ti1
+dwv,265.03
+ti1
+dwv,258.23
+ti1
+dwv,249.32
+ti1
+dwv,238.03
+ti1
+dwv,226.20
+ti1
+dwv,213.46
+ti1
+dwv,200.53
+ti1
+dwv,187.65
+ti1
+dwv,174.89
+ti1
+dwv,163.22
+ti1
+dwv,152.47
+ti1
+dwv,142.65
+ti1
+dwv,133.97
+ti1
+dwv,126.59
+ti1
+dwv,120.52
+ti1
+dwv,115.57
+ti1
+dwv,111.49
+ti1
+dwv,108.03
+ti1
+dwv,106.01
+ti1
+dwv,105.28
+ti1
+ti1
+dwv,106.91
+ti1
+dwv,109.73
+ti1
+dwv,114.91
+ti1
+dwv,120.66
+ti1
+dwv,123.74
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,211.57
+ti1
+dwv,227.06
+ti1
+dwv,240.57
+ti1
+dwv,252.26
+ti1
+dwv,262.67
+ti1
+dwv,270.66
+ti1
+dwv,273.40
+ti1
+dwv,270.25
+ti1
+dwv,263.76
+ti1
+dwv,256.03
+ti1
+dwv,246.87
+ti1
+dwv,237.10
+ti1
+dwv,225.11
+ti1
+dwv,211.53
+ti1
+dwv,197.77
+ti1
+dwv,185.75
+ti1
+dwv,173.00
+ti1
+dwv,159.31
+ti1
+dwv,147.18
+ti1
+dwv,134.84
+ti1
+dwv,125.07
+ti1
+dwv,115.82
+ti1
+dwv,107.33
+ti1
+dwv,100.07
+ti1
+dwv,93.55
+ti1
+dwv,87.60
+ti1
+dwv,81.75
+ti1
+dwv,77.03
+ti1
+dwv,73.39
+ti1
+dwv,70.97
+ti1
+dwv,67.94
+ti1
+dwv,66.64
+ti1
+dwv,65.80
+ti1
+ti1
+dwv,66.85
+ti1
+dwv,68.78
+ti1
+dwv,71.47
+ti1
+dwv,74.20
+ti1
+dwv,78.68
+ti1
+dwv,85.08
+ti1
+dwv,87.47
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,185.81
+ti1
+dwv,201.66
+ti1
+dwv,215.07
+ti1
+dwv,227.26
+ti1
+dwv,238.00
+ti1
+dwv,247.64
+ti1
+dwv,255.03
+ti1
+dwv,257.12
+ti1
+dwv,256.17
+ti1
+dwv,253.47
+ti1
+dwv,248.93
+ti1
+dwv,241.39
+ti1
+dwv,231.45
+ti1
+dwv,220.49
+ti1
+dwv,208.48
+ti1
+dwv,196.04
+ti1
+dwv,182.73
+ti1
+dwv,169.40
+ti1
+dwv,157.24
+ti1
+dwv,145.56
+ti1
+dwv,133.54
+ti1
+dwv,124.01
+ti1
+dwv,114.55
+ti1
+dwv,105.75
+ti1
+dwv,98.32
+ti1
+dwv,91.91
+ti1
+dwv,86.08
+ti1
+dwv,81.35
+ti1
+dwv,77.78
+ti1
+dwv,73.85
+ti1
+dwv,71.12
+ti1
+dwv,68.53
+ti1
+dwv,67.09
+ti1
+dwv,66.34
+ti1
+ti1
+ti1
+dwv,67.92
+ti1
+dwv,70.08
+ti1
+dwv,73.78
+ti1
+dwv,78.68
+ti1
+dwv,84.33
+ti1
+dwv,90.25
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,183.19
+ti1
+dwv,198.96
+ti1
+dwv,213.55
+ti1
+dwv,225.91
+ti1
+dwv,237.33
+ti1
+dwv,246.66
+ti1
+dwv,254.98
+ti1
+dwv,259.46
+ti1
+dwv,261.02
+ti1
+dwv,260.02
+ti1
+dwv,255.96
+ti1
+dwv,249.08
+ti1
+dwv,240.15
+ti1
+dwv,229.51
+ti1
+dwv,217.21
+ti1
+dwv,205.06
+ti1
+dwv,192.62
+ti1
+dwv,177.43
+ti1
+dwv,165.06
+ti1
+dwv,152.36
+ti1
+dwv,142.35
+ti1
+dwv,134.58
+ti1
+dwv,126.20
+ti1
+dwv,119.86
+ti1
+dwv,113.67
+ti1
+dwv,108.20
+ti1
+dwv,104.71
+ti1
+dwv,100.83
+ti1
+dwv,98.96
+ti1
+dwv,98.38
+ti1
+ti1
+dwv,100.29
+ti1
+dwv,103.47
+ti1
+dwv,107.73
+ti1
+dwv,113.04
+ti1
+dwv,118.90
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,200.70
+ti1
+dwv,217.77
+ti1
+dwv,232.45
+ti1
+dwv,244.28
+ti1
+dwv,256.61
+ti1
+dwv,265.93
+ti1
+dwv,272.01
+ti1
+ti1
+dwv,268.67
+ti1
+dwv,260.53
+ti1
+dwv,252.09
+ti1
+dwv,243.72
+ti1
+dwv,232.68
+ti1
+dwv,220.49
+ti1
+dwv,206.88
+ti1
+dwv,193.98
+ti1
+dwv,181.33
+ti1
+dwv,168.61
+ti1
+dwv,156.50
+ti1
+dwv,145.54
+ti1
+dwv,136.43
+ti1
+dwv,125.95
+ti1
+dwv,117.26
+ti1
+dwv,109.81
+ti1
+dwv,103.36
+ti1
+dwv,97.15
+ti1
+dwv,92.86
+ti1
+dwv,89.02
+ti1
+dwv,86.39
+ti1
+dwv,84.44
+ti1
+dwv,83.72
+ti1
+ti1
+dwv,85.89
+ti1
+dwv,88.39
+ti1
+dwv,92.31
+ti1
+dwv,96.00
+ti1
+dwv,100.24
+ti1
+dwv,102.55
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,197.15
+ti1
+dwv,212.33
+ti1
+dwv,225.48
+ti1
+dwv,236.75
+ti1
+dwv,247.52
+ti1
+dwv,255.21
+ti1
+dwv,260.74
+ti1
+dwv,262.81
+ti1
+dwv,262.09
+ti1
+dwv,258.08
+ti1
+dwv,250.83
+ti1
+dwv,242.39
+ti1
+dwv,230.86
+ti1
+dwv,219.62
+ti1
+dwv,206.80
+ti1
+dwv,193.41
+ti1
+dwv,180.60
+ti1
+dwv,168.20
+ti1
+dwv,157.77
+ti1
+dwv,145.25
+ti1
+dwv,136.23
+ti1
+dwv,126.28
+ti1
+dwv,118.10
+ti1
+dwv,110.74
+ti1
+dwv,105.29
+ti1
+dwv,99.75
+ti1
+dwv,95.61
+ti1
+dwv,92.16
+ti1
+dwv,89.93
+ti1
+dwv,88.45
+ti1
+ti1
+dwv,89.11
+ti1
+dwv,90.87
+ti1
+dwv,94.21
+ti1
+dwv,98.16
+ti1
+dwv,104.24
+ti1
+dwv,108.98
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,195.81
+ti1
+dwv,211.95
+ti1
+dwv,226.36
+ti1
+dwv,240.61
+ti1
+dwv,251.93
+ti1
+dwv,259.13
+ti1
+dwv,265.36
+ti1
+dwv,269.71
+ti1
+dwv,270.27
+ti1
+dwv,266.44
+ti1
+dwv,260.44
+ti1
+dwv,251.94
+ti1
+dwv,240.79
+ti1
+dwv,228.95
+ti1
+dwv,215.90
+ti1
+dwv,203.25
+ti1
+dwv,190.01
+ti1
+dwv,177.92
+ti1
+dwv,165.60
+ti1
+dwv,155.49
+ti1
+dwv,144.32
+ti1
+dwv,136.07
+ti1
+dwv,127.64
+ti1
+dwv,120.28
+ti1
+dwv,114.57
+ti1
+dwv,109.99
+ti1
+dwv,106.36
+ti1
+dwv,104.49
+ti1
+dwv,103.84
+ti1
+ti1
+dwv,105.77
+ti1
+dwv,107.83
+ti1
+dwv,112.41
+ti1
+dwv,117.71
+ti1
+dwv,120.66
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,210.13
+ti1
+dwv,225.03
+ti1
+dwv,238.76
+ti1
+dwv,250.50
+ti1
+dwv,261.18
+ti1
+dwv,269.22
+ti1
+dwv,274.18
+ti1
+dwv,272.28
+ti1
+dwv,266.66
+ti1
+dwv,258.68
+ti1
+dwv,249.88
+ti1
+dwv,239.94
+ti1
+dwv,227.14
+ti1
+dwv,213.22
+ti1
+dwv,197.58
+ti1
+dwv,184.86
+ti1
+dwv,172.52
+ti1
+dwv,160.19
+ti1
+dwv,149.20
+ti1
+dwv,137.49
+ti1
+dwv,127.86
+ti1
+dwv,118.91
+ti1
+dwv,110.49
+ti1
+dwv,102.73
+ti1
+dwv,96.33
+ti1
+dwv,90.95
+ti1
+dwv,86.38
+ti1
+dwv,82.72
+ti1
+dwv,79.65
+ti1
+dwv,77.61
+ti1
+dwv,75.70
+ti1
+dwv,74.49
+ti1
+ti1
+ti1
+dwv,76.48
+ti1
+dwv,79.14
+ti1
+dwv,82.84
+ti1
+dwv,87.86
+ti1
+dwv,92.69
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,181.33
+ti1
+dwv,196.86
+ti1
+dwv,210.98
+ti1
+dwv,223.13
+ti1
+dwv,233.90
+ti1
+dwv,243.19
+ti1
+dwv,250.57
+ti1
+dwv,255.00
+ti1
+dwv,256.36
+ti1
+dwv,255.16
+ti1
+dwv,250.15
+ti1
+dwv,242.80
+ti1
+dwv,233.82
+ti1
+dwv,223.41
+ti1
+dwv,210.81
+ti1
+dwv,199.04
+ti1
+dwv,187.39
+ti1
+dwv,174.14
+ti1
+dwv,162.62
+ti1
+dwv,151.39
+ti1
+dwv,139.59
+ti1
+dwv,128.71
+ti1
+dwv,119.17
+ti1
+dwv,111.02
+ti1
+dwv,103.91
+ti1
+dwv,96.78
+ti1
+dwv,91.56
+ti1
+dwv,87.13
+ti1
+dwv,83.22
+ti1
+dwv,80.50
+ti1
+dwv,76.83
+ti1
+dwv,74.24
+ti1
+dwv,70.80
+ti1
+dwv,69.04
+ti1
+dwv,67.12
+ti1
+dwv,66.51
+ti1
+ti1
+dwv,68.77
+ti1
+dwv,72.19
+ti1
+dwv,77.34
+ti1
+dwv,84.04
+ti1
+dwv,88.55
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,190.51
+ti1
+dwv,207.14
+ti1
+dwv,220.57
+ti1
+dwv,232.51
+ti1
+dwv,243.35
+ti1
+dwv,252.41
+ti1
+dwv,258.62
+ti1
+dwv,262.18
+ti1
+ti1
+dwv,259.10
+ti1
+dwv,253.54
+ti1
+dwv,245.44
+ti1
+dwv,235.55
+ti1
+dwv,223.43
+ti1
+dwv,209.91
+ti1
+dwv,197.52
+ti1
+dwv,185.90
+ti1
+dwv,172.13
+ti1
+dwv,161.09
+ti1
+dwv,150.58
+ti1
+dwv,140.37
+ti1
+dwv,130.27
+ti1
+dwv,122.13
+ti1
+dwv,114.99
+ti1
+dwv,108.76
+ti1
+dwv,104.67
+ti1
+dwv,100.36
+ti1
+dwv,97.61
+ti1
+dwv,95.48
+ti1
+dwv,94.83
+ti1
+dwv,95.45
+ti1
+dwv,97.15
+ti1
+dwv,100.73
+ti1
+dwv,105.10
+ti1
+dwv,111.46
+ti1
+dwv,118.27
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,202.92
+ti1
+dwv,220.25
+ti1
+dwv,233.35
+ti1
+dwv,243.48
+ti1
+dwv,254.85
+ti1
+dwv,265.75
+ti1
+dwv,272.62
+ti1
+ti1
+dwv,269.36
+ti1
+dwv,261.82
+ti1
+dwv,252.85
+ti1
+dwv,244.08
+ti1
+dwv,232.96
+ti1
+dwv,219.59
+ti1
+dwv,207.32
+ti1
+dwv,193.87
+ti1
+dwv,181.77
+ti1
+dwv,168.60
+ti1
+dwv,155.76
+ti1
+dwv,144.03
+ti1
+dwv,134.07
+ti1
+dwv,123.46
+ti1
+dwv,114.47
+ti1
+dwv,107.64
+ti1
+dwv,100.46
+ti1
+dwv,94.53
+ti1
+dwv,89.28
+ti1
+dwv,84.59
+ti1
+dwv,80.96
+ti1
+dwv,78.54
+ti1
+dwv,76.28
+ti1
+dwv,75.51
+ti1
+ti1
+dwv,76.55
+ti1
+dwv,78.55
+ti1
+dwv,81.57
+ti1
+dwv,85.18
+ti1
+dwv,90.61
+ti1
+dwv,96.01
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,184.51
+ti1
+dwv,201.57
+ti1
+dwv,216.33
+ti1
+dwv,228.69
+ti1
+dwv,239.90
+ti1
+dwv,250.41
+ti1
+dwv,257.91
+ti1
+dwv,262.29
+ti1
+dwv,263.41
+ti1
+dwv,261.70
+ti1
+dwv,256.75
+ti1
+dwv,246.82
+ti1
+dwv,236.35
+ti1
+dwv,225.17
+ti1
+dwv,212.90
+ti1
+dwv,201.61
+ti1
+dwv,188.42
+ti1
+dwv,175.92
+ti1
+dwv,163.70
+ti1
+dwv,153.18
+ti1
+dwv,142.89
+ti1
+dwv,132.95
+ti1
+dwv,125.18
+ti1
+dwv,117.61
+ti1
+dwv,110.36
+ti1
+dwv,104.56
+ti1
+dwv,100.13
+ti1
+dwv,96.64
+ti1
+dwv,93.52
+ti1
+dwv,91.91
+ti1
+ti1
+ti1
+dwv,93.84
+ti1
+dwv,97.13
+ti1
+dwv,101.08
+ti1
+dwv,107.19
+ti1
+dwv,111.89
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,195.89
+ti1
+dwv,212.65
+ti1
+dwv,226.60
+ti1
+dwv,239.28
+ti1
+dwv,251.28
+ti1
+dwv,259.92
+ti1
+dwv,266.03
+ti1
+dwv,269.76
+ti1
+ti1
+dwv,265.55
+ti1
+dwv,258.92
+ti1
+dwv,250.42
+ti1
+dwv,240.04
+ti1
+dwv,229.03
+ti1
+dwv,216.69
+ti1
+dwv,204.21
+ti1
+dwv,191.25
+ti1
+dwv,178.40
+ti1
+dwv,168.31
+ti1
+dwv,157.47
+ti1
+dwv,148.62
+ti1
+dwv,139.12
+ti1
+dwv,129.54
+ti1
+dwv,121.65
+ti1
+dwv,114.59
+ti1
+dwv,109.30
+ti1
+dwv,106.39
+ti1
+dwv,104.71
+ti1
+ti1
+dwv,106.41
+ti1
+dwv,109.22
+ti1
+dwv,113.62
+ti1
+dwv,118.31
+ti1
+dwv,124.34
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,205.67
+ti1
+dwv,221.25
+ti1
+dwv,235.02
+ti1
+dwv,247.47
+ti1
+dwv,258.37
+ti1
+dwv,267.42
+ti1
+dwv,272.60
+ti1
+dwv,272.00
+ti1
+dwv,267.91
+ti1
+dwv,260.38
+ti1
+dwv,251.10
+ti1
+dwv,241.32
+ti1
+dwv,230.96
+ti1
+dwv,217.34
+ti1
+dwv,204.99
+ti1
+dwv,191.24
+ti1
+dwv,178.58
+ti1
+dwv,164.79
+ti1
+dwv,153.07
+ti1
+dwv,141.06
+ti1
+dwv,129.86
+ti1
+dwv,119.79
+ti1
+dwv,111.13
+ti1
+dwv,103.53
+ti1
+dwv,96.95
+ti1
+dwv,89.42
+ti1
+dwv,85.22
+ti1
+dwv,80.54
+ti1
+dwv,76.85
+ti1
+dwv,74.41
+ti1
+dwv,72.12
+ti1
+dwv,71.21
+ti1
+ti1
+ti1
+dwv,72.13
+ti1
+dwv,74.22
+ti1
+dwv,76.95
+ti1
+dwv,80.65
+ti1
+dwv,85.36
+ti1
+dwv,90.60
+ti1
+dwv,92.36
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,191.27
+ti1
+dwv,205.03
+ti1
+dwv,218.89
+ti1
+dwv,230.87
+ti1
+dwv,241.63
+ti1
+dwv,249.83
+ti1
+dwv,255.42
+ti1
+dwv,257.98
+ti1
+dwv,257.33
+ti1
+dwv,252.87
+ti1
+dwv,245.90
+ti1
+dwv,237.78
+ti1
+dwv,227.14
+ti1
+dwv,214.67
+ti1
+dwv,202.31
+ti1
+dwv,188.68
+ti1
+dwv,175.96
+ti1
+dwv,163.25
+ti1
+dwv,151.43
+ti1
+dwv,139.79
+ti1
+dwv,130.40
+ti1
+dwv,118.92
+ti1
+dwv,110.88
+ti1
+dwv,101.92
+ti1
+dwv,94.45
+ti1
+dwv,88.13
+ti1
+dwv,83.19
+ti1
+dwv,79.11
+ti1
+dwv,74.60
+ti1
+dwv,71.86
+ti1
+dwv,68.77
+ti1
+dwv,66.57
+ti1
+dwv,65.24
+ti1
+dwv,64.41
+ti1
+ti1
+dwv,64.92
+ti1
+dwv,66.62
+ti1
+dwv,68.93
+ti1
+dwv,72.77
+ti1
+dwv,77.76
+ti1
+dwv,83.41
+ti1
+dwv,89.19
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,182.68
+ti1
+dwv,199.88
+ti1
+dwv,214.62
+ti1
+dwv,227.29
+ti1
+dwv,238.62
+ti1
+dwv,249.01
+ti1
+dwv,256.68
+ti1
+dwv,262.71
+ti1
+dwv,263.44
+ti1
+dwv,259.87
+ti1
+dwv,254.66
+ti1
+dwv,248.11
+ti1
+dwv,240.01
+ti1
+dwv,229.30
+ti1
+dwv,216.52
+ti1
+dwv,205.15
+ti1
+dwv,192.49
+ti1
+dwv,179.70
+ti1
+dwv,167.51
+ti1
+dwv,156.31
+ti1
+dwv,145.97
+ti1
+dwv,135.93
+ti1
+dwv,128.06
+ti1
+dwv,119.45
+ti1
+dwv,113.01
+ti1
+dwv,108.31
+ti1
+dwv,103.79
+ti1
+dwv,100.92
+ti1
+dwv,98.90
+ti1
+dwv,98.28
+ti1
+ti1
+dwv,100.12
+ti1
+dwv,102.38
+ti1
+dwv,106.07
+ti1
+dwv,111.06
+ti1
+dwv,117.00
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,202.42
+ti1
+dwv,217.46
+ti1
+dwv,232.83
+ti1
+dwv,245.05
+ti1
+dwv,256.39
+ti1
+dwv,265.28
+ti1
+dwv,271.80
+ti1
+ti1
+dwv,268.63
+ti1
+dwv,261.21
+ti1
+dwv,253.57
+ti1
+dwv,244.41
+ti1
+dwv,233.79
+ti1
+dwv,220.80
+ti1
+dwv,209.24
+ti1
+dwv,196.54
+ti1
+dwv,183.38
+ti1
+dwv,170.14
+ti1
+dwv,157.79
+ti1
+dwv,144.31
+ti1
+dwv,131.53
+ti1
+dwv,122.20
+ti1
+dwv,113.46
+ti1
+dwv,106.57
+ti1
+dwv,100.93
+ti1
+dwv,96.80
+ti1
+dwv,92.10
+ti1
+dwv,88.77
+ti1
+dwv,86.07
+ti1
+dwv,83.75
+ti1
+dwv,82.40
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,84.82
+ti1
+dwv,88.34
+ti1
+dwv,92.06
+ti1
+dwv,98.22
+ti1
+dwv,103.08
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,196.25
+ti1
+dwv,210.62
+ti1
+dwv,223.53
+ti1
+dwv,235.01
+ti1
+dwv,245.30
+ti1
+dwv,253.56
+ti1
+dwv,259.86
+ti1
+dwv,261.87
+ti1
+ti1
+dwv,257.71
+ti1
+dwv,251.10
+ti1
+dwv,242.25
+ti1
+dwv,232.00
+ti1
+dwv,219.62
+ti1
+dwv,207.54
+ti1
+dwv,194.54
+ti1
+dwv,182.85
+ti1
+dwv,170.49
+ti1
+dwv,158.24
+ti1
+dwv,147.54
+ti1
+dwv,137.40
+ti1
+dwv,129.81
+ti1
+dwv,121.07
+ti1
+dwv,114.39
+ti1
+dwv,109.32
+ti1
+dwv,103.67
+ti1
+dwv,99.51
+ti1
+dwv,96.53
+ti1
+dwv,94.67
+ti1
+dwv,93.79
+ti1
+ti1
+dwv,95.31
+ti1
+dwv,98.43
+ti1
+dwv,102.95
+ti1
+dwv,109.01
+ti1
+dwv,115.86
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,209.63
+ti1
+dwv,224.03
+ti1
+dwv,236.93
+ti1
+dwv,249.17
+ti1
+dwv,259.34
+ti1
+dwv,267.41
+ti1
+dwv,271.07
+ti1
+dwv,270.51
+ti1
+dwv,263.93
+ti1
+dwv,255.80
+ti1
+dwv,246.03
+ti1
+dwv,235.96
+ti1
+dwv,223.79
+ti1
+dwv,209.68
+ti1
+dwv,196.98
+ti1
+dwv,184.70
+ti1
+dwv,171.16
+ti1
+dwv,157.06
+ti1
+dwv,145.05
+ti1
+dwv,133.80
+ti1
+dwv,123.45
+ti1
+dwv,114.06
+ti1
+dwv,106.78
+ti1
+dwv,98.12
+ti1
+dwv,91.19
+ti1
+dwv,84.78
+ti1
+dwv,80.10
+ti1
+dwv,74.95
+ti1
+dwv,71.88
+ti1
+dwv,68.51
+ti1
+dwv,66.13
+ti1
+dwv,64.64
+ti1
+dwv,63.65
+ti1
+dwv,63.06
+ti1
+ti1
+dwv,64.29
+ti1
+dwv,66.41
+ti1
+dwv,68.95
+ti1
+dwv,73.12
+ti1
+dwv,78.00
+ti1
+dwv,83.67
+ti1
+dwv,85.55
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,187.86
+ti1
+dwv,202.65
+ti1
+dwv,216.23
+ti1
+dwv,228.24
+ti1
+dwv,239.81
+ti1
+dwv,248.77
+ti1
+dwv,252.97
+ti1
+dwv,254.72
+ti1
+ti1
+dwv,253.22
+ti1
+dwv,247.80
+ti1
+dwv,239.99
+ti1
+dwv,229.87
+ti1
+dwv,218.26
+ti1
+dwv,205.99
+ti1
+dwv,193.09
+ti1
+dwv,180.59
+ti1
+dwv,167.42
+ti1
+dwv,154.33
+ti1
+dwv,142.32
+ti1
+dwv,131.88
+ti1
+dwv,122.32
+ti1
+dwv,112.84
+ti1
+dwv,104.07
+ti1
+dwv,96.62
+ti1
+dwv,90.02
+ti1
+dwv,84.43
+ti1
+dwv,79.90
+ti1
+dwv,74.59
+ti1
+dwv,71.27
+ti1
+dwv,67.37
+ti1
+dwv,64.97
+ti1
+dwv,62.82
+ti1
+dwv,61.60
+ti1
+ti1
+ti1
+dwv,62.99
+ti1
+dwv,64.80
+ti1
+dwv,68.51
+ti1
+dwv,72.70
+ti1
+dwv,77.97
+ti1
+dwv,84.10
+ti1
+dwv,88.07
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+ti1
+dwv,184.25
+ti1
+dwv,199.56
+ti1
+dwv,212.97
+ti1
+dwv,226.37
+ti1
+dwv,237.23
+ti1
+dwv,247.66
+ti1
+dwv,254.97
+ti1
+dwv,259.77
+ti1
+dwv,261.89
+ti1
+dwv,260.39
+ti1
+dwv,255.67
+ti1
+dwv,248.49
+ti1
+dwv,238.75
+ti1
+dwv,228.34
+ti1
+dwv,215.95
+ti1
+dwv,201.71
+ti1
+dwv,187.12
+ti1
+dwv,174.33
+ti1
+dwv,162.05
+ti1
+dwv,151.79
+ti1
+dwv,142.67
+ti1
+dwv,134.03
+ti1
+dwv,126.03
+ti1
+dwv,118.64
+ti1
+dwv,112.00
+ti1
+dwv,107.16
+ti1
+dwv,103.71
+ti1
+dwv,100.06
+ti1
+dwv,98.59
+ti1
+dwv,97.68
+ti1
+ti1
--- /dev/null
+1 0
+2 214.59
+3 230.31
+4 242.64
+5 253.94
+6 264.33
+7 270.94
+8 273.52
+9 270.08
+10 263.19
+11 254.45
+12 244.91
+13 234.55
+14 222.49
+15 209.94
+16 197.17
+17 182.89
+18 169.76
+19 158.59
+20 145.37
+21 135.46
+22 124.77
+23 115.98
+24 108.77
+25 101.12
+26 94.45
+27 89.08
+28 84.63
+29 81.05
+30 78.93
+31 76.65
+32 75.59
+33 75.59
+34 75.59
+35 77.47
+36 80.17
+37 83.90
+38 88.56
+39 95.69
+40 97.48
+41 97.48
+42 97.48
+43 97.48
+44 97.48
+45 97.48
+46 97.48
+47 97.48
+48 203.08
+49 218.22
+50 229.37
+51 238.49
+52 247.43
+53 255.22
+54 261.31
+55 262.36
+56 260.66
+57 256.33
+58 249.34
+59 240.03
+60 228.55
+61 215.42
+62 203.37
+63 190.01
+64 177.81
+65 165.44
+66 152.92
+67 142.03
+68 132.91
+69 124.48
+70 116.45
+71 109.06
+72 103.27
+73 98.87
+74 94.95
+75 92.56
+76 90.47
+77 89.48
+78 89.48
+79 90.53
+80 93.07
+81 97.12
+82 101.82
+83 108.18
+84 109.73
+85 109.73
+86 109.73
+87 109.73
+88 109.73
+89 109.73
+90 109.73
+91 202.97
+92 217.38
+93 231.73
+94 243.11
+95 255.37
+96 264.12
+97 269.64
+98 270.98
+99 269.65
+100 264.55
+101 257.16
+102 246.01
+103 232.88
+104 219.85
+105 208.79
+106 197.00
+107 183.93
+108 172.00
+109 160.55
+110 150.59
+111 141.47
+112 133.02
+113 126.21
+114 120.64
+115 115.79
+116 111.62
+117 108.41
+118 106.41
+119 106.41
+120 106.41
+121 109.08
+122 113.23
+123 118.57
+124 122.57
+125 122.57
+126 122.57
+127 122.57
+128 122.57
+129 122.57
+130 122.57
+131 208.07
+132 224.14
+133 236.28
+134 248.12
+135 258.97
+136 267.74
+137 272.47
+138 271.52
+139 266.80
+140 258.61
+141 249.30
+142 239.19
+143 228.28
+144 215.79
+145 203.86
+146 190.08
+147 177.40
+148 163.81
+149 152.60
+150 141.33
+151 130.98
+152 121.98
+153 114.08
+154 106.61
+155 99.75
+156 93.10
+157 86.57
+158 80.62
+159 76.05
+160 71.52
+161 68.85
+162 67.46
+163 66.86
+164 67.51
+165 69.75
+166 72.85
+167 76.23
+168 82.85
+169 89.33
+170 93.39
+171 93.39
+172 93.39
+173 93.39
+174 93.39
+175 93.39
+176 93.39
+177 93.39
+178 188.37
+179 204.42
+180 217.16
+181 228.89
+182 238.83
+183 247.70
+184 253.59
+185 257.17
+186 257.17
+187 254.00
+188 248.24
+189 240.14
+190 229.42
+191 218.97
+192 205.09
+193 192.61
+194 179.74
+195 166.76
+196 155.36
+197 143.58
+198 131.40
+199 121.84
+200 112.46
+201 105.41
+202 97.15
+203 90.09
+204 84.79
+205 80.52
+206 75.58
+207 72.59
+208 69.39
+209 67.51
+210 66.42
+211 66.42
+212 66.42
+213 67.82
+214 69.76
+215 73.19
+216 77.35
+217 82.36
+218 87.82
+219 93.30
+220 93.30
+221 93.30
+222 93.30
+223 93.30
+224 93.30
+225 93.30
+226 93.30
+227 190.58
+228 203.43
+229 216.48
+230 228.89
+231 241.91
+232 251.60
+233 257.78
+234 262.18
+235 263.13
+236 260.91
+237 255.34
+238 247.17
+239 236.85
+240 225.24
+241 213.39
+242 201.46
+243 187.77
+244 175.31
+245 162.95
+246 152.55
+247 142.56
+248 132.94
+249 125.00
+250 117.69
+251 110.96
+252 105.02
+253 101.78
+254 98.48
+255 97.06
+256 96.50
+257 96.50
+258 98.48
+259 101.18
+260 104.56
+261 109.67
+262 115.86
+263 115.86
+264 115.86
+265 115.86
+266 115.86
+267 115.86
+268 115.86
+269 200.02
+270 217.51
+271 233.21
+272 245.72
+273 258.21
+274 267.24
+275 273.79
+276 273.20
+277 270.38
+278 260.76
+279 250.05
+280 241.32
+281 231.14
+282 219.83
+283 206.13
+284 193.24
+285 180.73
+286 167.82
+287 156.94
+288 144.13
+289 134.40
+290 125.23
+291 116.13
+292 107.34
+293 99.71
+294 94.11
+295 88.91
+296 84.51
+297 81.50
+298 78.66
+299 76.57
+300 75.82
+301 75.82
+302 76.88
+303 79.03
+304 82.12
+305 85.73
+306 91.05
+307 96.31
+308 96.31
+309 96.31
+310 96.31
+311 96.31
+312 96.31
+313 96.31
+314 96.31
+315 184.18
+316 201.10
+317 214.21
+318 226.18
+319 237.72
+320 247.57
+321 254.36
+322 258.34
+323 259.80
+324 257.76
+325 253.17
+326 246.51
+327 237.92
+328 227.09
+329 214.13
+330 202.20
+331 189.21
+332 177.65
+333 166.18
+334 154.03
+335 142.21
+336 131.51
+337 121.28
+338 111.80
+339 104.47
+340 98.80
+341 94.76
+342 91.81
+343 89.17
+344 88.00
+345 88.00
+346 88.00
+347 89.20
+348 91.17
+349 94.35
+350 99.00
+351 105.43
+352 109.34
+353 109.34
+354 109.34
+355 109.34
+356 109.34
+357 109.34
+358 109.34
+359 194.84
+360 212.05
+361 226.30
+362 239.03
+363 250.94
+364 259.73
+365 266.64
+366 269.67
+367 269.03
+368 265.03
+369 258.23
+370 249.32
+371 238.03
+372 226.20
+373 213.46
+374 200.53
+375 187.65
+376 174.89
+377 163.22
+378 152.47
+379 142.65
+380 133.97
+381 126.59
+382 120.52
+383 115.57
+384 111.49
+385 108.03
+386 106.01
+387 105.28
+388 105.28
+389 106.91
+390 109.73
+391 114.91
+392 120.66
+393 123.74
+394 123.74
+395 123.74
+396 123.74
+397 123.74
+398 123.74
+399 123.74
+400 211.57
+401 227.06
+402 240.57
+403 252.26
+404 262.67
+405 270.66
+406 273.40
+407 270.25
+408 263.76
+409 256.03
+410 246.87
+411 237.10
+412 225.11
+413 211.53
+414 197.77
+415 185.75
+416 173.00
+417 159.31
+418 147.18
+419 134.84
+420 125.07
+421 115.82
+422 107.33
+423 100.07
+424 93.55
+425 87.60
+426 81.75
+427 77.03
+428 73.39
+429 70.97
+430 67.94
+431 66.64
+432 65.80
+433 65.80
+434 66.85
+435 68.78
+436 71.47
+437 74.20
+438 78.68
+439 85.08
+440 87.47
+441 87.47
+442 87.47
+443 87.47
+444 87.47
+445 87.47
+446 87.47
+447 87.47
+448 185.81
+449 201.66
+450 215.07
+451 227.26
+452 238.00
+453 247.64
+454 255.03
+455 257.12
+456 256.17
+457 253.47
+458 248.93
+459 241.39
+460 231.45
+461 220.49
+462 208.48
+463 196.04
+464 182.73
+465 169.40
+466 157.24
+467 145.56
+468 133.54
+469 124.01
+470 114.55
+471 105.75
+472 98.32
+473 91.91
+474 86.08
+475 81.35
+476 77.78
+477 73.85
+478 71.12
+479 68.53
+480 67.09
+481 66.34
+482 66.34
+483 66.34
+484 67.92
+485 70.08
+486 73.78
+487 78.68
+488 84.33
+489 90.25
+490 90.25
+491 90.25
+492 90.25
+493 90.25
+494 90.25
+495 90.25
+496 90.25
+497 183.19
+498 198.96
+499 213.55
+500 225.91
+501 237.33
+502 246.66
+503 254.98
+504 259.46
+505 261.02
+506 260.02
+507 255.96
+508 249.08
+509 240.15
+510 229.51
+511 217.21
+512 205.06
+513 192.62
+514 177.43
+515 165.06
+516 152.36
+517 142.35
+518 134.58
+519 126.20
+520 119.86
+521 113.67
+522 108.20
+523 104.71
+524 100.83
+525 98.96
+526 98.38
+527 98.38
+528 100.29
+529 103.47
+530 107.73
+531 113.04
+532 118.90
+533 118.90
+534 118.90
+535 118.90
+536 118.90
+537 118.90
+538 118.90
+539 200.70
+540 217.77
+541 232.45
+542 244.28
+543 256.61
+544 265.93
+545 272.01
+546 272.01
+547 268.67
+548 260.53
+549 252.09
+550 243.72
+551 232.68
+552 220.49
+553 206.88
+554 193.98
+555 181.33
+556 168.61
+557 156.50
+558 145.54
+559 136.43
+560 125.95
+561 117.26
+562 109.81
+563 103.36
+564 97.15
+565 92.86
+566 89.02
+567 86.39
+568 84.44
+569 83.72
+570 83.72
+571 85.89
+572 88.39
+573 92.31
+574 96.00
+575 100.24
+576 102.55
+577 102.55
+578 102.55
+579 102.55
+580 102.55
+581 102.55
+582 102.55
+583 102.55
+584 197.15
+585 212.33
+586 225.48
+587 236.75
+588 247.52
+589 255.21
+590 260.74
+591 262.81
+592 262.09
+593 258.08
+594 250.83
+595 242.39
+596 230.86
+597 219.62
+598 206.80
+599 193.41
+600 180.60
+601 168.20
+602 157.77
+603 145.25
+604 136.23
+605 126.28
+606 118.10
+607 110.74
+608 105.29
+609 99.75
+610 95.61
+611 92.16
+612 89.93
+613 88.45
+614 88.45
+615 89.11
+616 90.87
+617 94.21
+618 98.16
+619 104.24
+620 108.98
+621 108.98
+622 108.98
+623 108.98
+624 108.98
+625 108.98
+626 108.98
+627 195.81
+628 211.95
+629 226.36
+630 240.61
+631 251.93
+632 259.13
+633 265.36
+634 269.71
+635 270.27
+636 266.44
+637 260.44
+638 251.94
+639 240.79
+640 228.95
+641 215.90
+642 203.25
+643 190.01
+644 177.92
+645 165.60
+646 155.49
+647 144.32
+648 136.07
+649 127.64
+650 120.28
+651 114.57
+652 109.99
+653 106.36
+654 104.49
+655 103.84
+656 103.84
+657 105.77
+658 107.83
+659 112.41
+660 117.71
+661 120.66
+662 120.66
+663 120.66
+664 120.66
+665 120.66
+666 120.66
+667 120.66
+668 210.13
+669 225.03
+670 238.76
+671 250.50
+672 261.18
+673 269.22
+674 274.18
+675 272.28
+676 266.66
+677 258.68
+678 249.88
+679 239.94
+680 227.14
+681 213.22
+682 197.58
+683 184.86
+684 172.52
+685 160.19
+686 149.20
+687 137.49
+688 127.86
+689 118.91
+690 110.49
+691 102.73
+692 96.33
+693 90.95
+694 86.38
+695 82.72
+696 79.65
+697 77.61
+698 75.70
+699 74.49
+700 74.49
+701 74.49
+702 76.48
+703 79.14
+704 82.84
+705 87.86
+706 92.69
+707 92.69
+708 92.69
+709 92.69
+710 92.69
+711 92.69
+712 92.69
+713 92.69
+714 181.33
+715 196.86
+716 210.98
+717 223.13
+718 233.90
+719 243.19
+720 250.57
+721 255.00
+722 256.36
+723 255.16
+724 250.15
+725 242.80
+726 233.82
+727 223.41
+728 210.81
+729 199.04
+730 187.39
+731 174.14
+732 162.62
+733 151.39
+734 139.59
+735 128.71
+736 119.17
+737 111.02
+738 103.91
+739 96.78
+740 91.56
+741 87.13
+742 83.22
+743 80.50
+744 76.83
+745 74.24
+746 70.80
+747 69.04
+748 67.12
+749 66.51
+750 66.51
+751 68.77
+752 72.19
+753 77.34
+754 84.04
+755 88.55
+756 88.55
+757 88.55
+758 88.55
+759 88.55
+760 88.55
+761 88.55
+762 88.55
+763 190.51
+764 207.14
+765 220.57
+766 232.51
+767 243.35
+768 252.41
+769 258.62
+770 262.18
+771 262.18
+772 259.10
+773 253.54
+774 245.44
+775 235.55
+776 223.43
+777 209.91
+778 197.52
+779 185.90
+780 172.13
+781 161.09
+782 150.58
+783 140.37
+784 130.27
+785 122.13
+786 114.99
+787 108.76
+788 104.67
+789 100.36
+790 97.61
+791 95.48
+792 94.83
+793 95.45
+794 97.15
+795 100.73
+796 105.10
+797 111.46
+798 118.27
+799 118.27
+800 118.27
+801 118.27
+802 118.27
+803 118.27
+804 118.27
+805 202.92
+806 220.25
+807 233.35
+808 243.48
+809 254.85
+810 265.75
+811 272.62
+812 272.62
+813 269.36
+814 261.82
+815 252.85
+816 244.08
+817 232.96
+818 219.59
+819 207.32
+820 193.87
+821 181.77
+822 168.60
+823 155.76
+824 144.03
+825 134.07
+826 123.46
+827 114.47
+828 107.64
+829 100.46
+830 94.53
+831 89.28
+832 84.59
+833 80.96
+834 78.54
+835 76.28
+836 75.51
+837 75.51
+838 76.55
+839 78.55
+840 81.57
+841 85.18
+842 90.61
+843 96.01
+844 96.01
+845 96.01
+846 96.01
+847 96.01
+848 96.01
+849 96.01
+850 96.01
+851 184.51
+852 201.57
+853 216.33
+854 228.69
+855 239.90
+856 250.41
+857 257.91
+858 262.29
+859 263.41
+860 261.70
+861 256.75
+862 246.82
+863 236.35
+864 225.17
+865 212.90
+866 201.61
+867 188.42
+868 175.92
+869 163.70
+870 153.18
+871 142.89
+872 132.95
+873 125.18
+874 117.61
+875 110.36
+876 104.56
+877 100.13
+878 96.64
+879 93.52
+880 91.91
+881 91.91
+882 91.91
+883 93.84
+884 97.13
+885 101.08
+886 107.19
+887 111.89
+888 111.89
+889 111.89
+890 111.89
+891 111.89
+892 111.89
+893 111.89
+894 195.89
+895 212.65
+896 226.60
+897 239.28
+898 251.28
+899 259.92
+900 266.03
+901 269.76
+902 269.76
+903 265.55
+904 258.92
+905 250.42
+906 240.04
+907 229.03
+908 216.69
+909 204.21
+910 191.25
+911 178.40
+912 168.31
+913 157.47
+914 148.62
+915 139.12
+916 129.54
+917 121.65
+918 114.59
+919 109.30
+920 106.39
+921 104.71
+922 104.71
+923 106.41
+924 109.22
+925 113.62
+926 118.31
+927 124.34
+928 124.34
+929 124.34
+930 124.34
+931 124.34
+932 124.34
+933 124.34
+934 205.67
+935 221.25
+936 235.02
+937 247.47
+938 258.37
+939 267.42
+940 272.60
+941 272.00
+942 267.91
+943 260.38
+944 251.10
+945 241.32
+946 230.96
+947 217.34
+948 204.99
+949 191.24
+950 178.58
+951 164.79
+952 153.07
+953 141.06
+954 129.86
+955 119.79
+956 111.13
+957 103.53
+958 96.95
+959 89.42
+960 85.22
+961 80.54
+962 76.85
+963 74.41
+964 72.12
+965 71.21
+966 71.21
+967 71.21
+968 72.13
+969 74.22
+970 76.95
+971 80.65
+972 85.36
+973 90.60
+974 92.36
+975 92.36
+976 92.36
+977 92.36
+978 92.36
+979 92.36
+980 92.36
+981 92.36
+982 191.27
+983 205.03
+984 218.89
+985 230.87
+986 241.63
+987 249.83
+988 255.42
+989 257.98
+990 257.33
+991 252.87
+992 245.90
+993 237.78
+994 227.14
+995 214.67
+996 202.31
+997 188.68
+998 175.96
+999 163.25
+1000 151.43
+1001 139.79
+1002 130.40
+1003 118.92
+1004 110.88
+1005 101.92
+1006 94.45
+1007 88.13
+1008 83.19
+1009 79.11
+1010 74.60
+1011 71.86
+1012 68.77
+1013 66.57
+1014 65.24
+1015 64.41
+1016 64.41
+1017 64.92
+1018 66.62
+1019 68.93
+1020 72.77
+1021 77.76
+1022 83.41
+1023 89.19
+1024 89.19
+1025 89.19
+1026 89.19
+1027 89.19
+1028 89.19
+1029 89.19
+1030 89.19
+1031 182.68
+1032 199.88
+1033 214.62
+1034 227.29
+1035 238.62
+1036 249.01
+1037 256.68
+1038 262.71
+1039 263.44
+1040 259.87
+1041 254.66
+1042 248.11
+1043 240.01
+1044 229.30
+1045 216.52
+1046 205.15
+1047 192.49
+1048 179.70
+1049 167.51
+1050 156.31
+1051 145.97
+1052 135.93
+1053 128.06
+1054 119.45
+1055 113.01
+1056 108.31
+1057 103.79
+1058 100.92
+1059 98.90
+1060 98.28
+1061 98.28
+1062 100.12
+1063 102.38
+1064 106.07
+1065 111.06
+1066 117.00
+1067 117.00
+1068 117.00
+1069 117.00
+1070 117.00
+1071 117.00
+1072 117.00
+1073 202.42
+1074 217.46
+1075 232.83
+1076 245.05
+1077 256.39
+1078 265.28
+1079 271.80
+1080 271.80
+1081 268.63
+1082 261.21
+1083 253.57
+1084 244.41
+1085 233.79
+1086 220.80
+1087 209.24
+1088 196.54
+1089 183.38
+1090 170.14
+1091 157.79
+1092 144.31
+1093 131.53
+1094 122.20
+1095 113.46
+1096 106.57
+1097 100.93
+1098 96.80
+1099 92.10
+1100 88.77
+1101 86.07
+1102 83.75
+1103 82.40
+1104 82.40
+1105 82.40
+1106 82.40
+1107 82.40
+1108 84.82
+1109 88.34
+1110 92.06
+1111 98.22
+1112 103.08
+1113 103.08
+1114 103.08
+1115 103.08
+1116 103.08
+1117 103.08
+1118 196.25
+1119 210.62
+1120 223.53
+1121 235.01
+1122 245.30
+1123 253.56
+1124 259.86
+1125 261.87
+1126 261.87
+1127 257.71
+1128 251.10
+1129 242.25
+1130 232.00
+1131 219.62
+1132 207.54
+1133 194.54
+1134 182.85
+1135 170.49
+1136 158.24
+1137 147.54
+1138 137.40
+1139 129.81
+1140 121.07
+1141 114.39
+1142 109.32
+1143 103.67
+1144 99.51
+1145 96.53
+1146 94.67
+1147 93.79
+1148 93.79
+1149 95.31
+1150 98.43
+1151 102.95
+1152 109.01
+1153 115.86
+1154 115.86
+1155 115.86
+1156 115.86
+1157 115.86
+1158 115.86
+1159 115.86
+1160 115.86
+1161 209.63
+1162 224.03
+1163 236.93
+1164 249.17
+1165 259.34
+1166 267.41
+1167 271.07
+1168 270.51
+1169 263.93
+1170 255.80
+1171 246.03
+1172 235.96
+1173 223.79
+1174 209.68
+1175 196.98
+1176 184.70
+1177 171.16
+1178 157.06
+1179 145.05
+1180 133.80
+1181 123.45
+1182 114.06
+1183 106.78
+1184 98.12
+1185 91.19
+1186 84.78
+1187 80.10
+1188 74.95
+1189 71.88
+1190 68.51
+1191 66.13
+1192 64.64
+1193 63.65
+1194 63.06
+1195 63.06
+1196 64.29
+1197 66.41
+1198 68.95
+1199 73.12
+1200 78.00
+1201 83.67
+1202 85.55
+1203 85.55
+1204 85.55
+1205 85.55
+1206 85.55
+1207 85.55
+1208 85.55
+1209 85.55
+1210 187.86
+1211 202.65
+1212 216.23
+1213 228.24
+1214 239.81
+1215 248.77
+1216 252.97
+1217 254.72
+1218 254.72
+1219 253.22
+1220 247.80
+1221 239.99
+1222 229.87
+1223 218.26
+1224 205.99
+1225 193.09
+1226 180.59
+1227 167.42
+1228 154.33
+1229 142.32
+1230 131.88
+1231 122.32
+1232 112.84
+1233 104.07
+1234 96.62
+1235 90.02
+1236 84.43
+1237 79.90
+1238 74.59
+1239 71.27
+1240 67.37
+1241 64.97
+1242 62.82
+1243 61.60
+1244 61.60
+1245 61.60
+1246 62.99
+1247 64.80
+1248 68.51
+1249 72.70
+1250 77.97
+1251 84.10
+1252 88.07
+1253 88.07
+1254 88.07
+1255 88.07
+1256 88.07
+1257 88.07
+1258 88.07
+1259 88.07
+1260 184.25
+1261 199.56
+1262 212.97
+1263 226.37
+1264 237.23
+1265 247.66
+1266 254.97
+1267 259.77
+1268 261.89
+1269 260.39
+1270 255.67
+1271 248.49
+1272 238.75
+1273 228.34
+1274 215.95
+1275 201.71
+1276 187.12
+1277 174.33
+1278 162.05
+1279 151.79
+1280 142.67
+1281 134.03
+1282 126.03
+1283 118.64
+1284 112.00
+1285 107.16
+1286 103.71
+1287 100.06
+1288 98.59
+1289 97.68
+1290 97.68
--- /dev/null
+#Date: Tue, 18 May 1999 12:48:07 -0500 (CDT)
+#From: Darrel Hankerson <hankedr@dms.auburn.edu>
+#To: arnold@gnu.org
+#Subject: [christopher.procter@bt.com: RE: Getline bug in Gawk 3.0.3]
+#
+#Here's a reply that came directly to me. --darrel
+#
+#
+#From: christopher.procter@bt.com
+#To: hankedr@dms.auburn.edu
+#Subject: RE: Getline bug in Gawk 3.0.3
+#Date: Tue, 18 May 1999 18:42:28 +0100
+#
+#Sorry that was me getting carried away and cut and pasting the wrong thing
+#into my email
+#
+#The real problem seems to be that :
+#BEGIN {
+#for (i=1;i<10;i++){
+# while((getline < "hello.txt")>0){
+# print $0
+# }
+# close("hello.txt")
+# }
+#}
+#works (printing the contents of hello.txt 9 times), where as:-
+#
+#END{
+#for (i=1;i<10;i++){
+# while((getline < "hello.txt")>0){
+# print $0
+# }
+# close("hello.txt")
+# }
+#}
+#
+#doesn't, (it prints out hello.txt once followed by the iteration numbers
+#from 1 to 9).
+#The only difference is that one is in the BEGIN block and one in the END
+#block.
+#
+#Sorry about the first post, I'm not a bad awk programmer, just a tired one
+#:)
+#
+#chris
+#
+#> -----Original Message-----
+#> From: Darrel Hankerson [SMTP:hankedr@dms.auburn.edu]
+#> Sent: 18 May 1999 18:28
+#> To: christopher.procter@bt.com
+#> Subject: Re: Getline bug in Gawk 3.0.3
+#>
+#> Could you clarify? Your first script uses an apparently undefined
+#> variable f.
+#>
+#>
+#> christopher.procter@bt.com writes:
+#>
+#> BEGIN {
+#> for (i=1;i<10;i++){
+#> while((getline < "hello.txt")>0){
+#> print $0
+#> }
+#> close(f)
+#> }
+#> }
+#>
+#> refuses to close the file and so prints the contents of hello.txt just
+#> once.
+#> However:-
+#>
+#> BEGIN {
+#> f="hello.txt"
+#> for (i=1;i<10;i++){
+#> while((getline < f)>0){
+#> print $0
+#> }
+#> close(f)
+#> }
+#> }
+#>
+#> works as advertised (printing the contents of hello.txt 9 times)
+#> It seems like a bug in the close statement.
+#>
+#> --
+#> --Darrel Hankerson hankedr@mail.auburn.edu
+#
+
+# srcdir is assigned on command line --- ADR
+END {
+ f = srcdir "/redfilnm.in"
+ for (i = 1; i < 10; i++){
+ while((getline < f) > 0){
+ print $0
+ }
+ close(f)
+ }
+}
--- /dev/null
+hello, world
--- /dev/null
+hello, world
+hello, world
+hello, world
+hello, world
+hello, world
+hello, world
+hello, world
+hello, world
+hello, world
--- /dev/null
+BEGIN { print exp(0), exp(1000000), exp(0.5) }
--- /dev/null
+1 gawk: reg/exp.awk:1: warning: exp argument 1e+06 is out of range
+Inf 1.64872
--- /dev/null
+BEGIN { print log(0), log(-1), log(100) }
--- /dev/null
+log: SING error
+-Inf gawk: reg/log.awk:1: warning: log called with negative argument -1
+log: DOMAIN error
+NaN 4.60517
--- /dev/null
+{ $0 ^= 3 ; print $1}
--- /dev/null
+BEGIN { print dummy(1) }
--- /dev/null
+gawk: reg/func.awk:1: fatal: function `dummy' not defined
--- /dev/null
+function dummy() { ; }
+BEGIN { print dummy (1) }
--- /dev/null
+gawk: reg/func2.awk:2: fatal: function `dummy' called with space between name and `(',
+or used in other expression context
--- /dev/null
+gawk: reg/func2.awk:2: fatal: function `dummy' called with space between name and `(',
+or used as a variable or an array
--- /dev/null
+#Date: Sat, 8 May 1999 17:42:20 +0200
+#From: Iva Cabric <ivac@fly.srk.fer.hr>
+#To: bug-gnu-utils@gnu.org
+#Cc: arnold@gnu.org
+#Subject: Problem in gawk with match
+#
+#Hello,
+#
+#gawk reports fatal error in match when first character in regexp is "=" :
+#
+#$ gawk '{ where = match($0, /=a/); print where}'
+#gawk: cmd. line:1: { where = match($0, /=a/); print where}
+#gawk: cmd. line:1: ^ parse error
+#gawk: cmd. line:1: fatal: match() cannot have 0 arguments
+#
+#Using "\=" instead "=" works without problems :
+#
+#$ gawk '{ where = match($0, /\=a/); print where}'
+#sdgfa
+#0
+#asdfds=a
+#7
+#
+#Other versions of awk have no problems with "/=/" (except oawk on SunOS).
+#
+#--
+# @
+#
+{ where = match($0, /=a/); print where}
--- /dev/null
+sdgfa
+asdfds=a
--- /dev/null
+#! /bin/sh
+
+case "$AWK" in
+"") AWK=../gawk ;;
+esac
+#AWK=${AWK:-../gawk}
+
+for i in reg/*.awk
+do
+ it=`basename $i .awk`
+ $AWK -f $i <reg/$it.in >reg/$it.out 2>&1
+ if diff reg/$it.out reg/$it.good
+ then
+ rm -f reg/$it.out
+ else
+ echo "regtest: $it fails"
+ fi
+done
--- /dev/null
+# The full test will only work in a Swedish localte
+# Try things that should work across the board
+# BEGIN {
+# s = "så är det"
+# print match(s,/\yså\y/), s ~ /\yså\y/, "å" ~ /\w/
+# }
+BEGIN {
+ printf "\"å\" = %c\n", "å"
+ printf "\"ä\" = %c\n", "ä"
+ s = "så är det"
+ printf "s = \"%s\"\n", s
+ printf "match(s,/\\yså/) = %d\n", match(s, /\yså/)
+# printf "match(s,/så\\y/) = %d\n", match(s, /så\y/)
+# printf "match(s,/\\yså\\y/) = %d\n", match(s, /\yså\y/)
+ printf "s ~ /å/ = %d\n", s ~ /å/
+ printf "s ~ /så/ = %d\n", s ~ /så/
+ printf "s ~ /\\yså/ = %d\n", s ~ /\yså/
+# printf "s ~ /så\\y/ = %d\n", s ~ /så\y/
+# printf "s ~ /\\yså\\y/ = %d\n", s ~ /\yså\y/
+# printf "\"å\" ~ /\\w/ = %d\n", "å" ~ /\w/
+# printf "\"ä\" ~ /\\w/ = %d\n", "ä" ~ /\w/
+# printf "\"å\" ~ /\\yä\\y/ = %d\n", "å" ~ /\yå\y/
+# printf "\"ä\" ~ /\\yä\\y/ = %d\n", "ä" ~ /\yä\y/
+# printf "\"å\" ~ /[[:alpha:]]/ = %d\n", "å" ~ /[[:alpha:]]/
+# printf "\"ä\" ~ /[[:alpha:]]/ = %d\n", "ä" ~ /[[:alpha:]]/
+}
--- /dev/null
+"å" = å
+"ä" = ä
+s = "så är det"
+match(s,/\yså/) = 1
+s ~ /å/ = 1
+s ~ /så/ = 1
+s ~ /\yså/ = 1
--- /dev/null
+{
+ if ($1 !~ /^+[2-9]/)
+ print "gawk is broken"
+ else
+ print "gawk is ok"
+}
--- /dev/null
++44 123 456
--- /dev/null
+gawk is ok
--- /dev/null
+{ print match($0, /a{3}/) }
--- /dev/null
+match this: aaa
--- /dev/null
+{
+ gsub(/x/, " ")
+ $0 = $0
+ print $1
+ print $0
+ print $1, $2, $3
+}
--- /dev/null
+1
+1 a b c 2
+1 a b
--- /dev/null
+{ FS = ":"; $0 = $0; print $2 }
--- /dev/null
+a:b:c d:e:f
--- /dev/null
+BEGIN { RS = "" }
+{ print $1, $2 }
--- /dev/null
+
+
+a
+b
+
+
+c d
+
+
+
+e
+
+
+
+
--- /dev/null
+a b
+c d
+e
--- /dev/null
+BEGIN { RS = "" }
+{ print }
--- /dev/null
+
+This is...
+the first record.
--- /dev/null
+This is...
+the first record.
--- /dev/null
+# From arnold@f7.net Wed Dec 15 11:32:46 2004
+# Date: Tue, 14 Dec 2004 14:48:58 +0100
+# From: Stepan Kasal <kasal@ucw.cz>
+# Subject: gawk bug with RS="^..."
+# To: bug-gawk@gnu.org
+# Message-id: <20041214134858.GA15490@matsrv.math.cas.cz>
+#
+# Hello,
+# I've noticed a problem with "^" in RS in gawk. In most cases, it seems
+# to match only the beginning of the file. But in fact it matches the
+# beginning of gawk's internal buffer.
+#
+# Observe the following example:
+#
+# $ gawk 'BEGIN{for(i=1;i<=100;i++) print "Axxxxxx"}' >file
+# $ gawk 'BEGIN{RS="^A"} END{print NR}' file
+# 2
+# $ gawk 'BEGIN{RS="^Ax*\n"} END{print NR}' file
+# 100
+# $ head file | gawk 'BEGIN{RS="^Ax*\n"} END{print NR}'
+# 10
+# $
+#
+# I think this calls for some clarification/fix. But I don't have any
+# fixed opinion how the solution should look like.
+#
+# Have a nice day,
+# Stepan Kasal
+#
+# PS: See also the discussion of the issue in the comp.lang.awk newsgroup.
+BEGIN { RS = "^A" }
+END { print NR }
--- /dev/null
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
+Axxxxxx
--- /dev/null
+BEGIN { RS = "^Ax*\n" }
+END { print NR }
--- /dev/null
+BEGIN {
+ RS = ""
+ FS = ":"
+ s = "a:b\nc:d"
+ print split(s,a)
+ print length(a[2])
+}
--- /dev/null
+BEGIN {
+ RS = ""
+ FS = "\\"
+ $0 = "a\\b"
+ print $1
+}
--- /dev/null
+# From spcecdt@armory.com Tue Apr 15 17:35:01 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (aahz [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h3FEYA6o001541
+# for <arnold@localhost>; Tue, 15 Apr 2003 17:35:01 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Tue, 15 Apr 2003 17:35:01 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Tue Apr 15 17:38:46 2003)
+# X-From_: spcecdt@armory.com Tue Apr 15 11:09:12 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h3F88uC19825 for <arobbins@actcom.co.il>;
+# Tue, 15 Apr 2003 11:09:04 +0300 (EET DST)
+# (rfc931-sender: smtp.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h3F8CgQ7019081
+# for <arobbins@actcom.co.il>; Tue, 15 Apr 2003 11:12:47 +0300
+# Received: from fencepost.gnu.org (fencepost.gnu.org [199.232.76.164])
+# by f7.net (8.11.7/8.11.6) with ESMTP id h3F88oW23381
+# for <arnold@skeeve.com>; Tue, 15 Apr 2003 04:08:50 -0400
+# Received: from monty-python.gnu.org ([199.232.76.173])
+# by fencepost.gnu.org with esmtp (Exim 4.10)
+# id 195LUo-0001cv-00
+# for bug-gawk@gnu.org; Tue, 15 Apr 2003 04:08:50 -0400
+# Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13)
+# id 195LUh-0006n0-00
+# for bug-gawk@gnu.org; Tue, 15 Apr 2003 04:08:44 -0400
+# Received: from deepthought.armory.com ([192.122.209.42] helo=armory.com)
+# by monty-python.gnu.org with smtp (Exim 4.10.13)
+# id 195LUC-0006JM-00
+# for bug-gawk@gnu.org; Tue, 15 Apr 2003 04:08:13 -0400
+# Date: Tue, 15 Apr 2003 01:08:11 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: bug-gawk@gnu.org
+# Subject: gawk 3.1.2 fatal bug
+# Message-ID: <20030415080811.GA14963@armory.com>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-Spam-Status: No, hits=-7.9 required=5.0
+# tests=SIGNATURE_SHORT_DENSE,SPAM_PHRASE_01_02,USER_AGENT,
+# USER_AGENT_MUTT
+# version=2.41
+# X-Spam-Level:
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# This program:
+#
+# BEGIN { RS = ""; "/bin/echo -n x" | getline }
+#
+# fails in exactly the same way under SCO OpenServer 5.0.6a using gawk 3.1.2
+# built with gcc 2.95.3 and linux using gawk 3.1.2 built with gcc 3.2.2:
+#
+# gawk: gawktest:1: fatal error: internal error
+# Abort
+#
+# The same program does not fail with gawk 3.1.1.
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
+#
+BEGIN {
+ RS = ""
+ "echo x | tr -d '\\12'" | getline
+}
--- /dev/null
+# From spcecdt@armory.com Mon May 5 14:37:09 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h45B1GvT031993
+# for <arnold@localhost>; Mon, 5 May 2003 14:37:09 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Mon, 05 May 2003 14:37:09 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Mon May 5 14:35:11 2003)
+# X-From_: spcecdt@armory.com Mon May 5 12:20:20 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h459KC529186 for <arobbins@actcom.co.il>;
+# Mon, 5 May 2003 12:20:15 +0300 (EET DST)
+# (rfc931-sender: smtp.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h459LMfl025854
+# for <arobbins@actcom.co.il>; Mon, 5 May 2003 12:21:24 +0300
+# Received: from armory.com (deepthought.armory.com [192.122.209.42])
+# by f7.net (8.11.7/8.11.6) with SMTP id h459K9I26841
+# for <arnold@skeeve.com>; Mon, 5 May 2003 05:20:09 -0400
+# Date: Mon, 5 May 2003 02:20:08 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: Aharon Robbins <arnold@skeeve.com>
+# Subject: Re: gawk 3.1.2b now available
+# Message-ID: <20030505092008.GA15970@armory.com>
+# References: <200305041149.h44BnLcm005484@localhost.localdomain>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# In-Reply-To: <200305041149.h44BnLcm005484@localhost.localdomain>
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# This is a curious one:
+#
+# gawk-3.1.2b 'BEGIN {
+# while (("echo" | getline) == 1)
+# ;
+# RS = ""
+# "echo \"a\n\nb\"" | getline y
+# print x
+# }' | hd
+#
+# The output is:
+#
+# 0000 00 13 0a ...
+# 0003
+#
+# (the uninitialized variable 'x' is somehow getting the value <null><control-S>)
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
+BEGIN {
+ while (("echo" | getline) == 1)
+ ;
+ RS = ""
+ "echo \"a\n\nb\"" | getline y
+ printf "y = <%s>\n", y # ADR
+ printf "x = <%s>\n", x # ADR
+}
--- /dev/null
+y = <a>
+x = <>
--- /dev/null
+# From spcecdt@armory.com Tue May 6 13:42:34 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (aahz [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h46AgG53003519
+# for <arnold@localhost>; Tue, 6 May 2003 13:42:34 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Tue, 06 May 2003 13:42:34 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Tue May 6 13:48:46 2003)
+# X-From_: spcecdt@armory.com Tue May 6 13:26:09 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h46AQ6520133 for <arobbins@actcom.co.il>;
+# Tue, 6 May 2003 13:26:07 +0300 (EET DST)
+# (rfc931-sender: lmail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h46ARSfl010998
+# for <arobbins@actcom.co.il>; Tue, 6 May 2003 13:27:31 +0300
+# Received: from armory.com (deepthought.armory.com [192.122.209.42])
+# by f7.net (8.11.7/8.11.6) with SMTP id h46AQ1I18183
+# for <arnold@skeeve.com>; Tue, 6 May 2003 06:26:01 -0400
+# Date: Tue, 6 May 2003 03:25:59 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: Aharon Robbins <arnold@skeeve.com>
+# Subject: Re: gawk 3.1.2b now available
+# Message-ID: <20030506102559.GA16105@armory.com>
+# References: <200305051157.h45Bv4XO003106@localhost.localdomain>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# In-Reply-To: <200305051157.h45Bv4XO003106@localhost.localdomain>
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: RO
+#
+# The patch fixed the previous case, but here's another one - this prints
+# <null><control-S>:
+#
+# BEGIN {
+# RS = ""
+# "echo 'foo\n\nbaz'" | getline
+# "echo 'foo\n\nbaz'" | getline
+# "echo 'bar\n\nbaz'" | getline
+# print x
+# }
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
+BEGIN {
+ RS = ""
+ "echo 'foo\n\nbaz'" | getline ; print
+ "echo 'foo\n\nbaz'" | getline ; print
+ "echo 'bar\n\nbaz'" | getline ; print
+ printf "x = <%s>\n", x
+}
--- /dev/null
+foo
+baz
+bar
+x = <>
--- /dev/null
+# Wed Jul 14 16:02:45 IDT 2004
+# Test case from John Haque mary1john8@earthlink.net
+
+BEGIN { RS = "XYZ" }
+
+{ print }
--- /dev/null
+ABCD
\ No newline at end of file
--- /dev/null
+BEGIN { RS = "" }
+{ printf("<%s>\n", $0) }
--- /dev/null
+< a b
+c d>
--- /dev/null
+BEGIN{
+ sub(/x/,"",a)
+ a[1]
+}
--- /dev/null
+gawk: scalar.awk:3: fatal: attempt to use scalar `a' as array
+EXIT CODE: 2
--- /dev/null
+BEGIN { j = 4; for (i in j) print j[i] }
--- /dev/null
+gawk: sclforin.awk:1: fatal: attempt to use scalar `j' as array
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ j = 4
+ if ("foo" in j)
+ print "ouch"
+ else
+ print "ok"
+}
--- /dev/null
+gawk: sclifin.awk:7: fatal: attempt to use scalar `j' as array
+EXIT CODE: 2
--- /dev/null
+function foo()
+{
+ print "foo"
+}
+
+function bar(A, Z, q)
+{
+ print "bar"
+}
+
+function baz(C, D)
+{
+ print "baz"
+}
+
+BEGIN {
+ A = C = D = Z = y = 1
+ foo()
+ bar()
+ baz()
+}
--- /dev/null
+gawk: shadow.awk:22: warning: function `bar': parameter `A' shadows global variable
+gawk: shadow.awk:22: warning: function `bar': parameter `Z' shadows global variable
+gawk: shadow.awk:22: warning: function `baz': parameter `C' shadows global variable
+gawk: shadow.awk:22: warning: function `baz': parameter `D' shadows global variable
+foo
+bar
+baz
--- /dev/null
+BEGIN{
+ a[1] = "barz";
+ a[2] = "blattt";
+ a[3] = "Zebra";
+ a[4] = 1234;
+
+ testit1(a)
+
+ delete a
+
+ a[1] = "barz";
+ a[2] = "blattt";
+ a[3] = "Zebra";
+ a[4] = 1234;
+
+ n = asort(a, b);
+
+ print "N = ", n;
+
+ for(i=1; i <= n; i++)
+ print i, a[i], b[i];
+}
+
+function testit1(a, count, j)
+{
+ print "start testit"
+ count = asort(a)
+ for (j = 1; j <= count; j++)
+ print j, a[j]
+ print "end testit"
+}
--- /dev/null
+start testit
+1 1234
+2 Zebra
+3 barz
+4 blattt
+end testit
+N = 4
+1 barz 1234
+2 blattt Zebra
+3 Zebra barz
+4 1234 blattt
--- /dev/null
+BEGIN { print asort(a) }
--- /dev/null
+gawk: fatal: can't open source file ` ' for reading (No such file or directory)
+EXIT CODE: 2
--- /dev/null
+BEGIN {
+ for (idx = 1; idx < ARGC; idx++)
+ split(ARGV[idx], temp, ".");
+ }
+ {
+ print $0;
+ }
--- /dev/null
+BEGIN {
+ for (idx = 1; idx < ARGC; idx++)
+ split(ARGV[idx], temp, ".");
+ }
+ {
+ print $0;
+ }
--- /dev/null
+BEGIN {
+ for (idx = 1; idx < ARGC; idx++)
+ split(ARGV[idx], temp, ".");
+ }
+ {
+ print $0;
+ }
--- /dev/null
+BEGIN {
+ a[1] = "elephantie"
+ a[2] = "e"
+ print split(a[1],a,a[2]), a[2], a[3], split(a[2],a,a[2])
+}
--- /dev/null
+4 l phanti 2
--- /dev/null
+BEGIN {
+ data = "abc:easy:as:one:two:three"
+ FS = ":"
+ FIELDWIDTHS = "3 1 4 1 2 1 3 1 3 1 5"
+ n = split(data, a)
+ printf "n = %d, a[3] = %s\n", n, a[3]
+}
--- /dev/null
+n = 6, a[3] = as
--- /dev/null
+{
+ sep = "=+"
+ n = split($0, a, sep)
+ print n
+}
--- /dev/null
+Here===Is=Some=====Data
--- /dev/null
+BEGIN {
+ str = "a b\t\tc d"
+ n = split(str, a, " ")
+ print n
+ m = split(str, b, / /)
+ print m
+}
--- /dev/null
+{ print sprintf("%c", $1), $1 }
--- /dev/null
+65
+66
+foo
--- /dev/null
+A 65
+B 66
+f foo
--- /dev/null
+
+function f1(b) { b = b "c"; print f(b); }
+
+function f(a) { a = a "b"; return a; }
+
+BEGIN { A = "a"; f1(A); }
--- /dev/null
+# strftime.awk ; test the strftime code
+#
+# input is the output of `date', see Makefile.in
+#
+# The mucking about with $0 and $N is to avoid problems
+# on cygwin, where the timezone field is empty and there
+# are two consecutive blanks.
+
+# Additional mucking about to lop off the seconds field;
+# helps decrease chance of difference due to a second boundary
+
+{
+ $3 = sprintf("%02d", $3 + 0)
+ $4 = substr($4, 1, 5)
+ print > "strftime.ok"
+ $0 = strftime("%a %b %d %H:%M %Z %Y")
+ $NF = $NF
+ print > OUTPUT
+}
--- /dev/null
+# test file from Paul Eggert, eggert@twinsun.com
+# modified for portability (%c doesn't cut it)
+
+BEGIN {
+ BUFSIZ = 1024
+ simpleformat = format = "%m/%d/%y %H:%M:%S\n"
+ clen = length(strftime(format, 0))
+ for (i = 1; i < BUFSIZ / clen + 1; i++)
+ format = format simpleformat
+ printf "%s", strftime(format, 0)
+}
--- /dev/null
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
+01/01/70 00:00:00
--- /dev/null
+{
+ x = "0x" $1 ; print x, x + 0
+ for (i=1; i<=NF; i++)
+ if ($i) print $i, "is not zero"
+}
--- /dev/null
+345 0 00 0e0 0E1 00E0 000e-5 .0e+0
--- /dev/null
+0x345 0
+345 is not zero
--- /dev/null
+BEGIN {
+ print strtonum("0x13")
+ print strtonum("013")
+ print strtonum("13")
+ print strtonum(13)
+}
--- /dev/null
+19
+11
+13
+13
--- /dev/null
+{ sub(/[a-z]/, "&") ; print }
--- /dev/null
+BEGIN { SUBSEP = 10; a[1, 1] = 100 ; print a[1 SUBSEP 1] }
--- /dev/null
+BEGIN {
+ i = 2
+ a[i] = 5
+ a[i] /= 2
+ printf "a[%s] = %f\n", i, a[i]
+}
--- /dev/null
+a[2] = 2.500000
--- /dev/null
+BEGIN {
+ x = "A"
+ printf("%-39s\n", substr(x,1,39))
+ print substr("abcdef", 0, 2)
+ print substr("abcdef", 2.3, 2)
+ print substr("abcdef", -1, 2)
+ print substr("abcdef", 1, 0)
+ print substr("abcdef", 1, -3)
+ print substr("abcdef", 1, 2.3)
+ print substr("", 1, 2)
+ print substr("abcdef", 5, 5)
+ print substr("abcdef", 7, 2)
+ exit (0)
+}
--- /dev/null
+A
+ab
+bc
+ab
+
+
+ab
+
+ef
+
--- /dev/null
+{
+ if ((getline tmp) > 0) {
+ print tmp
+ print
+ } else
+ print
+}
--- /dev/null
+This directory contains some examples/test-cases for different
+features of gawk - mostly not present in an old awk. Some are from
+"The GAWK Manual", some are original, and some are mixture of the two.
+Read header comments before attempting to use. Have fun and remember
+that program which consists only of BEGIN block does not need an input
+file.
+
+ --mj
+
--- /dev/null
+features of gawk - mostly not present in an old awk. Some are from
+This directory contains some examples/test-cases for different
+Read header comments before attempting to use. Have fun and remember
+"The GAWK Manual", some are original, and some are mixture of the two.
+file.
+that program which consists only of BEGIN block does not need an input
+ --mj
+
+
--- /dev/null
+# From spcecdt@armory.com Tue Jun 3 11:41:49 2003
+# Return-Path: <spcecdt@armory.com>
+# Received: from localhost (skeeve [127.0.0.1])
+# by skeeve.com (8.12.5/8.12.5) with ESMTP id h538fVuW018115
+# for <arnold@localhost>; Tue, 3 Jun 2003 11:41:49 +0300
+# Received: from actcom.co.il [192.114.47.1]
+# by localhost with POP3 (fetchmail-5.9.0)
+# for arnold@localhost (single-drop); Tue, 03 Jun 2003 11:41:49 +0300 (IDT)
+# Received: by actcom.co.il (mbox arobbins)
+# (with Cubic Circle's cucipop (v1.31 1998/05/13) Tue Jun 3 11:41:37 2003)
+# X-From_: spcecdt@armory.com Mon Jun 2 20:17:30 2003
+# Received: from smtp1.actcom.net.il by actcom.co.il with ESMTP
+# (8.11.6/actcom-0.2) id h52HHNY23516 for <arobbins@actcom.co.il>;
+# Mon, 2 Jun 2003 20:17:24 +0300 (EET DST)
+# (rfc931-sender: mail.actcom.co.il [192.114.47.13])
+# Received: from f7.net (consort.superb.net [209.61.216.22])
+# by smtp1.actcom.net.il (8.12.8/8.12.8) with ESMTP id h52HIHqv028728
+# for <arobbins@actcom.co.il>; Mon, 2 Jun 2003 20:18:18 +0300
+# Received: from armory.com (deepthought.armory.com [192.122.209.42])
+# by f7.net (8.11.7/8.11.6) with SMTP id h52HHKl31637
+# for <arnold@skeeve.com>; Mon, 2 Jun 2003 13:17:20 -0400
+# Date: Mon, 2 Jun 2003 10:17:11 -0700
+# From: "John H. DuBois III" <spcecdt@armory.com>
+# To: arnold@skeeve.com
+# Subject: gawk 3.1.2c coredump
+# Message-ID: <20030602171711.GA3958@armory.com>
+# Mime-Version: 1.0
+# Content-Type: text/plain; charset=us-ascii
+# Content-Disposition: inline
+# User-Agent: Mutt/1.3.28i
+# X-Www: http://www.armory.com./~spcecdt/
+# Sender: spcecdt@armory.com
+# X-SpamBouncer: 1.4 (10/07/01)
+# X-SBClass: OK
+# Status: R
+#
+#!/usr/local/bin/gawk -f
+BEGIN {
+ switch (substr("x",1,1)) {
+ case /ask.com/:
+ break
+ case "google":
+ break
+ }
+}
+#
+# The stack says:
+#
+# #0 0x0806fac2 in r_tree_eval (tree=0x8092000, iscond=0) at eval.c:813
+# #1 0x08070413 in r_tree_eval (tree=0x0, iscond=0) at eval.c:1071
+# #2 0x08070413 in r_tree_eval (tree=0x8092000, iscond=0) at eval.c:1071
+# #3 0x08070413 in r_tree_eval (tree=0x8092000, iscond=0) at eval.c:1071
+# [ this continues on indefinitely - I suppose it ran out of stack eventually ]
+#
+# John
+# --
+# John DuBois spcecdt@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
+#
+#
--- /dev/null
+# program to make sure we don't infinite
+# syntax errors
+
+print "hi"
--- /dev/null
+gawk: synerr1.awk:4: print "hi"
+gawk: synerr1.awk:4: ^ syntax error
+EXIT CODE: 1
--- /dev/null
+/foo^bar/
+/foo$bar/
--- /dev/null
+foo^bar
+foo$bar
--- /dev/null
+# To: bug-gnu-utils@prep.ai.mit.edu
+# Cc: arnold@gnu.ai.mit.edu
+# Date: Mon, 20 Nov 1995 11:39:29 -0500
+# From: "R. Hank Donnelly" <emory!head-cfa.harvard.edu!donnelly>
+#
+# Operating system: Linux1.2.13 (Slackware distrib)
+# GAWK version: 2.15 (?)
+# compiler: GCC (?)
+#
+# The following enclosed script does not want to fully process the input data
+# file. It correctly executes the operations on the first record, and then dies
+# on the second one. My true data file is much longer but this is
+# representative and it does fail on a file even as short as this one.
+# The failure appears to occur in the declared function add2output. Between the
+# steps of incrementing NF by one and setting $NF to the passed variable
+# the passed variable appears to vanish (i.e. NF does go from 68 to 69
+# and before incrementing it "variable" equals what it should but after
+# "variable" has no value at all.)
+#
+# The scripts have been developed using nawk on a Sun (where they run fine)
+# I have tried gawk there but get a different crash which I have not yet traced
+# down. Ideally I would like to keep the script the same so that it would run
+# on either gawk or nawk (that way I can step back and forth between laptop and
+# workstation.
+#
+# Any ideas why the laptop installation is having problems?
+# Hank
+#
+#
+# #!/usr/bin/gawk -f
+
+BEGIN {
+ # set a few values
+ FS = "\t"
+ OFS = "\t"
+ pi = atan2(0, -1)
+# distance from HRMA to focal plane in mm
+ fullradius = 10260.54
+
+ # set locations of parameters on input line
+ nf_nrg = 1
+ nf_order = 3
+ nf_item = 4
+ nf_suite = 5
+ nf_grating = 8
+ nf_shutter = 9
+ nf_type = 13
+ nf_src = 14
+ nf_target = 15
+ nf_voltage = 16
+ nf_flux = 17
+ nf_filt1 = 20
+ nf_filt1_th = 21
+ nf_filt2 = 22
+ nf_filt2_th = 23
+ nf_bnd = 24
+ nf_hrma_polar = 27
+ nf_hrma_az = 28
+ nf_detector = 30
+ nf_acis_read = 32
+ nf_acis_proc = 33
+ nf_acis_frame = 34
+ nf_hxda_aplist = 36
+ nf_hxda_y_range = 37
+ nf_hxda_z_range = 38
+ nf_hxda_y_step = 39
+ nf_hxda_z_step = 40
+ nf_sim_z = 41
+ nf_fam_polar = 43
+ nf_fam_az = 44
+ nf_fam_dither_type = 45
+ nf_mono_init = 51
+ nf_mono_range = 52
+ nf_mono_step = 53
+ nf_defocus = 54
+ nf_acis_temp = 55
+ nf_tight = 59
+ nf_offset_y = 64
+ nf_offset_z = 65
+
+ while( getline < "xrcf_mnemonics.dat" > 0 ) {
+ mnemonic[$1] = $2
+ }
+
+# "date" | getline date_line
+# ADR: use a fixed date so that testing will work
+ date_line = "Sun Mar 10 23:00:27 EST 1996"
+ split(date_line, in_date, " ")
+ out_date = in_date[2] " " in_date[3] ", " in_date[6]
+}
+
+function add2output( variable ) {
+#print("hi1") >> "debug"
+ NF++
+#print("hi2") >> "debug"
+ $NF = variable
+#print("hi3") >> "debug"
+}
+
+function error( ekey, message ) {
+ print "Error at input line " NR ", anode " ekey >> "errors.cleanup"
+ print " " message "." >> "errors.cleanup"
+}
+
+function hxda_na() {
+ $nf_hxda_aplist = $nf_hxda_y_range = $nf_hxda_z_range = "N/A"
+ $nf_hxda_y_step = $nf_hxda_z_step = "N/A"
+}
+
+function acis_na() {
+ $nf_acis_read = $nf_acis_proc = $nf_acis_frame = $nf_acis_temp = "N/A"
+}
+
+function hrc_na() {
+# print ("hi") >> "debug"
+}
+
+function fpsi_na() {
+ acis_na()
+ hrc_na()
+ $nf_sim_z = $nf_fam_polar = $nf_fam_az = $nf_fam_dither_type = "N/A"
+}
+
+function mono_na() {
+ $nf_mono_init = $nf_mono_range = $nf_mono_step = "N/A"
+}
+
+# this gives the pitch and yaw of the HRMA and FAM
+# positive pitch is facing the source "looking down"
+# positive yaw is looking left
+# 0 az is north 90 is up
+# this also adds in the FAM X,Y,Z positions
+
+function polaz2yawpitch(polar, az) {
+ theta = az * pi / 180
+ phi = polar * pi / 180 / 60
+
+
+ if( polar == 0 ) {
+ add2output( 0 )
+ add2output( 0 )
+ } else {
+ if(az == 0 || az == 180)
+ add2output( 0 )
+ else
+ add2output( - polar * sin(theta) )
+
+
+# x = cos (phi)
+# y = sin (phi) * cos (theta)
+# add2output( atan2(y,x)*180 / pi * 60 )
+
+ if(az == 90 || az ==270 )
+ add2output( 0 )
+ else
+ add2output( - polar * cos(theta) )
+
+ }
+# x = cos (phi)
+# z= sin (phi) * sin (theta)
+# add2output( atan2(z,x)*180 / pi * 60 )
+
+ if(config !~ /HXDA/) {
+# negative values of defocus move us farther from the source thus
+# increasing radius
+ radius = fullradius - defocus
+
+# FAM_x; FAM_y; FAM_z
+ if((offset_y == 0) && (offset_z == 0)){
+ add2output( fullradius - radius * cos (phi) )
+
+ if (az == 90 || az ==270)
+ add2output( 0 )
+ else
+ add2output( radius * sin (phi) * cos (theta) )
+
+ if (az == 0 || az == 180)
+ add2output( 0 )
+ else
+ add2output( - radius * sin (phi) * sin (theta) )
+ } else {
+# ******* THIS SEGMENT OF CODE IS NOT MATHEMATICALLY CORRECT FOR ****
+# OFF AXIS ANGLES AND IS SUPPLIED AS A WORKAROUND SINCE IT WILL
+# PROBABLY ONLY BE USED ON AXIS.
+ add2output( defocus )
+ add2output( offset_y )
+ add2output( offset_z )
+ }
+
+ } else {
+ add2output( "N/A" )
+ add2output( "N/A" )
+ add2output( "N/A" )
+ }
+}
+
+# set TIGHT/LOOSE to N/A if it is not one of the two allowed values
+function tight_na() {
+ if( $nf_tight !~ /TIGHT|LOOSE/ ) {
+ $nf_tight == "N/A"
+ }
+}
+
+# this entry is used to give certain entries names
+{
+ type = $nf_type
+ item = $nf_item
+ suite = $nf_suite
+ order = $nf_order
+ detector = $nf_detector
+ grating = $nf_grating
+ offset_y= $nf_offset_y
+ offset_z= $nf_offset_z
+ bnd = $nf_bnd
+ defocus = $nf_defocus
+}
+
+{
+ # make configuration parameter
+ # as well as setting configuration-dependent N/A values
+
+ if( $nf_bnd ~ "SCAN" ) {
+ # BND is scanning beam
+ config = "BND"
+ hxda_na()
+ fpsi_na()
+ } else {
+ if( grating == "NONE" ) {
+ config = "HRMA"
+ } else {
+ if( grating == "HETG" ) {
+ if( order != "Both" ) {
+ $nf_shutter = order substr($nf_shutter, \
+ index($nf_shutter, ",") )
+ }
+ } else {
+ order = "N/A"
+ }
+ config = "HRMA/" grating
+ }
+
+ if( detector ~ /ACIS|HRC/ ) {
+ detsys = detector
+ nsub = sub("-", ",", detsys)
+ config = config "/" detsys
+ hxda_na()
+ } else {
+ config = config "/HXDA"
+ fpsi_na()
+ if( detector == "HSI" ) {
+ hxda_na()
+ }
+ }
+ }
+
+ add2output( config )
+
+ if( $nf_src ~ /EIPS|Penning/ ) mono_na()
+
+ if( $nf_src == "Penning" ) $nf_voltage = "N/A"
+
+ itm = sprintf("%03d", item)
+
+ if(config in mnemonic) {
+ if( type in mnemonic ) {
+ ID = mnemonic[config] "-" mnemonic[type] "-" suite "." itm
+ add2output( ID )
+ } else {
+ error(type, "measurement type not in list")
+ }
+ } else {
+ error(config, "measurement configuration not in list")
+ }
+
+ # add date to output line
+ add2output( out_date )
+
+ # Convert HRMA polar and azimuthal angles to yaw and pitch
+ polaz2yawpitch($nf_hrma_polar, $nf_hrma_az)
+
+ # set TIGHT/LOOSE to N/A if it is not one of the two allowed values
+ tight_na()
+
+ # compute number of HXDA apertures
+ if( config ~ /HXDA/ && $nf_hxda_aplist != "N/A")
+ add2output( split( $nf_hxda_aplist, dummy, "," ) )
+ else
+ add2output( "N/A" )
+
+ # make sure the BND value is properly set
+ if($nf_bnd == "FIXED" && detector ~ /ACIS/)
+ $nf_bnd =bnd"-SYNC"
+ else
+ $nf_bnd = bnd"-FREE"
+ print
+}
--- /dev/null
+0.277 N/A N/A 1 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS C-Ka 1.108 0.13484 N/A N/A C8H8 10.32 C8H8 20.64 FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 44.7175 44.7175 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
+1.486 N/A N/A 2 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Al-Ka 4.458 0.642119 N/A N/A Al 18.38 Al 36.76 FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
+4.51 N/A N/A 3 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Ti-Ka 22.55 3.02894 N/A N/A Ti 40.6 N/A N/A FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
--- /dev/null
+0.277 N/A N/A 1 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS C-Ka 1.108 0.13484 N/A N/A C8H8 10.32 C8H8 20.64 FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 44.7175 44.7175 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
+1.486 N/A N/A 2 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Al-Ka 4.458 0.642119 N/A N/A Al 18.38 Al 36.76 FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
+4.51 N/A N/A 3 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Ti-Ka 22.55 3.02894 N/A N/A Ti 40.6 N/A N/A FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
--- /dev/null
+BEGIN { a = a + 1; x = a; print a}
+BEGIN { ++b; x = b; print b}
--- /dev/null
+gawk: uninit2.awk:1: warning: reference to uninitialized variable `a'
+1
+gawk: uninit2.awk:2: warning: reference to uninitialized variable `b'
+1
--- /dev/null
+function f(x){
+ print x
+}
+
+BEGIN {
+ f(x)
+}
--- /dev/null
+gawk: uninit3.awk:8: warning: function `f': parameter `x' shadows global variable
+gawk: uninit3.awk:2: warning: reference to uninitialized variable `x'
+
--- /dev/null
+# test whether --lint catches uninitialized fields:
+function pr()
+{
+ print
+}
+
+BEGIN {
+ pr()
+ print $0
+ print $(1-1)
+ print $1
+ NF=3; print $2
+}
--- /dev/null
+gawk: uninit4.awk:4: warning: reference to uninitialized field `$0'
+
+gawk: uninit4.awk:9: warning: reference to uninitialized field `$0'
+
+gawk: uninit4.awk:10: warning: reference to uninitialized field `$0'
+
+gawk: uninit4.awk:11: warning: reference to uninitialized field `$1'
+
+gawk: uninit4.awk:12: warning: reference to uninitialized field `$2'
+
--- /dev/null
+BEGIN {
+ a += 2
+}
--- /dev/null
+gawk: uninitialized.awk:2: warning: reference to uninitialized variable `a'
--- /dev/null
+BEGIN{x=".........................................................................................................................................................................................................................................................}
\ No newline at end of file
--- /dev/null
+gawk: unterm.awk:1: BEGIN{x=".........................................................................................................................................................................................................................................................}
+gawk: unterm.awk:1: ^ unterminated string
+EXIT CODE: 1
--- /dev/null
+{ word[$0]++ }
+END {
+ for (i in word)
+ print i
+}
--- /dev/null
+gawk
+pattern
+scanning
+and
+processing
+language
+or
+style
+options
+file
+or
+style
+options
+file
+or
+style
+options
+file
+or
+style
+options
+file
+is
+the
+Project's
+implementation
+of
+the
+programming
+language.
+It
+conforms
+to
+the
+definition
+of
+the
+language
+in
+the
+Command
+Language
+And
+Utilities
+Standard.
+This
+version
+in
+turn
+is
+based
+on
+the
+description
+in
+by
+Aho,
+Kernighan,
+and
+Weinberger,
+with
+the
+additional
+features
+found
+in
+the
+System
+V
+Release
+version
+of
+also
+provides
+more
+recent
+Bell
+Laboratories
+extensions,
+and
+a
+number
+of
+extensions.
+is
+the
+profiling
+version
+of
+It
+is
+identical
+in
+every
+way
+to
+except
+that
+programs
+run
+more
+slowly,
+and
+it
+automatically
+produces
+an
+execution
+profile
+in
+the
+file
+when
+done.
+See
+the
+option,
+below.
+The
+command
+line
+consists
+of
+options
+to
+itself,
+the
+program
+text
+not
+supplied
+via
+the
+or
+options),
+and
+values
+to
+be
+made
+available
+in
+the
+and
+pre-defined
+variables.
+options
+may
+be
+either
+traditional
+one
+letter
+options,
+or
+style
+long
+options.
+options
+start
+with
+a
+single
+while
+long
+options
+start
+with
+Long
+options
+are
+provided
+for
+both
+features
+and
+for
+features.
--- /dev/null
+Aho,
+And
+Bell
+Command
+It
+Kernighan,
+Laboratories
+Language
+Long
+Project's
+Release
+See
+Standard.
+System
+The
+This
+Utilities
+V
+Weinberger,
+a
+additional
+also
+an
+and
+are
+automatically
+available
+based
+be
+below.
+both
+by
+command
+conforms
+consists
+definition
+description
+done.
+either
+every
+except
+execution
+extensions,
+extensions.
+features
+features.
+file
+for
+found
+gawk
+identical
+implementation
+in
+is
+it
+itself,
+language
+language.
+letter
+line
+long
+made
+may
+more
+not
+number
+of
+on
+one
+option,
+options
+options),
+options,
+options.
+or
+pattern
+pre-defined
+processing
+produces
+profile
+profiling
+program
+programming
+programs
+provided
+provides
+recent
+run
+scanning
+single
+slowly,
+start
+style
+supplied
+text
+that
+the
+to
+traditional
+turn
+values
+variables.
+version
+via
+way
+when
+while
+with
--- /dev/null
+# From arnold@f7.net Sun Sep 5 12:30:53 2004
+# Date: Fri, 3 Sep 2004 00:54:32 -0400 (EDT)
+# From: William J Poser <wjposer@ldc.upenn.edu>
+# To: arnold@skeeve.com
+# Subject: gawk bug
+# Message-ID: <20040903004347.W80049@lorax.ldc.upenn.edu>
+#
+# Here is a revised version of my previous message, modified to describe
+# the accompanying files.
+#
+# IhSplit.awk should replicate every record with exactly one entry in the
+# IH field, delete records lacking an IH field, and produce as many copies
+# of records with two or more entries in the IH field as there are entries.
+# In the latter case, the original IH field should be relabelled OIH and
+# a new IH field be added at the beginning of the record.
+#
+# This has worked properly for many years, since at least 1997. It worked properly with gawk 3.0.5
+# and possibly later versions. Unfortunately I didn't keep track of exactly what version it
+# broke on, but it was whatever came with Mandrake Linux 9.0. It continued to fail with version
+# 3.1.2. However, the problem was eliminated with version 3.1.3 and remains
+# eliminated in version 3.1.4.
+#
+# The problem was that an apparently random subset of records would loose some
+# or all of their fields. Running the script on the same input always produces
+# the same output with the same errors.
+#
+# The file Input is a subset of a real lexicon that produces errors using
+# gawk 3.1.2. GoodOutput is the expected output. BadOutput is the erroneous
+# output. A diff will show that there are actually two errors. One record
+# has fields stripped as described above. Another is omitted in its entirety.
+#
+#
+# Bill Poser, Linguistics, University of Pennsylvania
+# http://www.ling.upenn.edu/~wjposer/ billposer@alum.mit.edu
+# ----------------------------------------------------------------------------
+#For each record that contains multiple items in its inverse headword (IH)
+#field, generate a set of new records each containing exactly one item
+#in the inverse headword field, otherwise copies of the original.
+
+function CleanUp() #Clean up for next input record.
+{
+ for(i in rec) delete rec[i];
+}
+
+BEGIN {
+RS = "";
+FS = "\n?%"
+}
+{
+
+# First, create an associative array with the tags as indices.
+ for(i = 2; i <= NF; i++) { # The leading FS creates an initial empty field
+ split($i, f, ":");
+ rec[f[1]]=substr($i,index($i,":")+1);
+ }
+
+ if(!("IH" in rec)) next;
+
+# Parse out the inverse headwords
+
+ items = split(rec["IH"],ihs,"/");
+
+# Replace the old IH field.
+
+ sub(/%IH:/,"%OIH:",$0);
+
+# Generate a new copy of the record for each inverse headword
+
+ for(i = 1; i <= items; i++){
+ entries+=1;
+ printf("%%IH:%s\n",ihs[i]);
+ printf("%s\n\n",$0);
+ }
+ CleanUp();
+ }
--- /dev/null
+%P:nut'i
+%G:exertion
+%IH:exertion
+%C:N
+%SF:abstractions-misc
+%S:JOPA/EDFR/VESE
+%ES:000088
+%UID:002463
+%MD:1999/03/15
+
+%P:ts'iyantsuk t'eooninzun
+%G:information
+%IH:information
+%C:N
+%SF:abstractions-misc
+%S:JOPA/BRBI
+%UID:000986
+%MD:1997/12/17
+
+%P:k'et'uk
+%G:interval
+%IH:interval
+%C:N
+%SF:abstractions-misc
+%S:MAGO
+%ES:001077
+%UID:000873
+%MD:1997/12/11
+
+%P:khunek
+%G:language, word, message
+%IH:language/word/message
+%POSS:ghunek
+%P1p:neghunek
+%C:N
+%SF:abstractions-misc
+%S:MAGO/BRBI/JOPA/EDFR/VESE/JEKO
+%UID:000928
+%MD:2001/02/10
+
+%P:gal
+%G:running
+%IH:running
+%C:N
+%R:Dugal ndesda. He got hurt while running.
+%SF:abstractions-misc
+%S:JOPA
+%ES:000535
+%UID:002462
+%MD:1999/03/15
+
+%P:t'en
+%G:work
+%IH:work
+%C:N
+%SF:abstractions-misc
+%S:VESE/PEJO
+%ES:000672
+%UID:003028
+%POCKET:N
+%MD:2000/10/04
+
+%P:'ut'en
+%G:work
+%IH:work
+%C:N
+%SF:abstractions-misc
+%P1p:neye'ut'en
+%S:JOPA
+%ES:001041
+%UID:004264
+%POCKET:Y
+%MD:2001/03/15
+
+%P:dulkw'ah
+%G:Spotted Frog
+%IH:Spotted Frog/Frog, Spotted
+%SN:Rana pretiosa
+%MN:Lives in water and has red markings on the belly.
+%PICTURE:/home/poser/Research/Dakelh/Pictures/psfiles/SpottedFrog.ps
+%CAPTION:{\qc Tsasdli} --- Spotted Frog
+%PICPERMISSION:N
+%PICCREDIT:Drawing of Spotted Frog from {\it The Amphibians of British Columbia\/}.
+%C:N
+%SF:amphibiansandreptiles
+%S:EDFR
+%UID:004111
+%POCKET:Y
+%MD:2001/03/07
+
+%P:chunlai
+%G:salamander, lizard
+%IH:lizard/salamander
+%MN:The only species of salamander found in the region is the
+ Long-toed Salamander {\it Ambystoma macrodactylum\/}. No lizards
+ are found in the region. However, this term is applied to other
+ varieties of salamander and to lizards, such as the gekkos sold as
+ pets.
+%FGREF:Corkran \& Thoms (1996;39)
+%SN:Ambystoma macrodactylum
+%C:N
+%SF:amphibiansandreptiles
+%S:LITM/JOPA/BRBI
+%UID:000157
+%MD:1998/05/16
+
+%P:tl'ughus
+%G:snake
+%IH:snake
+%C:N
+%MN:The only snake found in the region is the Common Garter Snake
+ {\it Thamnophis sirtalis\/}. However, the term is applied to all snakes.
+%SN:Thamnophis sirtalis
+%SF:amphibiansandreptiles
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000250
+%MD:1998/12/07
+
+%P:tsasdli
+%G:Western Toad
+%SN:Bufo boreas
+%IH:Western Toad/Toad, Western
+%MN:Lives on land.
+%SF:amphibiansandreptiles
+%C:N
+%S:LITM/JOPA/BRBI/MAGO/STJA/EDFR
+%UID:000059
+%MD:2001/03/07
+
+%P:lhits'e
+%G:bitch, female dog
+%IH:bitch/dog, female
+%C:N
+%SF:animals-domestic
+%S:JOPA/EDFR/VESE
+%UID:002446
+%MD:1999/03/15
+
+%P:musdus
+%G:cow
+%IH:cow
+%C:N
+%P2s:nmusdus
+%ETYM:Loan from Cree {\qf mostos} ``buffalo''.
+%LOANSOURCE:Cree
+%SF:animals-domestic
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000036
+%MD:1997/06/12
+
+%P:lhi
+%G:dog
+%IH:dog
+%C:N
+%DUOPLURAL:lhike
+%SF:animals-domestic
+%POSS:lik
+%P1s:slik
+%P1p:nelik
+%DUOPLURAL:lhike
+%S:LITM/JOPA/BRBI/STJA/VESE/EDFR/JEKO
+%UID:000270
+%MD:2001/02/15
+
+%P:budzocho
+%G:donkey, mule
+%IH:donkey/mule
+%SF:animals-domestic
+%ETYM:``big ears''.
+%C:N
+%S:JOPA/BRBI
+%UID:000376
+%MD:1997/11/14
+
+%P:yeztli
+%G:horse
+%IH:horse
+%SF:animals-domestic
+%ETYM:A contraction of {\qc yezihlhi} ``elk dog''.
+%C:N
+%S:LITM/JOPA/BRBI/PEJO
+%UID:000042
+%MD:2000/10/21
+
+%P:lhike
+%G:Irregular plural of {\qc lhi}, q.v.
+%IH:dogs
+%C:N
+%SF:animals-domestic
+%S:LITM/BRBI/JOPA/STJA
+%UID:000293
+%MD:1999/01/26
+
+%P:sbaiyaz
+%G:lamb
+%IH:lamb
+%C:N
+%SF:animals-domestic
+%S:LITM
+%UID:000254
+%MD:1997/06/16
+
+%P:gugoos
+%G:pig
+%IH:pig
+%C:N
+%ETYM:Ultimately borrowed from French {\qf coche}, probably via Cree.
+%LOANSOURCE:Cree
+%SF:animals-domestic
+%S:LITM/JOPA/BRBI
+%UID:000133
+%MD:1997/06/16
+
+%P:'ut'az
+%G:bat
+%IH:bat
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000390
+%MD:1997/11/14
+
+%P:liyabdut'ai
+%G:bat
+%MN:The only kind of bat found in the region is the Little Brown Myotis.
+%IH:bat
+%SF:animals-land
+%SN:Myotis lucifugus
+%ETYM:Literally, ``devil bird'', a compound of {\qc liyab} ``devil'', a loan from
+ French {\qf le diable}, and {\qc dut'ai} ``bird''.
+%LOANSOURCE:French
+%C:N
+%S:JOPA/BRBI
+%UID:000215
+%MD:1997/06/16
+
+%P:sus
+%G:black bear
+%IH:black bear
+%C:N
+%SF:animals-land
+%SN:Ursus americanus
+%S:LITM/JOPA/BRBI/STJA/EDFR/VESE/JEKO
+%UID:000048
+%MD:1998/12/19
+
+%P:musduscho dughai
+%G:buffalo
+%IH:buffalo
+%SF:animals-land
+%C:N
+%ETYM:``big hairy cow''.
+%S:JOPA/EDFR
+%UID:003478
+%POCKET:Y
+%MD:2000/11/04
+
+%P:tl'ok'umusdus
+%G:buffalo
+%IH:buffalo
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000374
+%MD:2000/11/01
+
+%P:jenyo
+%G:bull moose
+%IH:bull moose/moose, bull
+%SF:animals-land
+%C:N
+%S:MAGO/JOPA/VESE/EDFR/JEKO
+%UID:000474
+%MD:1999/05/11
+
+%P:denyo
+%G:bull moose
+%IH:moose, bull
+%SF:animals-land
+%C:N
+%S:LITM/JOPA
+%UID:000348
+%MD:1997/06/18
+
+%P:tsiyeyaz
+%G:calf moose
+%IH:calf moose/moose, calf
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000380
+%MD:1997/11/14
+
+%P:duniyaz
+%G:calf moose
+%IH:calf moose/moose, calf
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000245
+%MD:1997/06/16
+
+%P:whudzih
+%G:caribou
+%IH:caribou
+%C:N
+%SF:animals-land
+%SN:Rangifer tarandus
+%S:JOPA/BRBI/MAGO/EDFR/VESE/JEKO
+%UID:000274
+%MD:1999/05/11
+
+%P:boos
+%G:cat
+%IH:cat
+%C:N
+%SN:Felis domesticus
+%ETYM:Loan from English {\qf puss}, possibly via Chinook Jargon.
+%LOANSOURCE:English
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000137
+%MD:1997/12/17
+
+%P:ts'uwhuljos
+%G:chipmunk
+%IH:chipmunk
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000146
+%MD:1997/06/16
+
+%P:booscho
+%G:cougar
+%IH:cougar
+%SF:animals-land
+%SN:Felis concolor
+%C:N
+%ETYM:Literally, ``big cat'', where {\qc boos} ``cat'' is a loan from English
+ {\qf puss}, possibly via Chinook Jargon.
+%S:JOPA/BRBI
+%UID:000050
+%MD:1997/11/14
+
+%P:duni'at
+%G:cow moose
+%IH:cow moose/moose, cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000377
+%MD:1997/11/14
+
+%P:tintulhi
+%G:coyote
+%IH:coyote
+%C:N
+%SF:animals-land
+%SN:Canis latrans
+%S:JOPA/BRBI
+%R:LITM has chuntulhi.
+%UID:000155
+%MD:1997/06/16
+
+%P:yests'e
+%G:deer
+%IH:deer
+%SF:animals-land
+%C:N
+%S:LITM/JOPA/BRBI/EDFR
+%UID:000132
+%MD:1998/12/16
+
+%P:dets'it
+%G:dry cow moose
+%IH:dry cow moose/moose, dry cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000378
+%MD:1997/11/14
+
+%P:yezih
+%G:elk
+%IH:elk
+%SF:animals-land
+%C:N
+%R:STJA doesn't use this.
+%S:JOPA/BRBI
+%UID:000382
+%MD:1997/11/14
+
+%P:tsa'at
+%G:female beaver
+%IH:beaver, female
+%C:N
+%SF:animals-land
+%S:STJA
+%UID:001295
+%MD:1998/12/08
+
+%P:chunihcho
+%G:fisher
+%IH:fisher
+%ETYM:``big marten''.
+%SF:animals-land
+%SN:Martes pennanti
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000385
+%MD:2000/06/18
+
+%P:ts'unalhbuz
+%G:flying squirrel
+%IH:flying squirrel
+%SF:animals-land
+%SN:Glaucomys sabrinus alpinus
+%PICTURE:/home/poser/Research/Dakelh/Pictures/psfiles/FlyingSquirrel.ps
+%CAPTION:{\qc ts'unulhbuz} --- Flying Squirrel
+%PICPERMISSION:N
+%PICCREDIT:Drawing of Flying Squirrel from {\it The Mammals of British Columbia\/}.
+%C:N
+%S:JOPA/BRBI
+%UID:000389
+%MD:1997/11/14
+
+%P:nanguz
+%G:fox
+%IH:fox
+%C:N
+%SF:animals-land
+%S:MAGO
+%UID:000139
+%MD:2001/02/26
+
+%P:shas
+%G:grizzly bear
+%IH:grizzly bear
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI/VESE/EDFR/JEKO
+%UID:000039
+%MD:1997/06/12
+
+%P:shasyaz
+%G:grizzly bear cub
+%IH:grizzly bear cub/cub, grizzly bear
+%C:N
+%SF:animals-land
+%S:STJA
+%UID:002114
+%MD:1999/02/20
+
+%P:shas'at
+%G:grizzly bear sow
+%IH:grizzly bear sow/sow, grizzly bear
+%C:N
+%SF:animals-land
+%ETYM:``grizzly bear's wife''.
+%S:STJA
+%UID:002113
+%MD:1999/02/20
+
+%P:-lik
+%G:irregular possessed stem of {\qc lhi}, q.v.
+%C:N
+%SF:animals-land
+%S:MAGO
+%UID:000564
+%MD:1997/12/11
+
+%P:wasi
+%G:lynx
+%IH:lynx
+%C:N
+%SF:animals-land
+%SN:Felis lynx
+%ETYM:Loan from Gitksan {\qf wish}.
+%LOANSOURCE:Gitksan
+%S:JOPA/BRBI/STJA/EDFR/VESE/JEKO/MAGO
+%UID:000049
+%MD:2001/04/20
+
+%P:k'ani
+%G:woodchuck
+%IH:woodchuck
+%C:N
+%SF:animals-land
+%SN:Marmota monax
+%S:JOPA/BRBI/PEJO
+%R:Clarified with Josie and Peter 2001/05/28.
+%UID:000391
+%POCKET:Y
+%MD:2001/05/28
+
+%P:dutni
+%G:marmot
+%IH:marmot
+%SF:animals-land
+%C:N
+%SN:Marmota caligata
+%R:Josie and Peter are not really familiar with marmots but have heard older
+ people talk about them.
+%S:JOPA/PEJO
+%UID:000143
+%MD:1998/02/10
+
+%P:chunih
+%G:marten
+%IH:marten
+%SF:animals-land
+%SN:Martes americana
+%C:N
+%S:JOPA/BRBI/VESE/EDFR/JEKO/MAGO
+%UID:000016
+%MD:2001/04/20
+
+%P:telhjoos
+%G:mink
+%IH:mink
+%C:N
+%SF:animals-land
+%SN:Mustela vison
+%S:LITM/JOPA/BRBI
+%UID:000167
+%MD:1997/06/16
+
+%P:duni
+%G:moose
+%IH:moose
+%C:N
+%SF:animals-land
+%SN:Alces alces andersoni
+%S:LITM-EDFR/JOPA/BRBI
+%UID:000346
+%MD:1997/06/18
+
+%P:dats'ooz
+%G:mouse
+%IH:mouse
+%SF:animals-land
+%C:N
+%S:LITM/JOPA/MAGO/VESE/JEKO
+%UID:000156
+%MD:2001/01/22
+
+%P:tsek'et
+%G:muskrat
+%IH:muskrat
+%C:N
+%SF:animals-land
+%SN:Ondatra zibethicus
+%S:JOPA/BRBI/STJA/MAGO
+%UID:000335
+%MD:1998/12/08
+
+%P:chanjo
+%G:newly sexually mature cow moose
+%IH:moose, newly sexually mature cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000379
+%MD:1997/11/14
+
+%P:looncho
+%G:pack rat
+%IH:pack rat
+%C:N
+%SF:animals-land
+%S:VESE/JEKO/MAGO
+%UID:000149
+%MD:1999/05/10
+
+%P:dlooncho
+%G:packrat
+%IH:packrat
+%C:N
+%SF:animals-land
+%S:JOPA
+%UID:002701
+%MD:1999/05/11
+
+%P:duneza
+%G:porcupine
+%IH:porcupine
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000388
+%MD:2001/03/06
+
+%P:ts'it
+%G:porcupine
+%IH:porcupine
+%SF:animals-land
+%SN:Erethizon dorsatum
+%C:N
+%ETYM:Perhaps derived from the interjection {\qc ts'it} ``don't touch it!''.
+%S:JOPA/BRBI/MAGO/BEMC/STJA
+%UID:000387
+%MD:1998/12/08
+
+%P:lhiyaz
+%G:puppy
+%IH:puppy
+%C:N
+%SF:animals-land
+%DUOPLURAL:lhiyazke
+%DUOPLURAL:lhikeyaz
+%R:Josie prefers {\qc lhikeyaz}.
+%S:LITM/BRBI/JOPA/EDFR/MAGO-JEKO
+%UID:000182
+%MD:2001/05/26
+
+%P:nats'ildelh
+%G:Red Squirrel
+%IH:squirrel/Red Squirrel
+%SN:Tamiasciurus hudsonicus colum.
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI/STJA
+%UID:000034
+%MD:1999/02/17
+
+%P:goh
+%G:rabbit
+%IH:rabbit
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/VESE/EDFR/JEKO
+%UID:000023
+%MD:1999/05/11
+
+%P:ooch'ainischoot
+%G:recently weaned calf moose
+%IH:moose, recently weaned calf
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000381
+%MD:1997/11/14
+
+%P:sbai
+%G:sheep
+%IH:sheep
+%C:N
+%SF:animals-land
+%S:MAGO
+%UID:001131
+%MD:1998/02/10
+
+%P:'usbai
+%G:sheep
+%IH:sheep
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000375
+%MD:1997/11/14
+
+%P:'ulhguk
+%G:shrew
+%IH:shrew
+%SF:animals-land
+%C:N
+%S:MAGO/VESE/JEKO
+%UID:000526
+%MD:2001/01/22
+
+%P:hoonliz
+%G:skunk
+%IH:skunk
+%C:N
+%P2s:unhoonliz
+%SF:animals-land
+%S:LITM/JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000052
+%MD:1997/06/12
+
+%P:nohbai
+%G:weasel
+%IH:weasel
+%C:N
+%SF:animals-land
+%S:JOPA/BRBI/MAGO
+%UID:000141
+%MD:1997/06/16
+
+%P:yus
+%G:wolf
+%IH:wolf
+%C:N
+%SF:animals-land
+%SN:Canis lupus
+%S:LITM/JOPA/BRBI
+%UID:000051
+%MD:1997/06/12
+
+%P:noostel
+%G:wolverine
+%IH:wolverine
+%C:N
+%SF:animals-land
+%SN:Gulo gulo
+%S:JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000140
+%MD:2001/04/20
+
+%P:tsatsul
+%G:young beaver
+%IH:beaver, young
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI/STJA
+%UID:000384
+%MD:1998/12/08
+
+%P:lht'at
+%G:beaver dam
+%IH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001287
+%MD:1998/12/08
+
+%P:'ulh
+%G:beaver dam
+%IH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001288
+%MD:1998/12/08
+
+%P:tsaken
+%G:beaver lodge
+%IH:beaver lodge
+%C:N
+%SF:animals-misc
+%S:JOPA/BRBI/STJA
+%UID:000405
+%MD:1998/12/08
+
+%P:tunyohtsati
+%G:beaver path under the ice
+%IH:beaver path under the ice
+%C:N
+%SF:animals-misc
+%S:JOPA/EDFR
+%UID:003769
+%POCKET:Y
+%MD:2001/02/13
+
+%P:sus'an
+%G:black bear den
+%IH:black bear den
+%C:N
+%SF:animals-misc
+%S:LITM/STJA
+%UID:000131
+%MD:1998/12/08
+
+%P:shask'oh
+%G:grizzly bear tracks
+%IH:tracks, grizzly bear
+%C:N
+%SF:animals-misc
+%S:MAGO
+%UID:001132
+%MD:1998/02/10
+
+%P:hoolht'ukw
+%G:leech
+%IH:leech
+%SF:animals-misc
+%C:N
+%S:JOPA/PEJO/EDFR
+%UID:003410
+%POCKET:Y
+%MD:2000/11/01
+
+%P:hoot'ub
+%G:leech
+%IH:leech
+%SF:bugs
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000370
+%MD:2000/11/01
+
+%P:dunik'oh
+%G:moose tracks
+%IH:moose tracks
+%C:N
+%SF:animals-misc
+%S:PEJO/JOPA
+%ES:000491
+%UID:003121
+%POCKET:Y
+%MD:2000/09/28
+
+%P:gohk'oh
+%G:rabbit tracks
+%IH:tracks, rabbit
+%C:N
+%SF:animals-misc
+%S:LITM
+%UID:000073
+%MD:1997/06/12
+
+%P:tsa
+%G:beaver
+%IH:beaver
+%C:N
+%SN:Castor canadensis
+%UID:000044
+%SF:animals-water
+%S:JOPA/BRBI/STJA/EDFR/VESE/JEKO/MAGO
+%MD:2001/04/18
+
+%P:tsayaz
+%G:beaver kit
+%IH:kit, beaver/beaver, baby
+%SF:animals-water
+%C:N
+%S:STJA
+%UID:001294
+%MD:2000/06/18
+
+%P:tsati
+%G:big beaver, old beaver
+%IH:beaver, big/beaver, old
+%C:N
+%SF:animals-water
+%S:LITM/JOPA/BRBI/STJA
+%UID:000206
+%MD:1998/12/08
+
+%P:tsis
+%G:otter
+%IH:otter
+%SF:animals-water
+%SN:Lutra canadensis
+%C:N
+%S:JOPA/BRBI
+%UID:000386
+%MD:1997/11/14
+
+%P:datsan
+%G:American Crow
+%C:N
+%SF:bird-gen
+%SN:Corvus brachyrhynchos
+%IH:crow/American Crow
+%S:LITM/PEJO
+%UID:000158
+%MD:2000/10/21
+
+%P:sewh
+%G:American Robin
+%IH:Robin, American
+%SN:Turdus migratorius
+%C:N
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/PEJO
+%UID:000181
+%MD:2000/10/21
+
+%P:tsebalyan
+%G:Bald Eagle
+%IH:Bald Eagle
+%C:N
+%SF:bird-gen
+%SN:Haliaeetus leucocephalus
+%S:LITM/JOPA/BRBI
+%UID:000150
+%MD:1997/06/16
+
+%P:dut'ai
+%G:bird, duck
+%IH:bird/duck
+%C:N
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO/STJA/PEJO
+%UID:000081
+%MD:2000/09/28
+
+%P:delh
+%G:crane
+%IH:crane
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000255
+%MD:1997/06/16
+
+%P:khoh
+%G:goose
+%IH:goose
+%C:N
+%P1s:skhoh
+%P2s:nkhoh
+%P1p:nekhoh
+%POSS:khoh
+%SF:bird-gen
+%S:JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000031
+%MD:2001/02/15
+
+%P:ts'unalhduz
+%G:hummingbird
+%IH:hummingbird
+%C:N
+%SF:bird-gen
+%S:LITM/BRBI/JOPA
+%UID:000242
+%MD:1997/06/16
+
+%P:gagiyaz
+%G:little bird
+%IH:bird, little
+%C:N
+%QCHECK:Any little bird?
+%SF:bird-gen
+%S:PEJO
+%UID:003115
+%POCKET:Y
+%MD:2000/09/28
+
+%P:dut'aiyaz
+%G:little bird
+%IH:bird, little
+%C:N
+%SF:bird-gen
+%S:STJA/JOPA/EDFR/VESE/PEJO
+%UID:001818
+%MD:2000/09/28
+
+%P:dadzi
+%G:loon
+%IH:loon
+%SF:bird-gen
+%SN:Gavia immer
+%C:N
+%S:LITM/JOPA/BRBI
+%UID:000020
+%MD:1997/06/12
+
+%P:t'ugicho
+%G:Mallard Duck
+%IH:Mallard Duck
+%C:N
+%SN:Anas platyrhynchos
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000041
+%MD:1999/05/11
+
+%P:musdzoon
+%G:owl
+%IH:owl
+%C:N
+%SF:bird-gen
+%S:LITM/BRBI/JOPA/MAGO
+%UID:000135
+%MD:1997/12/11
+
+%P:ts'olh
+%G:Red-necked Grebe
+%MN:A variety of duck locally known as the Helldiver.
+%IH:Red-Necked Grebe/Helldiver/Grebe, Red-Necked
+%SN:Podiceps grisegena
+%SF:bird-gen
+%C:N
+%S:BRBI/JOPA
+%UID:000263
+%MD:2001/03/08
+
+%P:'utsut
+%G:Ruffed grouse
+%IH:Ruffed grouse
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000218
+%MD:1997/06/16
+
+%P:nat'oh
+%G:Spruce Grouse, Fool Hen
+%IH:Spruce Grouse/Grouse, Spruce/Fool Hen
+%SF:bird-gen
+%SN:Dendragapus canadensis
+%C:N
+%S:MAGO/LITM
+%UID:000539
+%MD:1997/12/04
+
+%P:tehgwuzeh
+%G:Steller's Jay, commonly known locally as ``bluejay''.
+%IH:Steller's Jay/jay, Steller's/Bluejay (Steller's Jay)
+%SF:bird-gen
+%SN:Cyanocitta stelleri
+%C:N
+%S:JOPA/BRBI
+%UID:000356
+%MD:1997/11/14
+
+%P:wedlew
+%G:sandpiper
+%IH:sandpiper
+%C:N
+%SN:Eremophila alpestris et sim.
+%SF:bird-gen
+%S:LITM
+%UID:000237
+%MD:2002/07/19
+
+%P:besk'i
+%G:seagull
+%IH:seagull
+%C:N
+%SN:Larus species
+%SF:bird-gen
+%S:LITM
+%UID:000136
+%MD:2002/07/19
+
+%P:ts'incho
+%G:swan
+%IH:swan
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000222
+%MD:1997/06/16
+
+%P:'uschas
+%G:Tree Swallow
+%IH:Tree Swallow
+%SF:bird-gen
+%SN:Tachycineta bicolor
+%C:N
+%S:MAGO
+%UID:000535
+%MD:1997/11/22
+
+%P:gwuzeh
+%G:Whiskey Jack, Gray Jay, Canadian Jay
+%IH:Whiskey Jack/Jay, Gray/Jay, Canadian
+%C:N
+%SN:Perisoreus canadensis
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000148
+%MD:1997/11/22
+
+%P:chundulkw'uz
+%G:woodpecker
+%IH:woodpecker
+%C:N
+%SF:bird-gen
+%S:JOPA/BRBI/STJA
+%UID:000138
+%MD:1999/03/31
+
+%P:-t'o
+%G:nest
+%IH:nest
+%C:N
+%Pind:'ut'o
+%P3s:but'o
+%Pref:dut'o
+%SF:bird-misc/bugs
+%S:STJA/PEJO/JOPA/BRBI/EDFR
+%ES:001353
+%UID:000226
+%MD:2001/03/07
+
+%P:-nak'uz
+%G:a single eye
+%IH:eye, a single
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%ES:000457
+%UID:003770
+%POCKET:Y
+%MD:2001/02/13
+
+%P:-kechunoh
+%G:ankle
+%IH:ankle
+%P1s:skechunoh
+%P2s:nkechunoh
+%C:N
+%S:MAGO/STJA
+%SF:body-ext
+%UID:000865
+%MD:1999/03/03
+
+%P:-de
+%G:antler, horn
+%IH:antler/horn
+%C:N
+%SF:body-ext
+%P3s:bude
+%S:STJA
+%UID:002266
+%MD:1999/03/02
+
+%P:-de_zu_s
+%G:antler velvet
+%IH:velvet, antler
+%C:N
+%SF:body-ext
+%P3s:bude_zu_s
+%S:STJA
+%UID:002267
+%MD:1999/03/02
+
+%P:-tsul
+%G:anus, asshole
+%IH:anus/asshole
+%C:N
+%P1s:stsul
+%SF:body-ext
+%S:STJA
+%UID:002171
+%MD:1999/02/23
+
+%P:-gan
+%G:arm
+%IH:arm
+%P1s:sgan
+%P2s:ngan
+%Pref:dugan
+%C:N
+%S:LITM/MAGO/STJA/JOPA/VESE/EDFR/JEKO
+%SF:body-ext
+%UID:000863
+%MD:1999/02/22
+
+%P:-chak'ests'oh
+%G:armpit
+%IH:armpit
+%P1s:schak'ests'oh
+%C:N
+%S:MAGO
+%UID:000859
+%SF:body-ext
+%MD:1997/12/11
+
+%P:-t'ak
+%G:back (of body)
+%IH:back (of body)
+%P1s:st'ak
+%P3s:but'ak
+%C:N
+%S:MAGO/EDFR/VESE/JEKO
+%SF:body-ext
+%UID:000899
+%MD:1997/12/11
+
+%P:-lat'ak
+%G:back of hand
+%IH:back of hand
+%P1s:slat'ak
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000871
+%MD:1997/12/11
+
+%P:tsake
+%G:beaver paws
+%IH:beaver paws
+%C:N
+%SF:body-ext
+%S:LITM-EDFR
+%UID:000329
+%MD:1997/06/18
+
+%P:tsache
+%G:beaver tail
+%IH:beaver tail
+%C:N
+%SF:body-ext
+%S:LITM
+%UID:000207
+%MD:1997/06/16
+
+%P:-but
+%G:belly
+%IH:belly
+%P1s:sbut
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000937
+%MD:1997/12/11
+
+%P:-ts'oo
+%G:breast
+%IH:breast
+%P1s:sts'oo
+%C:N
+%S:MAGO
+%UID:000855
+%SF:body-ext
+%MD:1997/12/11
+
+%P:-tl'a
+%G:bum, buttocks
+%IH:bum/buttocks
+%P1s:stl'a
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000936
+%MD:1997/12/11
+
+%P:-kechunch'ooz
+%G:calf of leg
+%IH:calf of leg
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%UID:004458
+%POCKET:Y
+%MD:2001/04/20
+
+%P:-nembus
+%G:cheek
+%IH:cheek
+%P1s:snimbus
+%C:N
+%S:MAGO/JOPA/BRBI
+%SF:body-ext
+%UID:000889
+%MD:1997/12/11
+
+%P:-yoh
+%G:chest
+%IH:chest
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%ES:000660
+%UID:003777
+%POCKET:Y
+%MD:2001/02/13
+
+%P:-yeda'
+%G:chin
+%IH:chin
+%P1s:syeda'
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000882
+%MD:1997/12/11
+
+%P:-tsidakwhudutle
+%G:cranial fontanelle, baby's soft spot
+%IH:cranial fontanelle/baby's soft spot
+%C:N
+%P3s:butsidakwhudutle
+%S:MAGO
+%SF:body-ext
+%UID:000898
+%MD:1997/12/11
+
+%P:-dzo
+%G:ear
+%IH:ear
+%MN:This refers to the ear considered as a whole, especially the exterior.
+ When the canal in particular is referred to, one uses {\qc -dzek}, q.v.
+%C:N
+%P1s:sdzo
+%S:MAGO
+%SF:body-ext
+%UID:000879
+%MD:1997/12/11
+
+%P:-dzobal
+%G:earlobe
+%IH:earlobe
+%C:N
+%P1s:sdzobal
+%SF:body-ext
+%S:BRBI/MAGO
+%UID:000641
+%MD:1997/12/17
+
+%P:-nints'uzti
+%G:elbow
+%IH:elbow
+%P1s:snints'uzti
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000916
+%MD:1997/12/11
+
+%P:-na
+%G:eye
+%IH:eye
+%P1s:sna
+%P3s:buna
+%C:N
+%S:MAGO/JOPA/EDFR
+%SF:body-ext
+%UID:000891
+%MD:1998/12/18
+
+%P:-nak'et
+%G:eye socket
+%IH:eye socket
+%P1s:snak'et
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000892
+%MD:1997/12/11
+
+%P:-nach'usdooz
+%G:eyebrow
+%IH:eyebrow
+%P1s:snach'usdooz
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000896
+%MD:1997/12/11
+
+%P:-nalusgha
+%G:eyelash
+%IH:eyelash
+%P1s:snalusgha
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000895
+%MD:1997/12/11
+
+%P:-nalus
+%G:eyelid
+%IH:eyelid
+%P1s:snalus
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000894
+%MD:1997/12/11
+
+%P:-nen
+%G:face
+%IH:face
+%P1s:snen
+%P2s:nyunen
+%P3s:bunen
+%C:N
+%S:MAGO/PEJO/STJA/JOPA/VESE/EDFR
+%SF:body-ext
+%ES:000369
+%UID:000890
+%MD:2001/04/20
+
+%P:ts'uz
+%G:feather, down
+%IH:feather/down
+%C:N
+%SF:body-ext
+%S:LITM/STJA/PEJO
+%UID:000271
+%MD:2000/10/16
+
+%P:dut'aits'uz
+%G:feathers, down
+%IH:feathers/down
+%C:N
+%SF:body-ext
+%S:STJA
+%UID:002647
+%MD:2001/02/27
+
+%P:-lasge
+%G:finger other than thumb or pinkie
+%IH:finger other than thumb or pinkie
+%P1s:slasge
+%C:N
+%S:MAGO/STJA/JOPA/PEJO/EDFR
+%SF:body-ext
+%UID:000869
+%MD:2000/11/01
+
+%P:-lagui
+%G:fingernails, claws of forepaws
+%IH:fingernails/claws of forepaws
+%P1s:slagui
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000875
+%MD:1997/12/11
+
+%P:-ke
+%G:foot
+%IH:foot
+%C:N
+%P1s:ske
+%Pref:duke
+%S:MAGO/STJA/JOPA/VESE/EDFR/JEKO
+%UID:000851
+%SF:body-ext
+%MD:1999/05/11
+
+%P:-gha
+%G:hair
+%MN:This refers to hair in general and where no more specific term exists, as on the
+ arms and chest. It is not used to refer to the hair of the head, for which the
+ more specific term {\qc -tsigha} is always used.
+%IH:hair
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000888
+%MD:1997/12/11
+
+%P:-tsigha
+%G:hair of the head
+%IH:hair of the head
+%P1s:stsigha
+%P2s:ntsigha
+%P3s:butsigha
+%C:N
+%S:MAGO/LITM/PEJO
+%SF:body-ext
+%UID:000887
+%MD:2000/10/20
+
+%P:-la
+%G:hand
+%IH:hand
+%P1s:sla
+%P2s:nla
+%C:N
+%S:MAGO/STJA
+%SF:body-ext
+%POCKET:Y
+%UID:000866
+%MD:1999/02/17
+
+%P:-tsi
+%G:head
+%IH:head
+%Pref:dutsi
+%C:N
+%SF:body-ext
+%S:STJA
+%UID:002965
+%POCKET:Y
+%MD:1999/06/24
+
+%P:-kelatsul
+%G:heel
+%IH:heel
+%P1s:skelatsul
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000917
+%MD:1997/12/11
+
+%P:-k'ui
+%G:hip
+%IH:hip
+%P1s:sk'ui
+%C:N
+%S:MAGO/JOPA
+%SF:body-ext
+%UID:000923
+%MD:2001/03/15
+
+%P:-gwut
+%G:knee
+%IH:knee
+%P1s:sgwut
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000933
+%MD:1997/12/11
+
+%P:-gwutlasi'ai
+%G:kneecap
+%IH:kneecap
+%P1s:sgwutlasi'ai
+%R:has something to do with floating at tip of knee
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000925
+%MD:1997/12/11
+
+%P:-langwut
+%G:knuckles at boundary between hand and fingers
+%IH:knuckles at boundary between hand and fingers
+%P1s:slangwut
+%SF:body-ext
+%C:N
+%S:JOPA/BRBI
+%UID:000967
+%MD:1997/12/17
+
+%P:-kechun
+%G:leg
+%IH:leg
+%P1s:skechun
+%C:N
+%S:MAGO
+%UID:000852
+%SF:body-ext
+%MD:1997/12/11
--- /dev/null
+%IH:exertion
+%P:nut'i
+%G:exertion
+%OIH:exertion
+%C:N
+%SF:abstractions-misc
+%S:JOPA/EDFR/VESE
+%ES:000088
+%UID:002463
+%MD:1999/03/15
+
+%IH:information
+%P:ts'iyantsuk t'eooninzun
+%G:information
+%OIH:information
+%C:N
+%SF:abstractions-misc
+%S:JOPA/BRBI
+%UID:000986
+%MD:1997/12/17
+
+%IH:interval
+%P:k'et'uk
+%G:interval
+%OIH:interval
+%C:N
+%SF:abstractions-misc
+%S:MAGO
+%ES:001077
+%UID:000873
+%MD:1997/12/11
+
+%IH:language
+%P:khunek
+%G:language, word, message
+%OIH:language/word/message
+%POSS:ghunek
+%P1p:neghunek
+%C:N
+%SF:abstractions-misc
+%S:MAGO/BRBI/JOPA/EDFR/VESE/JEKO
+%UID:000928
+%MD:2001/02/10
+
+%IH:word
+%P:khunek
+%G:language, word, message
+%OIH:language/word/message
+%POSS:ghunek
+%P1p:neghunek
+%C:N
+%SF:abstractions-misc
+%S:MAGO/BRBI/JOPA/EDFR/VESE/JEKO
+%UID:000928
+%MD:2001/02/10
+
+%IH:message
+%P:khunek
+%G:language, word, message
+%OIH:language/word/message
+%POSS:ghunek
+%P1p:neghunek
+%C:N
+%SF:abstractions-misc
+%S:MAGO/BRBI/JOPA/EDFR/VESE/JEKO
+%UID:000928
+%MD:2001/02/10
+
+%IH:running
+%P:gal
+%G:running
+%OIH:running
+%C:N
+%R:Dugal ndesda. He got hurt while running.
+%SF:abstractions-misc
+%S:JOPA
+%ES:000535
+%UID:002462
+%MD:1999/03/15
+
+%IH:work
+%P:t'en
+%G:work
+%OIH:work
+%C:N
+%SF:abstractions-misc
+%S:VESE/PEJO
+%ES:000672
+%UID:003028
+%POCKET:N
+%MD:2000/10/04
+
+%IH:work
+%P:'ut'en
+%G:work
+%OIH:work
+%C:N
+%SF:abstractions-misc
+%P1p:neye'ut'en
+%S:JOPA
+%ES:001041
+%UID:004264
+%POCKET:Y
+%MD:2001/03/15
+
+%IH:Spotted Frog
+%P:dulkw'ah
+%G:Spotted Frog
+%OIH:Spotted Frog/Frog, Spotted
+%SN:Rana pretiosa
+%MN:Lives in water and has red markings on the belly.
+%PICTURE:/home/poser/Research/Dakelh/Pictures/psfiles/SpottedFrog.ps
+%CAPTION:{\qc Tsasdli} --- Spotted Frog
+%PICPERMISSION:N
+%PICCREDIT:Drawing of Spotted Frog from {\it The Amphibians of British Columbia\/}.
+%C:N
+%SF:amphibiansandreptiles
+%S:EDFR
+%UID:004111
+%POCKET:Y
+%MD:2001/03/07
+
+%IH:Frog, Spotted
+%P:dulkw'ah
+%G:Spotted Frog
+%OIH:Spotted Frog/Frog, Spotted
+%SN:Rana pretiosa
+%MN:Lives in water and has red markings on the belly.
+%PICTURE:/home/poser/Research/Dakelh/Pictures/psfiles/SpottedFrog.ps
+%CAPTION:{\qc Tsasdli} --- Spotted Frog
+%PICPERMISSION:N
+%PICCREDIT:Drawing of Spotted Frog from {\it The Amphibians of British Columbia\/}.
+%C:N
+%SF:amphibiansandreptiles
+%S:EDFR
+%UID:004111
+%POCKET:Y
+%MD:2001/03/07
+
+%IH:lizard
+%P:chunlai
+%G:salamander, lizard
+%OIH:lizard/salamander
+%MN:The only species of salamander found in the region is the
+ Long-toed Salamander {\it Ambystoma macrodactylum\/}. No lizards
+ are found in the region. However, this term is applied to other
+ varieties of salamander and to lizards, such as the gekkos sold as
+ pets.
+%FGREF:Corkran \& Thoms (1996;39)
+%SN:Ambystoma macrodactylum
+%C:N
+%SF:amphibiansandreptiles
+%S:LITM/JOPA/BRBI
+%UID:000157
+%MD:1998/05/16
+
+%IH:salamander
+%P:chunlai
+%G:salamander, lizard
+%OIH:lizard/salamander
+%MN:The only species of salamander found in the region is the
+ Long-toed Salamander {\it Ambystoma macrodactylum\/}. No lizards
+ are found in the region. However, this term is applied to other
+ varieties of salamander and to lizards, such as the gekkos sold as
+ pets.
+%FGREF:Corkran \& Thoms (1996;39)
+%SN:Ambystoma macrodactylum
+%C:N
+%SF:amphibiansandreptiles
+%S:LITM/JOPA/BRBI
+%UID:000157
+%MD:1998/05/16
+
+%IH:snake
+%P:tl'ughus
+%G:snake
+%OIH:snake
+%C:N
+%MN:The only snake found in the region is the Common Garter Snake
+ {\it Thamnophis sirtalis\/}. However, the term is applied to all snakes.
+%SN:Thamnophis sirtalis
+%SF:amphibiansandreptiles
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000250
+%MD:1998/12/07
+
+%IH:Western Toad
+%P:tsasdli
+%G:Western Toad
+%SN:Bufo boreas
+%OIH:Western Toad/Toad, Western
+%MN:Lives on land.
+%SF:amphibiansandreptiles
+%C:N
+%S:LITM/JOPA/BRBI/MAGO/STJA/EDFR
+%UID:000059
+%MD:2001/03/07
+
+%IH:Toad, Western
+%P:tsasdli
+%G:Western Toad
+%SN:Bufo boreas
+%OIH:Western Toad/Toad, Western
+%MN:Lives on land.
+%SF:amphibiansandreptiles
+%C:N
+%S:LITM/JOPA/BRBI/MAGO/STJA/EDFR
+%UID:000059
+%MD:2001/03/07
+
+%IH:bitch
+%P:lhits'e
+%G:bitch, female dog
+%OIH:bitch/dog, female
+%C:N
+%SF:animals-domestic
+%S:JOPA/EDFR/VESE
+%UID:002446
+%MD:1999/03/15
+
+%IH:dog, female
+%P:lhits'e
+%G:bitch, female dog
+%OIH:bitch/dog, female
+%C:N
+%SF:animals-domestic
+%S:JOPA/EDFR/VESE
+%UID:002446
+%MD:1999/03/15
+
+%IH:cow
+%P:musdus
+%G:cow
+%OIH:cow
+%C:N
+%P2s:nmusdus
+%ETYM:Loan from Cree {\qf mostos} ``buffalo''.
+%LOANSOURCE:Cree
+%SF:animals-domestic
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000036
+%MD:1997/06/12
+
+%IH:dog
+%P:lhi
+%G:dog
+%OIH:dog
+%C:N
+%DUOPLURAL:lhike
+%SF:animals-domestic
+%POSS:lik
+%P1s:slik
+%P1p:nelik
+%DUOPLURAL:lhike
+%S:LITM/JOPA/BRBI/STJA/VESE/EDFR/JEKO
+%UID:000270
+%MD:2001/02/15
+
+%IH:donkey
+%P:budzocho
+%G:donkey, mule
+%OIH:donkey/mule
+%SF:animals-domestic
+%ETYM:``big ears''.
+%C:N
+%S:JOPA/BRBI
+%UID:000376
+%MD:1997/11/14
+
+%IH:mule
+%P:budzocho
+%G:donkey, mule
+%OIH:donkey/mule
+%SF:animals-domestic
+%ETYM:``big ears''.
+%C:N
+%S:JOPA/BRBI
+%UID:000376
+%MD:1997/11/14
+
+%IH:horse
+%P:yeztli
+%G:horse
+%OIH:horse
+%SF:animals-domestic
+%ETYM:A contraction of {\qc yezihlhi} ``elk dog''.
+%C:N
+%S:LITM/JOPA/BRBI/PEJO
+%UID:000042
+%MD:2000/10/21
+
+%IH:dogs
+%P:lhike
+%G:Irregular plural of {\qc lhi}, q.v.
+%OIH:dogs
+%C:N
+%SF:animals-domestic
+%S:LITM/BRBI/JOPA/STJA
+%UID:000293
+%MD:1999/01/26
+
+%IH:lamb
+%P:sbaiyaz
+%G:lamb
+%OIH:lamb
+%C:N
+%SF:animals-domestic
+%S:LITM
+%UID:000254
+%MD:1997/06/16
+
+%IH:pig
+%P:gugoos
+%G:pig
+%OIH:pig
+%C:N
+%ETYM:Ultimately borrowed from French {\qf coche}, probably via Cree.
+%LOANSOURCE:Cree
+%SF:animals-domestic
+%S:LITM/JOPA/BRBI
+%UID:000133
+%MD:1997/06/16
+
+%IH:bat
+%P:'ut'az
+%G:bat
+%OIH:bat
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000390
+%MD:1997/11/14
+
+%IH:bat
+%P:liyabdut'ai
+%G:bat
+%MN:The only kind of bat found in the region is the Little Brown Myotis.
+%OIH:bat
+%SF:animals-land
+%SN:Myotis lucifugus
+%ETYM:Literally, ``devil bird'', a compound of {\qc liyab} ``devil'', a loan from
+ French {\qf le diable}, and {\qc dut'ai} ``bird''.
+%LOANSOURCE:French
+%C:N
+%S:JOPA/BRBI
+%UID:000215
+%MD:1997/06/16
+
+%IH:black bear
+%P:sus
+%G:black bear
+%OIH:black bear
+%C:N
+%SF:animals-land
+%SN:Ursus americanus
+%S:LITM/JOPA/BRBI/STJA/EDFR/VESE/JEKO
+%UID:000048
+%MD:1998/12/19
+
+%IH:buffalo
+%P:musduscho dughai
+%G:buffalo
+%OIH:buffalo
+%SF:animals-land
+%C:N
+%ETYM:``big hairy cow''.
+%S:JOPA/EDFR
+%UID:003478
+%POCKET:Y
+%MD:2000/11/04
+
+%IH:buffalo
+%P:tl'ok'umusdus
+%G:buffalo
+%OIH:buffalo
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000374
+%MD:2000/11/01
+
+%IH:bull moose
+%P:jenyo
+%G:bull moose
+%OIH:bull moose/moose, bull
+%SF:animals-land
+%C:N
+%S:MAGO/JOPA/VESE/EDFR/JEKO
+%UID:000474
+%MD:1999/05/11
+
+%IH:moose, bull
+%P:jenyo
+%G:bull moose
+%OIH:bull moose/moose, bull
+%SF:animals-land
+%C:N
+%S:MAGO/JOPA/VESE/EDFR/JEKO
+%UID:000474
+%MD:1999/05/11
+
+%IH:moose, bull
+%P:denyo
+%G:bull moose
+%OIH:moose, bull
+%SF:animals-land
+%C:N
+%S:LITM/JOPA
+%UID:000348
+%MD:1997/06/18
+
+%IH:calf moose
+%P:tsiyeyaz
+%G:calf moose
+%OIH:calf moose/moose, calf
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000380
+%MD:1997/11/14
+
+%IH:moose, calf
+%P:tsiyeyaz
+%G:calf moose
+%OIH:calf moose/moose, calf
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000380
+%MD:1997/11/14
+
+%IH:calf moose
+%P:duniyaz
+%G:calf moose
+%OIH:calf moose/moose, calf
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000245
+%MD:1997/06/16
+
+%IH:moose, calf
+%P:duniyaz
+%G:calf moose
+%OIH:calf moose/moose, calf
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000245
+%MD:1997/06/16
+
+%IH:caribou
+%P:whudzih
+%G:caribou
+%OIH:caribou
+%C:N
+%SF:animals-land
+%SN:Rangifer tarandus
+%S:JOPA/BRBI/MAGO/EDFR/VESE/JEKO
+%UID:000274
+%MD:1999/05/11
+
+%IH:cat
+%P:boos
+%G:cat
+%OIH:cat
+%C:N
+%SN:Felis domesticus
+%ETYM:Loan from English {\qf puss}, possibly via Chinook Jargon.
+%LOANSOURCE:English
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000137
+%MD:1997/12/17
+
+%IH:chipmunk
+%P:ts'uwhuljos
+%G:chipmunk
+%OIH:chipmunk
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI
+%UID:000146
+%MD:1997/06/16
+
+%IH:cougar
+%P:booscho
+%G:cougar
+%OIH:cougar
+%SF:animals-land
+%SN:Felis concolor
+%C:N
+%ETYM:Literally, ``big cat'', where {\qc boos} ``cat'' is a loan from English
+ {\qf puss}, possibly via Chinook Jargon.
+%S:JOPA/BRBI
+%UID:000050
+%MD:1997/11/14
+
+%IH:cow moose
+%P:duni'at
+%G:cow moose
+%OIH:cow moose/moose, cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000377
+%MD:1997/11/14
+
+%IH:moose, cow
+%P:duni'at
+%G:cow moose
+%OIH:cow moose/moose, cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000377
+%MD:1997/11/14
+
+%IH:coyote
+%P:tintulhi
+%G:coyote
+%OIH:coyote
+%C:N
+%SF:animals-land
+%SN:Canis latrans
+%S:JOPA/BRBI
+%R:LITM has chuntulhi.
+%UID:000155
+%MD:1997/06/16
+
+%IH:deer
+%P:yests'e
+%G:deer
+%OIH:deer
+%SF:animals-land
+%C:N
+%S:LITM/JOPA/BRBI/EDFR
+%UID:000132
+%MD:1998/12/16
+
+%IH:dry cow moose
+%P:dets'it
+%G:dry cow moose
+%OIH:dry cow moose/moose, dry cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000378
+%MD:1997/11/14
+
+%IH:moose, dry cow
+%P:dets'it
+%G:dry cow moose
+%OIH:dry cow moose/moose, dry cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000378
+%MD:1997/11/14
+
+%IH:elk
+%P:yezih
+%G:elk
+%OIH:elk
+%SF:animals-land
+%C:N
+%R:STJA doesn't use this.
+%S:JOPA/BRBI
+%UID:000382
+%MD:1997/11/14
+
+%IH:beaver, female
+%P:tsa'at
+%G:female beaver
+%OIH:beaver, female
+%C:N
+%SF:animals-land
+%S:STJA
+%UID:001295
+%MD:1998/12/08
+
+%IH:fisher
+%P:chunihcho
+%G:fisher
+%OIH:fisher
+%ETYM:``big marten''.
+%SF:animals-land
+%SN:Martes pennanti
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000385
+%MD:2000/06/18
+
+%IH:flying squirrel
+%P:ts'unalhbuz
+%G:flying squirrel
+%OIH:flying squirrel
+%SF:animals-land
+%SN:Glaucomys sabrinus alpinus
+%PICTURE:/home/poser/Research/Dakelh/Pictures/psfiles/FlyingSquirrel.ps
+%CAPTION:{\qc ts'unulhbuz} --- Flying Squirrel
+%PICPERMISSION:N
+%PICCREDIT:Drawing of Flying Squirrel from {\it The Mammals of British Columbia\/}.
+%C:N
+%S:JOPA/BRBI
+%UID:000389
+%MD:1997/11/14
+
+%IH:fox
+%P:nanguz
+%G:fox
+%OIH:fox
+%C:N
+%SF:animals-land
+%S:MAGO
+%UID:000139
+%MD:2001/02/26
+
+%IH:grizzly bear
+%P:shas
+%G:grizzly bear
+%OIH:grizzly bear
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI/VESE/EDFR/JEKO
+%UID:000039
+%MD:1997/06/12
+
+%IH:grizzly bear cub
+%P:shasyaz
+%G:grizzly bear cub
+%OIH:grizzly bear cub/cub, grizzly bear
+%C:N
+%SF:animals-land
+%S:STJA
+%UID:002114
+%MD:1999/02/20
+
+%IH:cub, grizzly bear
+%P:shasyaz
+%G:grizzly bear cub
+%OIH:grizzly bear cub/cub, grizzly bear
+%C:N
+%SF:animals-land
+%S:STJA
+%UID:002114
+%MD:1999/02/20
+
+%IH:grizzly bear sow
+%P:shas'at
+%G:grizzly bear sow
+%OIH:grizzly bear sow/sow, grizzly bear
+%C:N
+%SF:animals-land
+%ETYM:``grizzly bear's wife''.
+%S:STJA
+%UID:002113
+%MD:1999/02/20
+
+%IH:sow, grizzly bear
+%P:shas'at
+%G:grizzly bear sow
+%OIH:grizzly bear sow/sow, grizzly bear
+%C:N
+%SF:animals-land
+%ETYM:``grizzly bear's wife''.
+%S:STJA
+%UID:002113
+%MD:1999/02/20
+
+%IH:lynx
+%P:wasi
+%G:lynx
+%OIH:lynx
+%C:N
+%SF:animals-land
+%SN:Felis lynx
+%ETYM:Loan from Gitksan {\qf wish}.
+%LOANSOURCE:Gitksan
+%S:JOPA/BRBI/STJA/EDFR/VESE/JEKO/MAGO
+%UID:000049
+%MD:2001/04/20
+
+%IH:woodchuck
+%P:k'ani
+%G:woodchuck
+%OIH:woodchuck
+%C:N
+%SF:animals-land
+%SN:Marmota monax
+%S:JOPA/BRBI/PEJO
+%R:Clarified with Josie and Peter 2001/05/28.
+%UID:000391
+%POCKET:Y
+%MD:2001/05/28
+
+%IH:marmot
+%P:dutni
+%G:marmot
+%OIH:marmot
+%SF:animals-land
+%C:N
+%SN:Marmota caligata
+%R:Josie and Peter are not really familiar with marmots but have heard older
+ people talk about them.
+%S:JOPA/PEJO
+%UID:000143
+%MD:1998/02/10
+
+%IH:marten
+%P:chunih
+%G:marten
+%OIH:marten
+%SF:animals-land
+%SN:Martes americana
+%C:N
+%S:JOPA/BRBI/VESE/EDFR/JEKO/MAGO
+%UID:000016
+%MD:2001/04/20
+
+%IH:mink
+%P:telhjoos
+%G:mink
+%OIH:mink
+%C:N
+%SF:animals-land
+%SN:Mustela vison
+%S:LITM/JOPA/BRBI
+%UID:000167
+%MD:1997/06/16
+
+%IH:moose
+%P:duni
+%G:moose
+%OIH:moose
+%C:N
+%SF:animals-land
+%SN:Alces alces andersoni
+%S:LITM-EDFR/JOPA/BRBI
+%UID:000346
+%MD:1997/06/18
+
+%IH:mouse
+%P:dats'ooz
+%G:mouse
+%OIH:mouse
+%SF:animals-land
+%C:N
+%S:LITM/JOPA/MAGO/VESE/JEKO
+%UID:000156
+%MD:2001/01/22
+
+%IH:muskrat
+%P:tsek'et
+%G:muskrat
+%OIH:muskrat
+%C:N
+%SF:animals-land
+%SN:Ondatra zibethicus
+%S:JOPA/BRBI/STJA/MAGO
+%UID:000335
+%MD:1998/12/08
+
+%IH:moose, newly sexually mature cow
+%P:chanjo
+%G:newly sexually mature cow moose
+%OIH:moose, newly sexually mature cow
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000379
+%MD:1997/11/14
+
+%IH:pack rat
+%P:looncho
+%G:pack rat
+%OIH:pack rat
+%C:N
+%SF:animals-land
+%S:VESE/JEKO/MAGO
+%UID:000149
+%MD:1999/05/10
+
+%IH:packrat
+%P:dlooncho
+%G:packrat
+%OIH:packrat
+%C:N
+%SF:animals-land
+%S:JOPA
+%UID:002701
+%MD:1999/05/11
+
+%IH:porcupine
+%P:duneza
+%G:porcupine
+%OIH:porcupine
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000388
+%MD:2001/03/06
+
+%IH:porcupine
+%P:ts'it
+%G:porcupine
+%OIH:porcupine
+%SF:animals-land
+%SN:Erethizon dorsatum
+%C:N
+%ETYM:Perhaps derived from the interjection {\qc ts'it} ``don't touch it!''.
+%S:JOPA/BRBI/MAGO/BEMC/STJA
+%UID:000387
+%MD:1998/12/08
+
+%IH:puppy
+%P:lhiyaz
+%G:puppy
+%OIH:puppy
+%C:N
+%SF:animals-land
+%DUOPLURAL:lhiyazke
+%DUOPLURAL:lhikeyaz
+%R:Josie prefers {\qc lhikeyaz}.
+%S:LITM/BRBI/JOPA/EDFR/MAGO-JEKO
+%UID:000182
+%MD:2001/05/26
+
+%IH:squirrel
+%P:nats'ildelh
+%G:Red Squirrel
+%OIH:squirrel/Red Squirrel
+%SN:Tamiasciurus hudsonicus colum.
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI/STJA
+%UID:000034
+%MD:1999/02/17
+
+%IH:Red Squirrel
+%P:nats'ildelh
+%G:Red Squirrel
+%OIH:squirrel/Red Squirrel
+%SN:Tamiasciurus hudsonicus colum.
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/BRBI/STJA
+%UID:000034
+%MD:1999/02/17
+
+%IH:rabbit
+%P:goh
+%G:rabbit
+%OIH:rabbit
+%C:N
+%SF:animals-land
+%S:LITM/JOPA/VESE/EDFR/JEKO
+%UID:000023
+%MD:1999/05/11
+
+%IH:moose, recently weaned calf
+%P:ooch'ainischoot
+%G:recently weaned calf moose
+%OIH:moose, recently weaned calf
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000381
+%MD:1997/11/14
+
+%IH:sheep
+%P:sbai
+%G:sheep
+%OIH:sheep
+%C:N
+%SF:animals-land
+%S:MAGO
+%UID:001131
+%MD:1998/02/10
+
+%IH:sheep
+%P:'usbai
+%G:sheep
+%OIH:sheep
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI
+%UID:000375
+%MD:1997/11/14
+
+%IH:shrew
+%P:'ulhguk
+%G:shrew
+%OIH:shrew
+%SF:animals-land
+%C:N
+%S:MAGO/VESE/JEKO
+%UID:000526
+%MD:2001/01/22
+
+%IH:skunk
+%P:hoonliz
+%G:skunk
+%OIH:skunk
+%C:N
+%P2s:unhoonliz
+%SF:animals-land
+%S:LITM/JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000052
+%MD:1997/06/12
+
+%IH:weasel
+%P:nohbai
+%G:weasel
+%OIH:weasel
+%C:N
+%SF:animals-land
+%S:JOPA/BRBI/MAGO
+%UID:000141
+%MD:1997/06/16
+
+%IH:wolf
+%P:yus
+%G:wolf
+%OIH:wolf
+%C:N
+%SF:animals-land
+%SN:Canis lupus
+%S:LITM/JOPA/BRBI
+%UID:000051
+%MD:1997/06/12
+
+%IH:wolverine
+%P:noostel
+%G:wolverine
+%OIH:wolverine
+%C:N
+%SF:animals-land
+%SN:Gulo gulo
+%S:JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000140
+%MD:2001/04/20
+
+%IH:beaver, young
+%P:tsatsul
+%G:young beaver
+%OIH:beaver, young
+%SF:animals-land
+%C:N
+%S:JOPA/BRBI/STJA
+%UID:000384
+%MD:1998/12/08
+
+%IH:beaver dam
+%P:lht'at
+%G:beaver dam
+%OIH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001287
+%MD:1998/12/08
+
+%IH:dam, beaver
+%P:lht'at
+%G:beaver dam
+%OIH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001287
+%MD:1998/12/08
+
+%IH:beaver dam
+%P:'ulh
+%G:beaver dam
+%OIH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001288
+%MD:1998/12/08
+
+%IH:dam, beaver
+%P:'ulh
+%G:beaver dam
+%OIH:beaver dam/dam, beaver
+%C:N
+%SF:animals-misc
+%S:STJA
+%UID:001288
+%MD:1998/12/08
+
+%IH:beaver lodge
+%P:tsaken
+%G:beaver lodge
+%OIH:beaver lodge
+%C:N
+%SF:animals-misc
+%S:JOPA/BRBI/STJA
+%UID:000405
+%MD:1998/12/08
+
+%IH:beaver path under the ice
+%P:tunyohtsati
+%G:beaver path under the ice
+%OIH:beaver path under the ice
+%C:N
+%SF:animals-misc
+%S:JOPA/EDFR
+%UID:003769
+%POCKET:Y
+%MD:2001/02/13
+
+%IH:black bear den
+%P:sus'an
+%G:black bear den
+%OIH:black bear den
+%C:N
+%SF:animals-misc
+%S:LITM/STJA
+%UID:000131
+%MD:1998/12/08
+
+%IH:tracks, grizzly bear
+%P:shask'oh
+%G:grizzly bear tracks
+%OIH:tracks, grizzly bear
+%C:N
+%SF:animals-misc
+%S:MAGO
+%UID:001132
+%MD:1998/02/10
+
+%IH:leech
+%P:hoolht'ukw
+%G:leech
+%OIH:leech
+%SF:animals-misc
+%C:N
+%S:JOPA/PEJO/EDFR
+%UID:003410
+%POCKET:Y
+%MD:2000/11/01
+
+%IH:leech
+%P:hoot'ub
+%G:leech
+%OIH:leech
+%SF:bugs
+%C:N
+%S:JOPA/BRBI/MAGO
+%UID:000370
+%MD:2000/11/01
+
+%IH:moose tracks
+%P:dunik'oh
+%G:moose tracks
+%OIH:moose tracks
+%C:N
+%SF:animals-misc
+%S:PEJO/JOPA
+%ES:000491
+%UID:003121
+%POCKET:Y
+%MD:2000/09/28
+
+%IH:tracks, rabbit
+%P:gohk'oh
+%G:rabbit tracks
+%OIH:tracks, rabbit
+%C:N
+%SF:animals-misc
+%S:LITM
+%UID:000073
+%MD:1997/06/12
+
+%IH:beaver
+%P:tsa
+%G:beaver
+%OIH:beaver
+%C:N
+%SN:Castor canadensis
+%UID:000044
+%SF:animals-water
+%S:JOPA/BRBI/STJA/EDFR/VESE/JEKO/MAGO
+%MD:2001/04/18
+
+%IH:kit, beaver
+%P:tsayaz
+%G:beaver kit
+%OIH:kit, beaver/beaver, baby
+%SF:animals-water
+%C:N
+%S:STJA
+%UID:001294
+%MD:2000/06/18
+
+%IH:beaver, baby
+%P:tsayaz
+%G:beaver kit
+%OIH:kit, beaver/beaver, baby
+%SF:animals-water
+%C:N
+%S:STJA
+%UID:001294
+%MD:2000/06/18
+
+%IH:beaver, big
+%P:tsati
+%G:big beaver, old beaver
+%OIH:beaver, big/beaver, old
+%C:N
+%SF:animals-water
+%S:LITM/JOPA/BRBI/STJA
+%UID:000206
+%MD:1998/12/08
+
+%IH:beaver, old
+%P:tsati
+%G:big beaver, old beaver
+%OIH:beaver, big/beaver, old
+%C:N
+%SF:animals-water
+%S:LITM/JOPA/BRBI/STJA
+%UID:000206
+%MD:1998/12/08
+
+%IH:otter
+%P:tsis
+%G:otter
+%OIH:otter
+%SF:animals-water
+%SN:Lutra canadensis
+%C:N
+%S:JOPA/BRBI
+%UID:000386
+%MD:1997/11/14
+
+%IH:crow
+%P:datsan
+%G:American Crow
+%C:N
+%SF:bird-gen
+%SN:Corvus brachyrhynchos
+%OIH:crow/American Crow
+%S:LITM/PEJO
+%UID:000158
+%MD:2000/10/21
+
+%IH:American Crow
+%P:datsan
+%G:American Crow
+%C:N
+%SF:bird-gen
+%SN:Corvus brachyrhynchos
+%OIH:crow/American Crow
+%S:LITM/PEJO
+%UID:000158
+%MD:2000/10/21
+
+%IH:Robin, American
+%P:sewh
+%G:American Robin
+%OIH:Robin, American
+%SN:Turdus migratorius
+%C:N
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/PEJO
+%UID:000181
+%MD:2000/10/21
+
+%IH:Bald Eagle
+%P:tsebalyan
+%G:Bald Eagle
+%OIH:Bald Eagle
+%C:N
+%SF:bird-gen
+%SN:Haliaeetus leucocephalus
+%S:LITM/JOPA/BRBI
+%UID:000150
+%MD:1997/06/16
+
+%IH:bird
+%P:dut'ai
+%G:bird, duck
+%OIH:bird/duck
+%C:N
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO/STJA/PEJO
+%UID:000081
+%MD:2000/09/28
+
+%IH:duck
+%P:dut'ai
+%G:bird, duck
+%OIH:bird/duck
+%C:N
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO/STJA/PEJO
+%UID:000081
+%MD:2000/09/28
+
+%IH:crane
+%P:delh
+%G:crane
+%OIH:crane
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000255
+%MD:1997/06/16
+
+%IH:goose
+%P:khoh
+%G:goose
+%OIH:goose
+%C:N
+%P1s:skhoh
+%P2s:nkhoh
+%P1p:nekhoh
+%POSS:khoh
+%SF:bird-gen
+%S:JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000031
+%MD:2001/02/15
+
+%IH:hummingbird
+%P:ts'unalhduz
+%G:hummingbird
+%OIH:hummingbird
+%C:N
+%SF:bird-gen
+%S:LITM/BRBI/JOPA
+%UID:000242
+%MD:1997/06/16
+
+%IH:bird, little
+%P:gagiyaz
+%G:little bird
+%OIH:bird, little
+%C:N
+%QCHECK:Any little bird?
+%SF:bird-gen
+%S:PEJO
+%UID:003115
+%POCKET:Y
+%MD:2000/09/28
+
+%IH:bird, little
+%P:dut'aiyaz
+%G:little bird
+%OIH:bird, little
+%C:N
+%SF:bird-gen
+%S:STJA/JOPA/EDFR/VESE/PEJO
+%UID:001818
+%MD:2000/09/28
+
+%IH:loon
+%P:dadzi
+%G:loon
+%OIH:loon
+%SF:bird-gen
+%SN:Gavia immer
+%C:N
+%S:LITM/JOPA/BRBI
+%UID:000020
+%MD:1997/06/12
+
+%IH:Mallard Duck
+%P:t'ugicho
+%G:Mallard Duck
+%OIH:Mallard Duck
+%C:N
+%SN:Anas platyrhynchos
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO/VESE/EDFR/JEKO
+%UID:000041
+%MD:1999/05/11
+
+%IH:owl
+%P:musdzoon
+%G:owl
+%OIH:owl
+%C:N
+%SF:bird-gen
+%S:LITM/BRBI/JOPA/MAGO
+%UID:000135
+%MD:1997/12/11
+
+%IH:Red-Necked Grebe
+%P:ts'olh
+%G:Red-necked Grebe
+%MN:A variety of duck locally known as the Helldiver.
+%OIH:Red-Necked Grebe/Helldiver/Grebe, Red-Necked
+%SN:Podiceps grisegena
+%SF:bird-gen
+%C:N
+%S:BRBI/JOPA
+%UID:000263
+%MD:2001/03/08
+
+%IH:Helldiver
+%P:ts'olh
+%G:Red-necked Grebe
+%MN:A variety of duck locally known as the Helldiver.
+%OIH:Red-Necked Grebe/Helldiver/Grebe, Red-Necked
+%SN:Podiceps grisegena
+%SF:bird-gen
+%C:N
+%S:BRBI/JOPA
+%UID:000263
+%MD:2001/03/08
+
+%IH:Grebe, Red-Necked
+%P:ts'olh
+%G:Red-necked Grebe
+%MN:A variety of duck locally known as the Helldiver.
+%OIH:Red-Necked Grebe/Helldiver/Grebe, Red-Necked
+%SN:Podiceps grisegena
+%SF:bird-gen
+%C:N
+%S:BRBI/JOPA
+%UID:000263
+%MD:2001/03/08
+
+%IH:Ruffed grouse
+%P:'utsut
+%G:Ruffed grouse
+%OIH:Ruffed grouse
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000218
+%MD:1997/06/16
+
+%IH:Spruce Grouse
+%P:nat'oh
+%G:Spruce Grouse, Fool Hen
+%OIH:Spruce Grouse/Grouse, Spruce/Fool Hen
+%SF:bird-gen
+%SN:Dendragapus canadensis
+%C:N
+%S:MAGO/LITM
+%UID:000539
+%MD:1997/12/04
+
+%IH:Grouse, Spruce
+%P:nat'oh
+%G:Spruce Grouse, Fool Hen
+%OIH:Spruce Grouse/Grouse, Spruce/Fool Hen
+%SF:bird-gen
+%SN:Dendragapus canadensis
+%C:N
+%S:MAGO/LITM
+%UID:000539
+%MD:1997/12/04
+
+%IH:Fool Hen
+%P:nat'oh
+%G:Spruce Grouse, Fool Hen
+%OIH:Spruce Grouse/Grouse, Spruce/Fool Hen
+%SF:bird-gen
+%SN:Dendragapus canadensis
+%C:N
+%S:MAGO/LITM
+%UID:000539
+%MD:1997/12/04
+
+%IH:Steller's Jay
+%P:tehgwuzeh
+%G:Steller's Jay, commonly known locally as ``bluejay''.
+%OIH:Steller's Jay/jay, Steller's/Bluejay (Steller's Jay)
+%SF:bird-gen
+%SN:Cyanocitta stelleri
+%C:N
+%S:JOPA/BRBI
+%UID:000356
+%MD:1997/11/14
+
+%IH:jay, Steller's
+%P:tehgwuzeh
+%G:Steller's Jay, commonly known locally as ``bluejay''.
+%OIH:Steller's Jay/jay, Steller's/Bluejay (Steller's Jay)
+%SF:bird-gen
+%SN:Cyanocitta stelleri
+%C:N
+%S:JOPA/BRBI
+%UID:000356
+%MD:1997/11/14
+
+%IH:Bluejay (Steller's Jay)
+%P:tehgwuzeh
+%G:Steller's Jay, commonly known locally as ``bluejay''.
+%OIH:Steller's Jay/jay, Steller's/Bluejay (Steller's Jay)
+%SF:bird-gen
+%SN:Cyanocitta stelleri
+%C:N
+%S:JOPA/BRBI
+%UID:000356
+%MD:1997/11/14
+
+%IH:sandpiper
+%P:wedlew
+%G:sandpiper
+%OIH:sandpiper
+%C:N
+%SN:Eremophila alpestris et sim.
+%SF:bird-gen
+%S:LITM
+%UID:000237
+%MD:2002/07/19
+
+%IH:seagull
+%P:besk'i
+%G:seagull
+%OIH:seagull
+%C:N
+%SN:Larus species
+%SF:bird-gen
+%S:LITM
+%UID:000136
+%MD:2002/07/19
+
+%IH:swan
+%P:ts'incho
+%G:swan
+%OIH:swan
+%C:N
+%SF:bird-gen
+%S:LITM
+%UID:000222
+%MD:1997/06/16
+
+%IH:Tree Swallow
+%P:'uschas
+%G:Tree Swallow
+%OIH:Tree Swallow
+%SF:bird-gen
+%SN:Tachycineta bicolor
+%C:N
+%S:MAGO
+%UID:000535
+%MD:1997/11/22
+
+%IH:Whiskey Jack
+%P:gwuzeh
+%G:Whiskey Jack, Gray Jay, Canadian Jay
+%OIH:Whiskey Jack/Jay, Gray/Jay, Canadian
+%C:N
+%SN:Perisoreus canadensis
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000148
+%MD:1997/11/22
+
+%IH:Jay, Gray
+%P:gwuzeh
+%G:Whiskey Jack, Gray Jay, Canadian Jay
+%OIH:Whiskey Jack/Jay, Gray/Jay, Canadian
+%C:N
+%SN:Perisoreus canadensis
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000148
+%MD:1997/11/22
+
+%IH:Jay, Canadian
+%P:gwuzeh
+%G:Whiskey Jack, Gray Jay, Canadian Jay
+%OIH:Whiskey Jack/Jay, Gray/Jay, Canadian
+%C:N
+%SN:Perisoreus canadensis
+%SF:bird-gen
+%S:LITM/JOPA/BRBI/MAGO
+%UID:000148
+%MD:1997/11/22
+
+%IH:woodpecker
+%P:chundulkw'uz
+%G:woodpecker
+%OIH:woodpecker
+%C:N
+%SF:bird-gen
+%S:JOPA/BRBI/STJA
+%UID:000138
+%MD:1999/03/31
+
+%IH:nest
+%P:-t'o
+%G:nest
+%OIH:nest
+%C:N
+%Pind:'ut'o
+%P3s:but'o
+%Pref:dut'o
+%SF:bird-misc/bugs
+%S:STJA/PEJO/JOPA/BRBI/EDFR
+%ES:001353
+%UID:000226
+%MD:2001/03/07
+
+%IH:eye, a single
+%P:-nak'uz
+%G:a single eye
+%OIH:eye, a single
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%ES:000457
+%UID:003770
+%POCKET:Y
+%MD:2001/02/13
+
+%IH:ankle
+%P:-kechunoh
+%G:ankle
+%OIH:ankle
+%P1s:skechunoh
+%P2s:nkechunoh
+%C:N
+%S:MAGO/STJA
+%SF:body-ext
+%UID:000865
+%MD:1999/03/03
+
+%IH:antler
+%P:-de
+%G:antler, horn
+%OIH:antler/horn
+%C:N
+%SF:body-ext
+%P3s:bude
+%S:STJA
+%UID:002266
+%MD:1999/03/02
+
+%IH:horn
+%P:-de
+%G:antler, horn
+%OIH:antler/horn
+%C:N
+%SF:body-ext
+%P3s:bude
+%S:STJA
+%UID:002266
+%MD:1999/03/02
+
+%IH:velvet, antler
+%P:-de_zu_s
+%G:antler velvet
+%OIH:velvet, antler
+%C:N
+%SF:body-ext
+%P3s:bude_zu_s
+%S:STJA
+%UID:002267
+%MD:1999/03/02
+
+%IH:anus
+%P:-tsul
+%G:anus, asshole
+%OIH:anus/asshole
+%C:N
+%P1s:stsul
+%SF:body-ext
+%S:STJA
+%UID:002171
+%MD:1999/02/23
+
+%IH:asshole
+%P:-tsul
+%G:anus, asshole
+%OIH:anus/asshole
+%C:N
+%P1s:stsul
+%SF:body-ext
+%S:STJA
+%UID:002171
+%MD:1999/02/23
+
+%IH:arm
+%P:-gan
+%G:arm
+%OIH:arm
+%P1s:sgan
+%P2s:ngan
+%Pref:dugan
+%C:N
+%S:LITM/MAGO/STJA/JOPA/VESE/EDFR/JEKO
+%SF:body-ext
+%UID:000863
+%MD:1999/02/22
+
+%IH:armpit
+%P:-chak'ests'oh
+%G:armpit
+%OIH:armpit
+%P1s:schak'ests'oh
+%C:N
+%S:MAGO
+%UID:000859
+%SF:body-ext
+%MD:1997/12/11
+
+%IH:back (of body)
+%P:-t'ak
+%G:back (of body)
+%OIH:back (of body)
+%P1s:st'ak
+%P3s:but'ak
+%C:N
+%S:MAGO/EDFR/VESE/JEKO
+%SF:body-ext
+%UID:000899
+%MD:1997/12/11
+
+%IH:back of hand
+%P:-lat'ak
+%G:back of hand
+%OIH:back of hand
+%P1s:slat'ak
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000871
+%MD:1997/12/11
+
+%IH:beaver paws
+%P:tsake
+%G:beaver paws
+%OIH:beaver paws
+%C:N
+%SF:body-ext
+%S:LITM-EDFR
+%UID:000329
+%MD:1997/06/18
+
+%IH:beaver tail
+%P:tsache
+%G:beaver tail
+%OIH:beaver tail
+%C:N
+%SF:body-ext
+%S:LITM
+%UID:000207
+%MD:1997/06/16
+
+%IH:belly
+%P:-but
+%G:belly
+%OIH:belly
+%P1s:sbut
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000937
+%MD:1997/12/11
+
+%IH:breast
+%P:-ts'oo
+%G:breast
+%OIH:breast
+%P1s:sts'oo
+%C:N
+%S:MAGO
+%UID:000855
+%SF:body-ext
+%MD:1997/12/11
+
+%IH:bum
+%P:-tl'a
+%G:bum, buttocks
+%OIH:bum/buttocks
+%P1s:stl'a
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000936
+%MD:1997/12/11
+
+%IH:buttocks
+%P:-tl'a
+%G:bum, buttocks
+%OIH:bum/buttocks
+%P1s:stl'a
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000936
+%MD:1997/12/11
+
+%IH:calf of leg
+%P:-kechunch'ooz
+%G:calf of leg
+%OIH:calf of leg
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%UID:004458
+%POCKET:Y
+%MD:2001/04/20
+
+%IH:cheek
+%P:-nembus
+%G:cheek
+%OIH:cheek
+%P1s:snimbus
+%C:N
+%S:MAGO/JOPA/BRBI
+%SF:body-ext
+%UID:000889
+%MD:1997/12/11
+
+%IH:chest
+%P:-yoh
+%G:chest
+%OIH:chest
+%C:N
+%SF:body-ext
+%S:JOPA/EDFR
+%ES:000660
+%UID:003777
+%POCKET:Y
+%MD:2001/02/13
+
+%IH:chin
+%P:-yeda'
+%G:chin
+%OIH:chin
+%P1s:syeda'
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000882
+%MD:1997/12/11
+
+%IH:cranial fontanelle
+%P:-tsidakwhudutle
+%G:cranial fontanelle, baby's soft spot
+%OIH:cranial fontanelle/baby's soft spot
+%C:N
+%P3s:butsidakwhudutle
+%S:MAGO
+%SF:body-ext
+%UID:000898
+%MD:1997/12/11
+
+%IH:baby's soft spot
+%P:-tsidakwhudutle
+%G:cranial fontanelle, baby's soft spot
+%OIH:cranial fontanelle/baby's soft spot
+%C:N
+%P3s:butsidakwhudutle
+%S:MAGO
+%SF:body-ext
+%UID:000898
+%MD:1997/12/11
+
+%IH:ear
+%P:-dzo
+%G:ear
+%OIH:ear
+%MN:This refers to the ear considered as a whole, especially the exterior.
+ When the canal in particular is referred to, one uses {\qc -dzek}, q.v.
+%C:N
+%P1s:sdzo
+%S:MAGO
+%SF:body-ext
+%UID:000879
+%MD:1997/12/11
+
+%IH:earlobe
+%P:-dzobal
+%G:earlobe
+%OIH:earlobe
+%C:N
+%P1s:sdzobal
+%SF:body-ext
+%S:BRBI/MAGO
+%UID:000641
+%MD:1997/12/17
+
+%IH:elbow
+%P:-nints'uzti
+%G:elbow
+%OIH:elbow
+%P1s:snints'uzti
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000916
+%MD:1997/12/11
+
+%IH:eye
+%P:-na
+%G:eye
+%OIH:eye
+%P1s:sna
+%P3s:buna
+%C:N
+%S:MAGO/JOPA/EDFR
+%SF:body-ext
+%UID:000891
+%MD:1998/12/18
+
+%IH:eye socket
+%P:-nak'et
+%G:eye socket
+%OIH:eye socket
+%P1s:snak'et
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000892
+%MD:1997/12/11
+
+%IH:eyebrow
+%P:-nach'usdooz
+%G:eyebrow
+%OIH:eyebrow
+%P1s:snach'usdooz
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000896
+%MD:1997/12/11
+
+%IH:eyelash
+%P:-nalusgha
+%G:eyelash
+%OIH:eyelash
+%P1s:snalusgha
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000895
+%MD:1997/12/11
+
+%IH:eyelid
+%P:-nalus
+%G:eyelid
+%OIH:eyelid
+%P1s:snalus
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000894
+%MD:1997/12/11
+
+%IH:face
+%P:-nen
+%G:face
+%OIH:face
+%P1s:snen
+%P2s:nyunen
+%P3s:bunen
+%C:N
+%S:MAGO/PEJO/STJA/JOPA/VESE/EDFR
+%SF:body-ext
+%ES:000369
+%UID:000890
+%MD:2001/04/20
+
+%IH:feather
+%P:ts'uz
+%G:feather, down
+%OIH:feather/down
+%C:N
+%SF:body-ext
+%S:LITM/STJA/PEJO
+%UID:000271
+%MD:2000/10/16
+
+%IH:down
+%P:ts'uz
+%G:feather, down
+%OIH:feather/down
+%C:N
+%SF:body-ext
+%S:LITM/STJA/PEJO
+%UID:000271
+%MD:2000/10/16
+
+%IH:feathers
+%P:dut'aits'uz
+%G:feathers, down
+%OIH:feathers/down
+%C:N
+%SF:body-ext
+%S:STJA
+%UID:002647
+%MD:2001/02/27
+
+%IH:down
+%P:dut'aits'uz
+%G:feathers, down
+%OIH:feathers/down
+%C:N
+%SF:body-ext
+%S:STJA
+%UID:002647
+%MD:2001/02/27
+
+%IH:finger other than thumb or pinkie
+%P:-lasge
+%G:finger other than thumb or pinkie
+%OIH:finger other than thumb or pinkie
+%P1s:slasge
+%C:N
+%S:MAGO/STJA/JOPA/PEJO/EDFR
+%SF:body-ext
+%UID:000869
+%MD:2000/11/01
+
+%IH:fingernails
+%P:-lagui
+%G:fingernails, claws of forepaws
+%OIH:fingernails/claws of forepaws
+%P1s:slagui
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000875
+%MD:1997/12/11
+
+%IH:claws of forepaws
+%P:-lagui
+%G:fingernails, claws of forepaws
+%OIH:fingernails/claws of forepaws
+%P1s:slagui
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000875
+%MD:1997/12/11
+
+%IH:foot
+%P:-ke
+%G:foot
+%OIH:foot
+%C:N
+%P1s:ske
+%Pref:duke
+%S:MAGO/STJA/JOPA/VESE/EDFR/JEKO
+%UID:000851
+%SF:body-ext
+%MD:1999/05/11
+
+%IH:hair
+%P:-gha
+%G:hair
+%MN:This refers to hair in general and where no more specific term exists, as on the
+ arms and chest. It is not used to refer to the hair of the head, for which the
+ more specific term {\qc -tsigha} is always used.
+%OIH:hair
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000888
+%MD:1997/12/11
+
+%IH:hair of the head
+%P:-tsigha
+%G:hair of the head
+%OIH:hair of the head
+%P1s:stsigha
+%P2s:ntsigha
+%P3s:butsigha
+%C:N
+%S:MAGO/LITM/PEJO
+%SF:body-ext
+%UID:000887
+%MD:2000/10/20
+
+%IH:hand
+%P:-la
+%G:hand
+%OIH:hand
+%P1s:sla
+%P2s:nla
+%C:N
+%S:MAGO/STJA
+%SF:body-ext
+%POCKET:Y
+%UID:000866
+%MD:1999/02/17
+
+%IH:head
+%P:-tsi
+%G:head
+%OIH:head
+%Pref:dutsi
+%C:N
+%SF:body-ext
+%S:STJA
+%UID:002965
+%POCKET:Y
+%MD:1999/06/24
+
+%IH:heel
+%P:-kelatsul
+%G:heel
+%OIH:heel
+%P1s:skelatsul
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000917
+%MD:1997/12/11
+
+%IH:hip
+%P:-k'ui
+%G:hip
+%OIH:hip
+%P1s:sk'ui
+%C:N
+%S:MAGO/JOPA
+%SF:body-ext
+%UID:000923
+%MD:2001/03/15
+
+%IH:knee
+%P:-gwut
+%G:knee
+%OIH:knee
+%P1s:sgwut
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000933
+%MD:1997/12/11
+
+%IH:kneecap
+%P:-gwutlasi'ai
+%G:kneecap
+%OIH:kneecap
+%P1s:sgwutlasi'ai
+%R:has something to do with floating at tip of knee
+%C:N
+%S:MAGO
+%SF:body-ext
+%UID:000925
+%MD:1997/12/11
+
+%IH:knuckles at boundary between hand and fingers
+%P:-langwut
+%G:knuckles at boundary between hand and fingers
+%OIH:knuckles at boundary between hand and fingers
+%P1s:slangwut
+%SF:body-ext
+%C:N
+%S:JOPA/BRBI
+%UID:000967
+%MD:1997/12/17
+
+%IH:leg
+%P:-kechun
+%G:leg
+%OIH:leg
+%P1s:skechun
+%C:N
+%S:MAGO
+%UID:000852
+%SF:body-ext
+%MD:1997/12/11
+
--- /dev/null
+# From sbohdjal@matrox.com Tue Dec 31 11:41:25 2002
+# Return-Path: <sbohdjal@matrox.com>
+# X-From_: sbohdjal@matrox.com Mon Dec 30 17:34:41 2002
+# Message-Id: <4.3.1.1.20021230101824.00fc4bd8@mailbox.matrox.com>
+# Date: Mon, 30 Dec 2002 10:33:10 -0500
+# To: bug-gawk@gnu.org
+# From: Serge Bohdjalian <sbohdjal@matrox.com>
+# Subject: GAWK 3.1.1 bug, DJGPP port
+#
+# When I run the following AWK file...
+#
+BEGIN {
+ $0 = "00E0";
+ print $0 ", " ($0 && 1) ", " ($0 != "");
+ $1 = "00E0";
+ print $1 ", " ($1 && 1) ", " ($1 != "");
+}
+#
+# With the SimTel version of GAWK 3.1.1 for Windows (downloadable from
+# ftp://ftp.cdrom.com/pub/simtelnet/gnu/djgpp/v2gnu/), I get the following
+# output...
+#
+# 00E0, 0, 1
+# 00E0, 1, 1
+#
+# With the Cygwin version of GAWK 3.1.1 for Windows, I get...
+#
+# 00E0, 1, 1
+# 00E0, 1, 1
+#
+# As far as I know, if "$0" isn't blank, the value of "($0 && 1)" should be
+# "1" (true). I get the same problem if I substitute "00E0" with "00E1" to
+# "00E9". Other strings don't have have this problem (for example, "00EA").
+# The problem occurs whether I use file input or whether I manually assign
+# "$0" (as above).
+#
+# The problem is also discussed in a comp.lang.awk posting ("Bug in GAWK
+# 3.1.1?", Dec. 27, 2002).
+#
+# -Serge
--- /dev/null
+00E0, 1, 1
+00E0, 1, 1
--- /dev/null
+BEGIN { printf("%2.1d---%02.1d\n", 2, 2) }
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawkmisc.atr (os_restore_mode): New function
+
+Sun Dec 3 16:53:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.atr (os_setbinmode): new function.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.atr (os_is_setuid): new function.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.ai.mit.edu>
+
+ * Close-on-exec changes:
+ gawkmisc.atr: (os_close_on_exec, os_isdir): new functions.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Thu Nov 21 13:11:20 1996 Michal Jaegermann <michal@phys.ualberta.ca>
+
+ * Makefile.st: Once again Makefile.st and config.h chase
+ moving targets from the main directory.
+
+Thu Nov 7 21:02:01 1996 Michal Jaegermann <michal@phys.ualberta.ca>
+
+ * Makefile.st, Makefile.awklib: sync'ed with ones in main tree.
+
+Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * ChangeLog created.
--- /dev/null
+# Makefile for GNU Awk support library
+# Copy this file to 'awklib' subdirectory of main directory
+# and execute via relevant targets in your top Makefile
+#
+# This Makefile actually will work for awklib even when NOT
+# compiling with Atari Makefile!!!
+#
+# Copyright (C) 1995, 96 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+SHELL = /bin/sh
+
+srcdir = .
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+
+CC = gcc
+CFLAGS = -g -O
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+binprefix =
+manprefix =
+
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
+mandir = ${prefix}/man/man1
+manext = .1
+infodir = ${prefix}/info
+datadir = ${prefix}/share/awk
+libexecdir = ${exec_prefix}/libexec/awk
+
+# default names of library utilities; on some systems they may require
+# names with extenstions
+PWCAT = pwcat
+GRCAT = grcat
+# the following command used, when necessary, for edits when
+# creating igawk from igawk.sh
+GCOM = '{print}'
+GAWK = gawk
+# $(AWK) is a by default freshly compiled gawk or installed awk when
+# cross-compiling; it is used for edits, since we may compile not on
+# Unix machine and an utility like 'sed' may NOT exist there
+AWK = $(srcdir)/../$(GAWK)
+AUXPROGS = $(PWCAT) $(GRCAT)
+AUXAWK = passwd.awk group.awk
+
+all: stamp-eg $(AUXPROGS) igawk $(AUXAWK)
+
+stamp-eg: $(srcdir)/../doc/gawk.texi
+ rm -fr eg stamp-eg
+ $(AWK) -f $(srcdir)/extract.awk $(srcdir)/../doc/gawk.texi
+ @echo 'some makes are stupid and will not check a directory' > stamp-eg
+ @echo 'against a file, so this file is a place holder. gack.' >> stamp-eg
+
+$(PWCAT): $(srcdir)/eg/lib/pwcat.c
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/pwcat.c $(LDFLAGS) -o $@
+
+$(GRCAT): $(srcdir)/eg/lib/grcat.c
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/grcat.c $(LDFLAGS) -o $@
+
+igawk: $(srcdir)/eg/prog/igawk.sh
+ $(AWK) $(GCOM) $(srcdir)/eg/prog/igawk.sh > $@ ; chmod 755 $@
+
+passwd.awk: $(srcdir)/eg/lib/passwdawk.in
+ $(AWK) '{gsub(/\/usr\/local\/libexec\/awk/, "$(libexecdir)"); print}' \
+ $? > $@
+
+group.awk: $(srcdir)/eg/lib/groupawk.in
+ $(AWK) '{gsub(/\/usr\/local\/libexec\/awk/, "$(libexecdir)"); print}' \
+ $? > $@
+
+install: igawk $(AUXPROGS) $(AUXAWK)
+ $(INSTALL_PROGRAM) igawk $(bindir)/igawk && chmod 755 $(bindir)/igawk
+ for i in $(AUXPROGS) ; do \
+ $(INSTALL_PROGRAM) $$i $(libexecdir)/$$i ; \
+ done
+ for i in $(AUXAWK) $(srcdir)/eg/lib/*.awk ; do \
+ $(INSTALL_DATA) $$i $(datadir)/$$i ; \
+ done
+
+# libexecdir and bindir are removed in the top level Makefile's uninstall
+uninstall:
+ rm -fr $(libexecdir)/* $(datadir)/*
+ rm -f $(bindir)/igawk
+
+clean:
+ rm -f $(AUXPROGS) $(AUXAWK) igawk *~
+
+distclean: clean
+ rm -f Makefile
--- /dev/null
+# Makefile for GNU Awk - ST version.
+#
+# This makefile hand edited from Makefile automatically generated
+# by configure - gcc 2.x.x compiler with TOS version of libraries
+# and modified system().
+# Check comments in this Makefile and adjust to your needs!!
+#
+# This Makefile assumes that you are using Bourne compatible shell
+# (like bash). If this is not the case you will have to edit various
+# targets or perform some actions by hand.
+#
+# Copyright (C) 1986, 1988-1996 the Free Software Foundation, Inc.
+#
+# This file is part of GAWK, the GNU implementation of the
+# AWK Programming Language.
+#
+# GAWK is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GAWK is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+
+MAKEINFO = makeinfo --no-split
+
+srcdir = .
+
+# native compiler with freshly compiled gawk.ttp to fix awklib
+GAWK = gawk.ttp
+CC = gcc
+
+# cross-compiler and gawk already installed on the system (any awk will do)
+# GAWK = gawk
+# CC = cgcc
+
+# WIDTH and EXT have to be both defined or both undefined
+# WIDTH = -mshort -DINT_IS_16BIT
+# EXT = 16
+
+OFLAGS = -O2 -Wall -fomit-frame-pointer $(WIDTH)
+LDFLAGS = $(WIDTH)
+YACC = bison -y
+
+# xstrip -k in target gawk.ttp removes all symbols but _stksize
+# allowing for stack size manipulations without recompiling (with fixstk)
+INSTALL = xstrip -k ; cp -p
+INSTALL_PROGRAM = ${INSTALL}
+#INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_DATA = ${INSTALL}
+
+LIBS = -lpml$(EXT)
+
+ALLOCA =
+
+#all these definitions likely require changes
+exec_prefix = ${prefix}
+prefix = /usr/local
+binprefix =
+manprefix =
+
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
+manexta = l
+mandir = ${prefix}/man/man$(manexta)
+manext = .$(manexta)
+infodir = ${prefix}/info
+#datadir = ${prefix}/share/awk
+datadir = ${prefix}/lib/awk
+libexecdir = ${exec_prefix}/lib/awk
+
+#DEFPATH = ".:$(datadir)"
+# datadir is passed to the next Makefile level and through sed
+# you may need many more backslashes than that if you have to use
+# them at all - sigh...
+DEFPATH = ".,c:\\lib\\awk,c:\\gnu\\lib\\awk"
+
+SHELL = /bin/sh
+
+SHELL = /bin/sh
+#CFLAGS = -g -O
+CFLAGS = $(OFLAGS)
+COMPFLAGS = $(CFLAGS) -DGAWK -I. -I$(srcdir) -DHAVE_CONFIG_H
+
+MFLAGS = "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS)" \
+ GAWK=../$(GAWK) \
+ AWK=awk \
+ PWCAT=pwcat.ttp GRCAT=grcat.ttp \
+ "GCOM='{sub(/\":\"/, \"\\\",\\\"\"); print}'" \
+ "COMPFLAGS=$(COMPFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "bindir=$(bindir)" \
+ "libdir=$(libdir)" \
+ "mandir=$(mandir)" \
+ "manext=$(manext)" \
+ "infodir=$(infodir)" \
+ "datadir=$(datadir)" \
+ "libexecdir=$(libexecdir)"
+
+MMAKE = $(MAKE) $(MFLAGS)
+
+# object files
+AWKOBJS = array.o builtin.o eval.o field.o gawkmisc.o io.o main.o \
+ missing.o msg.o node.o re.o version.o
+
+ALLOBJS = $(AWKOBJS) awktab.o
+
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS= getopt.o getopt1.o regex.o dfa.o random.o $(ALLOCA)
+
+# source and documentation files
+SRC = array.c builtin.c eval.c field.c gawkmisc.c io.c main.c \
+ missing.c msg.c node.c re.c version.c
+
+ALLSRC= $(SRC) awktab.c
+
+AWKSRC= awk.h awk.y custom.h $(ALLSRC) patchlevel.h protos.h random.h
+
+LIBSRC = alloca.c dfa.c dfa.h regex.c regex.h getopt.h getopt.c getopt1.c random.c
+
+COPIES = missing/system.c missing/tzset.c \
+ missing/memcmp.c missing/memcpy.c missing/memset.c \
+ missing/strncasecmp.c missing/strchr.c \
+ missing/strerror.c missing/strtod.c \
+ missing/strftime.c missing/strftime.3
+
+DOCS= doc/gawk.1 doc/gawk.texi doc/texinfo.tex
+
+TEXFILES= doc/gawk.aux doc/gawk.cp doc/gawk.cps doc/gawk.fn doc/gawk.fns \
+ doc/gawk.ky doc/gawk.kys doc/gawk.pg doc/gawk.pgs doc/gawk.toc \
+ doc/gawk.tp doc/gawk.tps doc/gawk.vr doc/gawk.vrs
+
+MISC = NEWS COPYING FUTURES Makefile.in PROBLEMS README PORTS POSIX.STD \
+ configure configure.in acconfig.h configh.in ACKNOWLEDGMENT \
+ ChangeLog INSTALL LIMITATIONS install-sh mkinstalldirs aclocal.m4 \
+ stamp-h.in
+
+OTHERS= amiga doc pc atari vms README_d posix awklib
+
+ALLDOC= doc/gawk.dvi $(TEXFILES) doc/gawk.info*
+
+MAKEFILEIN = Makefile.in awklib/Makefile.in doc/Makefile.in test/Makefile.in
+
+# Release of gawk. There can be no leading or trailing white space here!
+REL=3.0
+
+# clear out suffixes list
+.SUFFIXES:
+.SUFFIXES: .c .o
+
+.c.o:
+ $(CC) -c $(COMPFLAGS) $<
+
+# rules to build gawk
+all: $(GAWK) awklib/all
+
+alldoc: all doc/all
+
+$(GAWK): $(ALLOBJS) $(LIBOBJS) $(REOBJS)
+ $(CC) -o $(GAWK) $(COMPFLAGS) $(LDFLAGS) $(ALLOBJS) $(LIBOBJS) \
+ $(REOBJS) $(LIBS)
+
+$(ALLOBJS): awk.h dfa.h regex.h config.h custom.h
+
+$(LIBOBJS): config.h custom.h
+
+gawkmisc.o: $(srcdir)/atari/gawkmisc.atr
+ $(CC) -c $(COMPFLAGS) -DDEFPATH='$(DEFPATH)' $(srcdir)/gawkmisc.c
+
+# this rule needed or not - depending on your library
+missing.o io.o:
+ $(CC) -c $(COMPFLAGS) -DPIPES_SIMULATED $(srcdir)/$<
+
+# cheat with defines to force an inclusion of a proper code
+getopt.o: getopt.h
+ $(CC) $(CFLAGS) -D_LIBC -D__alloca=__builtin_alloca -c getopt.c
+
+getopt.o: getopt.h
+
+getopt1.o: getopt.h
+
+random.o: random.h
+
+main.o: patchlevel.h
+
+awktab.c: awk.y
+ $(YACC) -v $(srcdir)/awk.y && \
+ if test -f y.tab.c ; then mv y.tab.c ytab.c ; else true ; fi && \
+ sed '/^extern char .malloc(), .realloc();$$/d' ytab.c >awktab.c && \
+ rm ytab.c
+
+# VMS POSIX make won't apply the default .c.o rule to awktab.o for some reason
+awktab.o: awktab.c awk.h
+ $(CC) -c $(COMPFLAGS) $(srcdir)/awktab.c
+
+alloca.o: alloca.c
+
+install: $(GAWK) info installdirs
+ $(INSTALL_PROGRAM) $(GAWK) $(bindir) && chmod 755 $(bindir)/$(GAWK)
+ cd awklib && $(MMAKE) install
+
+installdirs: mkinstalldirs
+ $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
+ $(libdir) $(infodir) $(mandir) $(libexecdir)
+
+installdoc: info
+ cd doc && $(MMAKE) install
+
+#
+#installtotal: installdirs install installdoc
+
+uninstall:
+ rm -f $(bindir)/$(GAWK)
+ cd awklib && $(MMAKE) uninstall
+ -rmdir $(datadir) $(libexecdir)
+# cd doc && $(MMAKE) uninstall
+
+clean:
+ rm -rf $(GAWK) *.o core y.output
+ cd awklib && $(MMAKE) clean
+# the following does not always make sense (when crosscompiling)
+# cd test && $(MAKE) $(MFLAGS) clean
+# cd doc && $(MAKE) $(MFLAGS) clean
+
+local-distclean:
+ rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output \
+ gmon.out make.out config.h config.status config.cache \
+ config.log stamp-h *~
+
+distclean: clean local-distclean
+ cd doc && $(MMAKE) distclean
+ cd awklib && $(MMAKE) distclean
+ cd test && $(MMAKE) distclean
+
+maintainer-clean: clean local-distclean
+ @echo "This command is intended for maintainers to use; it"
+ @echo "deletes files that may require special tools to rebuild."
+ rm -f awktab.c TAGS tags
+ cd doc && $(MMAKE) maintainer-clean
+# cd test && $(MMAKE) maintainer-clean
+# cd awklib && $(MMAKE) maintainer-clean
+
+clobber: maintainer-clean
+
+TAGS:
+ etags $(AWKSRC)
+
+tags:
+ ctags $(AWKSRC)
+
+dvi: $(srcdir)/doc/gawk.texi
+ cd doc && $(MMAKE) dvi
+
+info: $(srcdir)/doc/gawk.texi
+ cd doc && $(MMAKE) info
+
+doc/all:
+ cd doc && $(MMAKE) all
+
+awklib/all:
+ cd awklib && $(MMAKE) all
+
+# to run this target you have to adjust test/Makefile quite a bit
+# in order to make it palatable to your shell
+#
+check: $(GAWK)
+ cd test; $(MMAKE) -k
+
+test: check
+
--- /dev/null
+Tue Nov 7 14:19:41 2000
+
+The atari port is no longer supported. If you have an atari,
+you are welcome to try and use the port here, but we no longer have
+the hardware to test gawk on.
--- /dev/null
+/*
+ * Sample configuration file for ST - works with gcc and TOS libraries;
+ * revise for your configuration if configure script does not work
+ */
+/*
+ * config.h -- configuration definitions for gawk.
+ */
+
+/*
+ * Copyright (C) 1995, 96 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define if type char is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+/* #undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to the type of elements in the array set by `getgroups'.
+ Usually this is either `int' or `gid_t'. */
+#define GETGROUPS_T gid_t
+
+/* Define if the `getpgrp' function takes no argument. */
+#define GETPGRP_VOID 1
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have a working `mmap' system call. */
+/* #undef HAVE_MMAP */
+
+/* Define if your struct stat has st_blksize. */
+#define HAVE_ST_BLKSIZE 1
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if your struct tm has tm_zone. */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+ tzname. */
+/* #undef HAVE_TZNAME */
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+#define TM_IN_SYS_TIME 1
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+#define HAVE_STRINGIZE 1 /* can use ANSI # operator in cpp */
+/* #undef REGEX_MALLOC */ /* use malloc instead of alloca in regex.c */
+#define SPRINTF_RET int /* return type of sprintf */
+
+/* Define if you have the fmod function. */
+#define HAVE_FMOD 1
+
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the madvise function. */
+/* #undef HAVE_MADVISE */
+
+/* Define if you have the memcmp function. */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memset function. */
+#define HAVE_MEMSET 1
+
+/* Define if you have the strchr function. */
+#define HAVE_STRCHR 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strncasecmp function. */
+/* #undef HAVE_STRNCASECMP */
+
+/* Define if you have the strtod function. */
+#define HAVE_STRTOD 1
+
+/* Define if you have the system function. */
+/* This is a white lie - but you may or may not prefer this way */
+/* #define HAVE_SYSTEM 1 */
+
+/* Define if you have the tzset function. */
+#define HAVE_TZSET 1
+
+/* Define if you have the valloc function. */
+/* #undef HAVE_VALLOC */
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <signum.h> header file. */
+/* #undef HAVE_SIGNUM_H */
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+#include <custom.h> /* overrides for stuff autoconf can't deal with */
--- /dev/null
+/*
+ * gawkmisc.atr --- miscellaneous gawk routines that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Progamming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+
+char quote = '\'';
+#ifndef DEFPATH
+char *defpath = ".,c:\\lib\\awk,c:\\gnu\\lib\\awk";
+#else
+char *defpath = DEFPATH;
+#endif
+char envsep = ',';
+
+
+/* gawk_name --- pull out the "gawk" part from how the OS called us */
+
+char *
+gawk_name(filespec)
+const char *filespec;
+{
+ char *p, *q;
+
+ p = (char *)filespec;
+
+ if ((q = strrchr(p, '\\')) != NULL)
+ p = q + 1;
+ if ((q = strrchr(p, '/')) != NULL)
+ p = q + 1;
+ if ((q = strchr(p, '.')) != NULL)
+ *q = '\0';
+ strlwr(p);
+
+ return (p == NULL ? (char *)filespec : (char *)p);
+}
+
+/* os_arg_fixup --- fixup the command line */
+
+void
+os_arg_fixup(argcp, argvp)
+int *argcp;
+char ***argvp;
+{
+ /* no-op */
+ return;
+}
+
+/* os_devopen --- open special per-OS devices */
+
+int
+os_devopen(name, flag)
+const char *name;
+int flag;
+{
+ /* no-op */
+ return INVALID_HANDLE;
+}
+
+/* optimal_bufsize --- determine optimal buffer size */
+
+size_t
+optimal_bufsize(fd, stb)
+int fd;
+struct stat *stb;
+{
+ /* force all members to zero in case OS doesn't use all of them. */
+ memset(stb, '\0', sizeof(struct stat));
+
+ /* The atari has the st_blksize structure, so we just use it. */
+#define DEFBLKSIZE (stb->st_blksize ? stb->st_blksize : BUFSIZ)
+
+ /*
+ * On ST redirected stdin does not have a name attached
+ * (this could be hard to do to) and fstat would fail
+ */
+ if (fd == 0)
+ return BUFSIZ;
+ if (fstat(fd, stb) == -1)
+ fatal("can't stat fd %d (%s)", fd, strerror(errno));
+ if (S_ISREG(stb->st_mode)
+ && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
+ return stb->st_size;
+ return DEFBLKSIZE;
+}
+
+/* ispath --- return true if path has directory components */
+
+int
+ispath(file)
+const char *file;
+{
+ return (strchr(file, '/') != NULL || strchr(file, '\\') != NULL);
+}
+
+/* isdirpunct --- return true if char is a directory separator */
+
+int
+isdirpunct(c)
+int c;
+{
+ return (c == '/' || c == '\\');
+}
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+const char *name, *what, *dir;
+{
+ if (fcntl(fd, F_SETFD, 1) < 0)
+ warning("%s %s `%s': could not set close-on-exec: %s",
+ what, dir, name, strerror(errno));
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+#if ! defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+int
+os_isdir(fd)
+int fd;
+{
+ struct stat sbuf;
+
+ return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
+}
+
+/* os_is_setuid --- true if running setuid root */
+
+int
+os_is_setuid()
+{
+ return 0;
+}
+
+/* os_setbinmode --- set binary mode on file */
+
+int
+os_setbinmode (fd, mode)
+int fd, mode;
+{
+ return 0;
+}
+
+/* os_restore_mode --- restore the original mode of the console device */
+
+void
+os_restore_mode (fd)
+int fd;
+{
+ /* no-op */
+ return;
+}
--- /dev/null
+/*
+ * redirect.h --- definitions for functions that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-1993 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* This file is already conditioned on atarist in awk.h */
+
+#define read _text_read /* we do not want all these CR's to mess our input */
+extern int _text_read(int, char *, int);
+#ifndef __MINT__
+#undef NGROUPS_MAX
+#endif /* __MINT__ */
--- /dev/null
+/*
+ * This value indicates an amount of reserved memory for a stack
+ * in executables - see source of a startup code for details.
+ * It can be changed without recompilation with fixstk.ttp utility.
+ */
+long _stksize = 2L; /* keep half of memory */
--- /dev/null
+/*
+ * function system() - slightly modified from sources dLibs 1.2
+ * - a freely distributable C library for Atari ST.
+ * Authors: Dale Schumacher and John Stanley, I believe.
+ * Changes for gcc compiler and gnulib.olb - Michal Jaegermann
+ */
+
+#include <osbind.h>
+#include <stdio.h>
+#include <string.h>
+#include <basepage.h>
+#ifdef __GNUC__
+#include <process.h>
+#define ERROR 2
+#endif
+
+/* #define DEBUG */
+#ifdef DEBUG
+#define _COOKIE(x) puts(x);putchar('\n')
+#endif
+
+static void
+parse_args(char *cmdln, register char **argv)
+{
+ register char *p;
+ static char delim[] = " \t\r\n";
+
+ if(NULL != (p = strtok(cmdln, delim))) {
+ do {
+ *argv++ = p;
+ } while(NULL != (p = strtok(NULL, delim)));
+ }
+}
+
+#ifdef __GNUC__
+/* this is used by assembler statement to keep a copy of registers */
+static volatile long savearea[16];
+#endif
+
+int
+system(const char *command)
+{
+ register char *p;
+ register int (*shell)();
+#ifndef __GNUC__
+ char rv[2];
+#endif
+ char cmdln[1024];
+ char *args[64];
+ char *getenv(const char *);
+
+ if(!command)
+ return(ERROR);
+
+ /* get _shell_p value */
+ p = (char *) Super(0L); /* supervisor mode */
+ shell = (int (*)()) *((long *) 0x4F6L);
+ (void) Super(p); /* restore user mode */
+
+ /* validate _shell_p */
+ if((shell) && /* Shell available. */
+ (((long) shell) < ((long) _base)) && /* Reasonable shell pointer. */
+ (strncmp((char *)shell, "PATH", 4))) /* Not corrupted */
+ {
+#ifdef __GNUC__
+ int ret;
+#endif
+ /* execute the command */
+#ifdef DEBUG
+_COOKIE("system: using _shell_p");
+printf("'shell' got value 0x%08lx\n", (long)shell);
+#endif
+/* a bit of paranoia caused by some misbehaving programs */
+#ifdef __GNUC__
+asm("moveml d1-d7/a0-a7,_savearea");
+ ret = (*shell)(command);
+asm("moveml _savearea,d1-d7/a0-a7");
+ return (ret);
+#else
+ return ((*shell)(command));
+#endif
+ }
+
+ strcpy(cmdln, command); /* copy the command line for parsing */
+
+ if((p = getenv("SHELL")) && (*p)) /* SHELL= variable? */
+ {
+ args[0] = p;
+ parse_args(cmdln, (args + 1));
+#ifdef DEBUG
+_COOKIE("system: executing SHELL");
+_COOKIE(p);
+#endif
+ }
+ else /* attempt to find first token as a program on the path */
+ {
+ parse_args(cmdln, args);
+ p = args[0];
+#ifdef DEBUG
+_COOKIE("system: directly executing program");
+_COOKIE(p);
+#endif
+ }
+
+#ifdef __GNUC__
+ return(spawnvp(0, p, args));
+#else /* original from dLibs */
+ forkvpe(p, args, NULL);
+ wait(rv);
+ return((rv[1] == 0) ? rv[0] : rv[1]);
+#endif
+}
--- /dev/null
+#ifdef PIPES_SIMULATED
+/* tmpnam.c : return a temporary file name */
+/* written by Eric R. Smith and placed in the public domain */
+/**
+ * - modified for gawk needs - pattern /$$XXXXXX from the original
+ * code creates names which are hard to remove when somethig
+ * goes wrong
+ * - returned name can be passed outside via system(); other programs
+ * may not dig '/' as a path separator
+ * - somehow more frugal in a memory use
+ * (mj - October 1990)
+ **/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char * getenv(const char *);
+extern char * mktemp(char *);
+char * tempnam(const char *path, const char *base);
+static char pattern[] = "\\gwkXXXXX";
+
+char *tmpnam(buf)
+ char *buf;
+{
+ char *tmpdir;
+
+ if (!(tmpdir = getenv("TEMP")) && !(tmpdir = getenv("TMPDIR")))
+ tmpdir = ".";
+
+ if (!buf) {
+ size_t blen;
+
+ blen = strlen (tmpdir) + sizeof(pattern);
+ if (NULL == (buf = malloc(blen)))
+ return NULL;
+ }
+ (void) strcat(strcpy(buf, tmpdir), pattern);
+ return(mktemp(buf));
+}
+
+/* used by gawk_popen() */
+char *tempnam(path, base)
+const char *path, *base; /* ignored */
+{
+ return tmpnam(NULL);
+}
+#endif /* PIPES_SIMULATED */
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * tmisc.c (os_restore_mode): New function
+
+Sun Dec 3 16:53:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * tmisc.c (os_setbinmode): new function.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * tmisc.c (os_is_setuid): new function.
+
+Tue Jun 1 14:09:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ Sync with changes in 3.0.4 for non-Unix popen/pclose
+ * popen.h: add defines for popen and pclose.
+ * config.h: add define for HAVE_POPEN_H.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Close-on-exec changes:
+ tmisc.c: (os_close_on_exec, os_isdir): new functions.
+
+Mon Jul 27 11:40:00 1997 Arnold D. Robbins <arnold@gnu.org>
+
+ * Initial integration of Tandem stuff into gawk source tree.
--- /dev/null
+?TACL MACRO\r#FRAME\r#PUSH #INLINEPREFIX\r#SET #INLINEPREFIX +\r==\r== Compile the bits\r==\rc /in allocac, out allocax/allocao; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in arrayc, out arrayx/arrayo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in builtinc, out builtinx/builtino; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in dfac, out dfax/dfao; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in evalc, out evalx/evalo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in fieldc, out fieldx/fieldo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in gawkmisc, out gawkmisx/gawkmiso; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in getoptc, out getoptx/getopto; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in getopt1c, out getopt1x/getopt1o;symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in ioc, out iox/ioo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in isattyc, out isattyx/isattyo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in mainc, out mainx/maino; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in missingc, out missingx/missingo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in msgc, out msgx/msgo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in nodec, out nodex/nodeo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in popenc, out popenx/popeno; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in rec, out rex/reo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in regexc, out regexx/regexo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in awktabc, out tawktabx/tawktabo; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\rc /in versionc, out versionx/versiono; symbols,WIDE,define TANDEM,define HAVE_CONFIG_H,SSV0 "$system.system",SSV1 "[#defaults]"\r==\r== then bind them\r==\rbind/inline,out bindout/\r+ select runnable object on\r+ select check parameter off\r+ select list * off\r+ select fixups on\r+ select search $system.system.cwide\r+ add * from arrayo\r+ add * from allocao\r+ add * from builtino\r+ add * from dfao\r+ add * from evalo\r+ add * from fieldo\r+ add * from gawkmiso\r+ add * from getopto\r+ add * from getopt1o\r+ add * from ioo\r+ add * from isattyo\r+ add * from maino\r+ add * from missingo\r+ add * from msgo\r+ add * from nodeo\r+ add * from popeno\r+ add * from reo\r+ add * from regexo\r+ add * from tawktabo\r+ add * from versiono\r+ set heap 5000 pages\r+ build awk\r+ file awk\r+ info unresolved *\r+ list *\rINLEOF\r#UNFRAME\r
\ No newline at end of file
--- /dev/null
+/* config.h. Generated automatically by configure. */
+/* configh.in. Generated automatically from configure.in by autoheader. */
+/*
+ * acconfig.h -- configuration definitions for gawk.
+ */
+
+/*
+ * Copyright (C) 1995-1997 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Progamming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c. */
+#define C_ALLOCA
+
+/* Define if type char is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+#define __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to the type of elements in the array set by `getgroups'.
+ Usually this is either `int' or `gid_t'. */
+#define GETGROUPS_T gid_t
+
+/* Define if the `getpgrp' function takes no argument. */
+#define GETPGRP_VOID 1
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if your struct stat has st_blksize. */
+/* #define HAVE_ST_BLKSIZE 1 */
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if your struct tm has tm_zone. */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+ tzname. */
+#define HAVE_TZNAME 1
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+#define HAVE_STRINGIZE 1 /* can use ANSI # operator in cpp */
+#define REGEX_MALLOC 1 /* use malloc instead of alloca in regex.c */
+#define SPRINTF_RET int /* return type of sprintf */
+/* #undef BITOPS */ /* bitwise ops (undocumented feature) */
+/* #undef NONDECDATA */ /* non-decimal input data (undocumented feature) */
+/* #undef HAVE_MKTIME */ /* we have the mktime function */
+
+/* Define if you have the fmod function. */
+#define HAVE_FMOD
+
+/* Define if you have the memcmp function. */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memset function. */
+#define HAVE_MEMSET 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the strchr function. */
+#define HAVE_STRCHR 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strncasecmp function. */
+/* Tandem doesn't have it but the file name is too long, so pretend here
+ and do it properly at the end of this file */
+#define HAVE_STRNCASECMP 1
+
+/* Define if you have the strtod function. */
+#define HAVE_STRTOD 1
+
+/* Define if you have the system function. */
+#define HAVE_SYSTEM 1
+
+/* Define if you have the tzset function. */
+#define HAVE_TZSET 1
+
+/* Define if you have the <fcntl.h> header file. */
+/* #undef HAVE_FCNTL_H */
+
+/* Define if you have the <limits.h> header file. */
+/* #undef HAVE_LIMITS_H */
+
+/* Define if you have the <locale.h> header file. */
+/* #undef HAVE_LOCALE_H */
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <signum.h> header file. */
+/* #undef HAVE_SIGNUM_H */
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+/* #undef HAVE_SYS_TIME_H */
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H 1
+
+/* Define if you have the m library (-lm). */
+/* #undef HAVE_LIBM */
+
+#define HAVE_POPEN_H 1
+
+#include <custom.h> /* overrides for stuff autoconf can't deal with */
--- /dev/null
+#if defined _MSC_VER || defined TANDEM
+
+#ifndef TANDEM
+#ifdef OS2
+# define INCL_DOSPROCESS
+# include <os2.h>
+# if _MSC_VER == 510
+# define DosGetPID DosGetPid
+# endif
+#else
+# include <process.h>
+#endif
+
+#ifdef OS2
+int getpid(void)
+{
+ PIDINFO PidInfo;
+
+ DosGetPID(&PidInfo);
+ return(PidInfo.pid);
+}
+#endif
+
+int getppid(void)
+{
+#ifdef OS2
+ PIDINFO PidInfo;
+
+ DosGetPID(&PidInfo);
+ return(PidInfo.pidParent);
+#else
+ return(0);
+#endif
+}
+
+#endif /* TANDEM */
+#ifdef TANDEM
+unsigned int getuid (void)
+{
+ short cret;
+ short cwd,pwd;
+
+ cret = PROCESS_GETINFO_(,,,,,,,,,,&cwd,&pwd);
+ return ((unsigned int) (cwd & 255));
+}
+
+unsigned int geteuid (void)
+{
+ short cret;
+ short cwd,pwd;
+
+ cret = PROCESS_GETINFO_(,,,,,,,,,,&cwd,&pwd);
+ return ((unsigned int) (pwd & 255));
+}
+
+unsigned int getgid (void)
+{
+ short cret;
+ short cwd,pwd;
+
+ cret = PROCESS_GETINFO_(,,,,,,,,,,&cwd,&pwd);
+ return ((unsigned int) ((cwd >> 8) & 255));
+}
+
+unsigned int getegid (void)
+{
+ short cret;
+ short cwd,pwd;
+
+ cret = PROCESS_GETINFO_(,,,,,,,,,,&cwd,&pwd);
+ return ((unsigned int) ((pwd >> 8) & 255));
+}
+
+int getpid(void)
+{
+ return (0);
+}
+
+int getppid(void)
+{
+ return (0);
+}
+
+#else
+unsigned int getuid (void)
+{
+ return (0); /* root! */
+}
+
+
+unsigned int geteuid (void)
+{
+ return (0);
+}
+
+
+unsigned int getgid (void)
+{
+ return (0);
+}
+
+
+unsigned int getegid (void)
+{
+ return (0);
+}
+
+
+char *getlogin (void)
+{
+ return ("root");
+}
+
+#endif /* TANDEM */
+#endif
+
+int getpgrp(void)
+{
+ return (0);
+}
--- /dev/null
+#include <cextdecs(FILE_GETINFO_)>
+#include <stdioh>
+#include <talh>
+
+int isatty(int fd)
+{
+ short cret,sfd,typ[5];
+ sfd = (short) fd;
+ cret = FILE_GETINFO_(sfd,,,,,&typ[0]);
+ if(typ[0] == 6)
+ return (1);
+ else
+ return (0);
+}
+int dup(int fd)
+{
+ return (fd);
+}
+int dup2(int fd, int fd2)
+{
+ return (0);
+}
--- /dev/null
+#include "popen.h"
+#include <stdlib.h>
+#if !defined(TANDEM)
+#include <io.h>
+#else
+#include "config.h"
+#include <fcntl.h>
+#endif
+#include <string.h>
+#if !defined(TANDEM)
+#include <process.h>
+#endif
+
+#ifdef OS2
+#ifdef _MSC_VER
+#define popen(c,m) _popen(c,m)
+#define pclose(f) _pclose(f)
+#endif
+#endif
+
+#ifndef _NFILE
+#define _NFILE 40
+#endif
+
+static char template[] = "piXXXXXX";
+typedef enum { unopened = 0, reading, writing } pipemode;
+static
+struct {
+ char *command;
+ char *name;
+ pipemode pmode;
+} pipes[_NFILE];
+
+FILE *
+os_popen( char *command, char *mode ) {
+ FILE *current;
+ char *name;
+ int cur;
+ pipemode curmode;
+
+#if defined(OS2) && (_MSC_VER != 510)
+ if (_osmode == OS2_MODE)
+ return(popen(command, mode));
+#endif
+
+ /*
+ ** decide on mode.
+ */
+ if(strcmp(mode,"r") == 0)
+ curmode = reading;
+ else if(strcmp(mode,"w") == 0)
+ curmode = writing;
+ else
+ return NULL;
+ /*
+ ** get a name to use.
+ */
+ if((name = tempnam(".","pip"))==NULL)
+ return NULL;
+ /*
+ ** If we're reading, just call system to get a file filled with
+ ** output.
+ */
+ if(curmode == reading) {
+ if ((cur = dup(fileno(stdout))) == -1)
+ return NULL;
+ if ((current = freopen(name, "w", stdout)) == NULL)
+ return NULL;
+ system(command);
+ if (dup2(cur, fileno(stdout)) == -1)
+ return NULL;
+ close(cur);
+ if((current = fopen(name,"r")) == NULL)
+ return NULL;
+ } else {
+ if((current = fopen(name,"w")) == NULL)
+ return NULL;
+ }
+ cur = fileno(current);
+ pipes[cur].name = name;
+ pipes[cur].pmode = curmode;
+ pipes[cur].command = strdup(command);
+ return current;
+}
+
+int
+os_pclose( FILE * current) {
+ int cur = fileno(current),rval;
+
+#if defined(OS2) && (_MSC_VER != 510)
+ if (_osmode == OS2_MODE)
+ return(pclose(current));
+#endif
+
+ /*
+ ** check for an open file.
+ */
+ if(pipes[cur].pmode == unopened)
+ return -1;
+ if(pipes[cur].pmode == reading) {
+ /*
+ ** input pipes are just files we're done with.
+ */
+ rval = fclose(current);
+ unlink(pipes[cur].name);
+ } else {
+ /*
+ ** output pipes are temporary files we have
+ ** to cram down the throats of programs.
+ */
+ char command[256];
+ fclose(current);
+#if defined(TANDEM)
+ sprintf(command,"%s /IN %s/",pipes[cur].command,pipes[cur].name);
+#else
+ sprintf(command,"%s < %s",pipes[cur].command,pipes[cur].name);
+#endif
+ rval = system(command);
+ unlink(pipes[cur].name);
+ }
+ /*
+ ** clean up current pipe.
+ */
+ pipes[cur].pmode = unopened;
+ free(pipes[cur].name);
+ free(pipes[cur].command);
+ return rval;
+}
--- /dev/null
+/*
+
+** popen.h -- prototypes for pipe functions
+
+*/
+
+#if !defined(FILE)
+
+#include <stdio.h>
+
+#endif
+
+
+
+extern FILE *os_popen( char *, char * );
+
+extern int os_pclose( FILE * );
+
+#define popen os_popen
+#define pclose os_close
--- /dev/null
+/*
+ * strdup --- duplicate a string
+ *
+ * We supply this routine for those systems that aren't standard yet.
+ */
+
+char *
+strdup (str)
+register const char *str;
+{
+ char *p;
+
+ p=(char *)malloc(strlen(str)+1);
+ return strcpy(p,str);
+}
--- /dev/null
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef atarist
+#include <sys/types.h>
+#else
+#define u_char unsigned char
+#endif
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return(cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while ((long)(--n) >= 0 && cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return((long)n < 0 ? 0 : cm[*us1] - cm[*--us2]);
+}
--- /dev/null
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+char *name, *what, *dir;
+{
+ /* no-op */
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+#if ! defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+int
+os_isdir(fd)
+int fd;
+{
+ struct stat sbuf;
+
+ return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
+}
+/*
+ * gawkmisc.c --- miscellanious gawk routines that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Progamming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+char quote = '"';
+char envsep = ';';
+char *defpath = "";
+
+/* gawk_name --- pull out the "gawk" part from how the OS called us */
+
+char *
+gawk_name(filespec)
+const char *filespec;
+{
+ char *p, *q;
+
+ p = (char *) filespec; /* Sloppy... */
+
+ if ((q = strrchr(p, '.')) != NULL)
+ p = q + 1;
+ return p;
+}
+
+/* os_arg_fixup --- fixup the command line */
+
+void
+os_arg_fixup(argcp, argvp)
+int *argcp;
+char ***argvp;
+{
+ return;
+}
+
+/* os_devopen --- open special per-OS devices */
+
+int
+os_devopen(name, flag)
+const char *name;
+int flag;
+{
+ /* no-op */
+ return -1;
+}
+
+/* optimal_bufsize --- determine optimal buffer size */
+
+size_t
+optimal_bufsize(fd, stb)
+int fd;
+struct stat *stb;
+{
+ /*
+ * TANDEM doesn't have a stat function.
+ * So we just return 4096 which is the Tandem disk block size.
+ */
+
+ /* set all members to zero. */
+
+ memset(stb, '\0', sizeof(struct stat));
+
+ /* set file size to arbitrary non-zero value. */
+ stb->st_size = 1;
+
+ return 4096;
+}
+
+/* ispath --- return true if path has directory components */
+
+int
+ispath(file)
+const char *file;
+{
+ for (; *file; file++) {
+ switch (*file) {
+ case '.':
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* isdirpunct --- return true if char is a directory separator */
+
+int
+isdirpunct(c)
+int c;
+{
+ return (strchr(".\\", c) != NULL);
+}
+
+void
+initstate(i, j, k)
+unsigned i;
+char * j;
+int k;
+{
+}
+
+void setstate(i)
+char * i;
+{
+}
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+char *name, *what, *dir;
+{
+ /* no-op */
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+/* can't do this on tandem, so just assume it's not a directory */
+
+int
+os_isdir(fd)
+int fd;
+{
+ return 0;
+}
+
+/* os_is_setuid --- true if running setuid root */
+
+int
+os_is_setuid()
+{
+ return 0;
+}
+
+/* os_setbinmode --- set binary mode on file */
+
+int
+os_setbinmode (fd, mode)
+int fd, mode;
+{
+ return 0;
+}
+
+/* os_restore_mode --- restore the original mode of the console device */
+
+void
+os_restore_mode (fd)
+int fd;
+{
+ /* no-op */
+ return;
+}
--- /dev/null
+#include "config.h"
+
+const char *version_string = "@(#)GNU Awk 3.1.5";
+
+/* 1.02 fixed /= += *= etc to return the new Left Hand Side instead
+ of the Right Hand Side */
+
+/* 1.03 Fixed split() to treat strings of space and tab as FS if
+ the split char is ' '.
+
+ Added -v option to print version number
+
+ Fixed bug that caused rounding when printing large numbers */
+
+/* 2.00beta Incorporated the functionality of the "new" awk as described
+ the book (reference not handy). Extensively tested, but no
+ doubt still buggy. Badly needs tuning and cleanup, in
+ particular in memory management which is currently almost
+ non-existent. */
+
+/* 2.01 JF: Modified to compile under GCC, and fixed a few
+ bugs while I was at it. I hope I didn't add any more.
+ I modified parse.y to reduce the number of reduce/reduce
+ conflicts. There are still a few left. */
+
+/* 2.02 Fixed JF's bugs; improved memory management, still needs
+ lots of work. */
+
+/* 2.10 Major grammar rework and lots of bug fixes from David.
+ Major changes for performance enhancements from David.
+ A number of minor bug fixes and new features from Arnold.
+ Changes for MSDOS from Conrad Kwok and Scott Garfinkle.
+ The gawk.texinfo and info files included! */
+
+/* 2.11 Bug fix release to 2.10. Lots of changes for portability,
+ speed, and configurability. */
+
+/* 2.12 Lots of changes for portability, speed, and configurability.
+ Several bugs fixed. POSIX compliance. Removal of last set
+ of hard-wired limits. Atari and VMS ports added. */
+
+/* 2.13 Public release of 2.12 */
+
+/* 2.14 Mostly bug fixes. */
+
+/* 2.15 Bug fixes plus intermixing of command-line source and files,
+ GNU long options, ARGIND, ERRNO and Plan 9 style /dev/ files.
+ `delete array'. OS/2 port added. */
+
+/* 3.0 RS as regexp, RT variable, FS = "", fflush builtin, posix
+ regexps, IGNORECASE applies to all comparison, autoconf, source
+ code cleanup. See the NEWS file. */
+
+/* 3.1 PROCINFO array, LINT variable, mktime builtin, BINMODE variable,
+ |&, tcp/ip, i18n stuff. Automake. See NEWS. */
--- /dev/null
+#include "config.h"
+
+const char *version_string = "@(#)@PACKAGE_STRING@";
+
+/* 1.02 fixed /= += *= etc to return the new Left Hand Side instead
+ of the Right Hand Side */
+
+/* 1.03 Fixed split() to treat strings of space and tab as FS if
+ the split char is ' '.
+
+ Added -v option to print version number
+
+ Fixed bug that caused rounding when printing large numbers */
+
+/* 2.00beta Incorporated the functionality of the "new" awk as described
+ the book (reference not handy). Extensively tested, but no
+ doubt still buggy. Badly needs tuning and cleanup, in
+ particular in memory management which is currently almost
+ non-existent. */
+
+/* 2.01 JF: Modified to compile under GCC, and fixed a few
+ bugs while I was at it. I hope I didn't add any more.
+ I modified parse.y to reduce the number of reduce/reduce
+ conflicts. There are still a few left. */
+
+/* 2.02 Fixed JF's bugs; improved memory management, still needs
+ lots of work. */
+
+/* 2.10 Major grammar rework and lots of bug fixes from David.
+ Major changes for performance enhancements from David.
+ A number of minor bug fixes and new features from Arnold.
+ Changes for MSDOS from Conrad Kwok and Scott Garfinkle.
+ The gawk.texinfo and info files included! */
+
+/* 2.11 Bug fix release to 2.10. Lots of changes for portability,
+ speed, and configurability. */
+
+/* 2.12 Lots of changes for portability, speed, and configurability.
+ Several bugs fixed. POSIX compliance. Removal of last set
+ of hard-wired limits. Atari and VMS ports added. */
+
+/* 2.13 Public release of 2.12 */
+
+/* 2.14 Mostly bug fixes. */
+
+/* 2.15 Bug fixes plus intermixing of command-line source and files,
+ GNU long options, ARGIND, ERRNO and Plan 9 style /dev/ files.
+ `delete array'. OS/2 port added. */
+
+/* 3.0 RS as regexp, RT variable, FS = "", fflush builtin, posix
+ regexps, IGNORECASE applies to all comparison, autoconf, source
+ code cleanup. See the NEWS file. */
+
+/* 3.1 PROCINFO array, LINT variable, mktime builtin, BINMODE variable,
+ |&, tcp/ip, i18n stuff. Automake. See NEWS. */
--- /dev/null
+Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.5: Release tar file made.
+
+Mon May 23 20:54:31 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms_gawk.c [gawk_cmd, #if __ia64__]: Switch from globalvalue
+ to strict_refdef and then take gawk_cmd's address during use.
+
+ * vmstest.com (concat1, longsub, arrayprm2, arrayprm3, arryref2,
+ arryref3, arryref4, arryref5, aryprm1, aryprm2, aryprm3,
+ aryprm4, aryprm5, aryprm6, aryprm7, aryprm8, concat2, concat3,
+ delarpm2, delfunc, exitval2, fmttest, fnarray2, fnmisc, fordel,
+ getline3, gsubasgn, gsubtest, gsubtst2, gsubtst4, gsubtst5,
+ hex, inputred, iobug1, manglprm, nested, nfneg, noloop1,
+ noloop2, nulrsend, prec, prtoeval, rstest1, rstest2, rstest3,
+ rstest4, rstest5, scalar, sortempty, splitarr, strcat1,
+ subsepnm, synerr1, uninit2, uninit3, uninit4, uninitialized,
+ unterm, wjposer1, zeroe0): New tests.
+
+Wed May 18 21:22:09 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms_gawk.c [#if __ia64__]: Use #pragma extern_model globalvalue
+ for the declaration of gawk_cmd.
+
+Mon May 9 21:17:33 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h [#if DECC]: Use #pragma to suppress "new feature in C99"
+ diagnostic for structure field designator style initialization in
+ regexec.c.
+
+Thu May 5 21:17:48 2005 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * vms_gawk.c [__ia64__]: Change to lower case, then Itanium
+ VMS is happy.
+
+Sun May 1 08:20:00 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms_gawk.c [gawk_cmd]: Declare as ordinary data symbol rather
+ than as a fake routine for Itanium. (Can't do that for other
+ configurations without getting tangled up in compiler-specific
+ details like `#pragma extern_model' and VAX C's `globalref'.)
+
+Fri Mar 4 20:46:20 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h: Define VAXCRTL when appropriate; used in builtin.c.
+
+Sat Feb 19 20:13:28 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h [RE_TOKEN_INIT_BUG]: Define for regcomp.c.
+
+Wed Feb 16 20:45:21 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h [NO_MBSUPPORT]: Define when compiling with VAX C.
+ [inline]: Define as empty when compiling with VAX C.
+
+Thu Jan 20 19:09:52 2005 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h: Synchronize with configh.in.
+
+Mon Aug 2 12:18:15 2004 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.4: Release tar file made.
+
+Mon Jun 14 18:40:22 2004 Pat Rankin <rankin@pactechdata.com>
+
+ * descrip.mms (dfa.c, dfa.h): reinstate these.
+ (gettext.h, mbsupport.h): add these.
+ (patchlev.h): remove this.
+
+ * vmstest.com (longwrds): customize it.
+ (getline, getline2): replace getline with getline2.
+
+Mon Jul 7 11:01:43 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.3: Release tar file made.
+
+Mon Jun 9 22:15:40 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h: Synchronize with current configh.in.
+ ALLOW_SWITCH: Define this to enable new `switch' feature.
+
+Wed Mar 19 14:10:31 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ This time for sure.
+ -- Bullwinkle
+
+ * Release 3.1.2: Release tar file made.
+
+Thu Feb 27 17:54:33 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * descrip.mms: Revert regex compilation to single file.
+ vmsbuild.com: Likewise.
+
+Thu Feb 20 18:06:54 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * vms_gawk.c (vms_gawk): Don't check for `RUNUSED' status because
+ it gets a false match when gawk is invoked via fork+exec.
+
+ * gawk.hlp: Limited updates to the release notes section.
+
+Tue Feb 4 14:28:06 2003 Arnold D. Robbins <arnold@skeeve.com>
+
+ All relevant files: Copyright year updated to 2003.
+
+Mon Feb 3 20:37:09 2003 Pat Rankin <rankin@pactechdata.com>
+
+ * vms-conf.h (ssize_t): Define as int.
+ (TIME_T_UNSIGNED): New macro; used in strftime.
+ * vms_cli.c (Cli_Parse_Command): Increase command buffer size
+ from 2.5Kb to 8Kb.
+
+ From Steve Pitcher:
+ * vms_gawk.c (vms_gawk): Don't report "missing required element"
+ for INSFPRM status unless invoked via a native DCL verb.
+
+ From Jouk Jansen:
+ * vms-conf.h (CRTL_VER_V731): New macro.
+ * vms_misc.c (getpgrp): Use it.
+
+Mon Dec 23 16:53:42 2002 Pat Rankin <rankin@pactechdata.com>
+
+ * descrip.mms (AWKOBJ1, AWKOBJ2): Split AWKOBJS into pieces to
+ avoid line length overflow when creating gawk.opt.
+ (regcomp.obj, regexec.obj, regex_internal.obj): New targets.
+ * vmsbuild.com: Likewise.
+
+Thu Nov 21 19:45:08 2002 Pat Rankin <rankin@pactechdata.com>
+
+ * descrip.mms: Update to reflect regex changes; eliminate dfa.
+
+ * vmstest.com (exit_code): Hack to add "EXIT CODE n" record to
+ output for tests that trigger gawk failure.
+
+Wed May 1 16:41:32 2002 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.1: Release tar file made.
+
+Wed Apr 17 15:57:30 2002 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (forsimp, concat1, longsub): New Tests.
+ (strftime): Revamp test to avoid use of defunct %v extension.
+
+Sat Dec 22 19:18:31 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * redirect.h (tzset): Declare.
+
+Sun Jun 3 13:04:44 2001 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.0: Release tar file made. And there was
+ rejoicing.
+
+Thu Apr 12 18:29:50 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms_misc.c (open): Add handling for /dev/null and /dev/tty.
+ (vms_devopen): Remove handling for /dev/null and /dev/tty.
+
+ * vms_misc.c (VMS_stat, VMS_fstat): New functions to work
+ around old VAXCRTL bugs.
+ * redirect.h (fstat): Define as VMS_fstat for VAX C or GNU C.
+
+ * vms-conf.h (HAVE_UNISTD_H): Avoid <unistd.h> for GNU C.
+
+ * descrip.mms: Synchronize with 3.1.0 sources.
+
+ * vmstest.com: Add many new tests.
+ (fixup_LRL): New subroutine.
+
+Thu Apr 5 20:31:22 2001 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h: synchronize with current configh.in.
+ [NO_ALLOCA]: define instead of C_ALLOCA.
+ * redirect.h (strcoll): substitute strcmp for VAXCRTL config.
+ (struct timeval): define.
+ (gettimeofday): substitute vms_gettimeofday; declare.
+
+ * vms_misc.c (vms_gettimeofday): new function.
+ * vms_fwrite.c [#if NO_ALLOCA]: fix fake alloca's use of free().
+
+ * vmsbuild.com: synchronize with current sources.
+
+Sun Jan 28 15:50:02 2001 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gawkmisc.vms (os_restore_mode): New function
+
+Sun Dec 3 16:53:37 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_setbinmode): new function.
+
+Tue Nov 7 14:09:14 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_is_setuid): new function.
+
+Wed Jul 30 19:53:52 1997 Arnold D. Robbins <arnold@gnu.ai.mit.edu>
+
+ * Close-on-exec changes:
+ gawkmisc.vms: (os_close_on_exec, os_isdir): new functions.
+
+Mon Aug 7 15:23:00 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.6: Release tar file made.
+
+Sat Jul 15 20:52:09 2000 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (printf1, fusmnam, fnamedat, numindex,
+ subslash, opasnslf, opasnidx, arynocls, getlnbuf,
+ arysubnm, fnparydl): New basic tests.
+ (igncdym): New gawk.extensions test.
+ (nondec): Old gawk.extensions test commented out.
+
+Sun Jun 25 15:08:19 2000 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.0.5: Release tar file made.
+
+Wed Jun 30 16:14:36 1999 Arnold D. Robbins <arnold@gnu.org>
+
+ * Release 3.0.4: Release tar file made. This time for sure.
+
+Fri May 7 20:29:04 1999 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h (__CRTL_VER): Add same override as __VMS_VER.
+
+Wed May 5 19:10:15 1999 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (nasty, zeroflag, getnr2tm, getnr2tb): New tests.
+
+Wed Nov 25 17:24:26 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (vms_tests): New general target.
+ (vms_io1): New specific test.
+
+Thu May 15 12:49:08 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.3: Release tar file made.
+
+Mon May 12 18:39:30 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (delarprm, prdupval): new `basic' tests.
+ (nondec): new `gawk.extensions' test (commented out for now).
+ (reint): move from `basic' to `gawk.extensions'.
+
+Mon May 5 21:40:07 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (clobber): new `basic' test.
+ (pid): new test, replacing `specfile'.
+ (pipeio2): new for `unix-tests'; can't execute this one under VMS.
+
+Mon May 5 21:23:52 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms_args.c (vms_arg_fixup): for the 2>&1 case, don't set the
+ output filename to "sys$error" because that results in an extra
+ empty file being created.
+
+ * vms_misc.c (vms_open): explicitly specify stream_lf format
+ when creating files rather than letting DECC$SHR make a new file
+ inherit its record format from any earlier version of that file.
+
+ Suggested by Pete Cascio <pete@rmi.net>:
+
+ * vms_misc.c (vms_open): use full record sharing options when
+ reading any record-oriented file, regardless of its organization.
+
+Mon Apr 21 19:22:12 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com (funstack): new `basic' test.
+ (reint): add missing entry to `basic'.
+ (pipeio1, specfile, strftlng): move from `basic' to `unix-tests'.
+ (childin): skip due to known failure.
+ (specfile): skip due to potentially confusing feedback.
+
+Thu Apr 24 23:18:04 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * vms_popen.c, vms_misc.c, vms_gawk.c, vms_fwrite.c,
+ vms_args.c: moved to generic GPL statement at top.
+
+Fri Apr 18 07:55:47 1997 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * BETA Release 3.0.34: Release tar file made.
+
+Wed Apr 2 18:17:30 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * descrip.mms, vmsbuild.com (PATCHLVL): update to 3.
+
+ * vmstest.com (nlfldsep, splitvar, intest, nfldstr, nors,
+ fnarydel, noparms, pipeio1): new tests.
+
+Wed Jan 15 15:21:01 1997 Pat Rankin <rankin@eql.caltech.edu>
+
+ * redirect.h (stat, fstat): do not declare these functions;
+ rely on <stat.h> to do so. There are too many DEC C version
+ variants to handle otherwise.
+
+ From Martin Zinser <zinser@axp602.gsi.de>:
+
+ * descrip.mms (gawk.dvi): update to build in [.doc] directory
+ using texindex.c retained from an earlier gawk 2.x distribution.
+ (texindex.exe): don't assume VAX C.
+
+Wed Dec 25 11:25:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.2: Release tar file made.
+
+Mon Dec 23 20:51:27 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms_misc.c (vms_bcopy): `bcopy' is defined as this in redirect.h.
+
+Thu Dec 19 17:49:31 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * redirect.h (strcasecmp, strncasecmp, tzset, tzname,
+ daylight, timezone, altzone, bcopy, popen, pclose, unlink):
+ New macros to avoid conflict with VMS V7.x DECC$SHR symbols.
+ (close, dup, dup2, read): Declare with full prototypes.
+ (fstat, stat): Ditto, and guard against conflicting DEC C
+ declarations (which might have trailing elipsis).
+ * vms_misc.c (tzset, tzname, daylight, timezone, altzone):
+ Suppress these if compiled with VMS_V7 defined [not supported].
+
+Mon Dec 16 14:32:08 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms_popen (popen): Delete unprototyped declaration of strcmp()
+ to avoid conflict with a strcmp macro in DEC C V5.0 header files.
+
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Fri Dec 6 20:55:57 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * redirect.h, vms-conf.h: Refine Sep 20th change: include
+ <stdlib.h> and <string.h> in redirect.h rather than vms-conf.h
+ so that it occurs for VMS POSIX as well as for normal VMS.
+
+Wed Nov 20 15:47:02 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * descrip.mms (LIBOBJS): Rename from GNUOBJS; add random.obj.
+ (LIBSRC): Rename from GNUSRC; add random.c.
+ (AWKSRC): Add random.h.
+ (random.obj, builtin.obj): Depend upon random.h.
+ * vmsbuild.com: compile random.c, link random.obj.
+
+ * vmstest.com (childin): Split message about expected failure
+ in order to avoid consecutive tick marks in the quoted string.
+
+Wed Nov 13 15:32:58 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com: New file to execute test suite.
+
+Fri Nov 8 18:29:42 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ Revise makefiles so that no editing should be needed.
+
+ * descrip.mms: Use DEC C as the default compiler, since
+ the same compile and link options for it can be used as-is
+ on both VAX and Alpha.
+ (GNUC, VAXC): New `make' macros for specifying an alternate
+ compiler on the MMS or MMK command line.
+ (PATCHLVL): Update to 1.
+ * vmsbuild.com: Make the equivalent changes.
+
+Mon Oct 28 17:02:39 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms.h (U_Long, U_Short): Replace u_long and u_short typedefs.
+ * vms_*.c: Use them.
+
+ * vms.h, vms_*.c: Change SYS$ and LIB$ routines to lower case
+ equivalents; fully prototype sys$ and lib$ routines rather than
+ just declare them.
+
+Fri Sep 20 17:33:05 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h: directly include <stdlib.h> and <string.h>.
+ * vms-conf.h (strftime): delete this macro.
+ * redirect.h (strftime): define it here instead.
+
+Fri May 17 09:08:16 1996 Arnold Robbins <arnold@skeeve.atl.ga.us>
+
+ * gawkmisc.vms (envsep): Now initialized to ',' instead of ':',
+ per email from Pat Rankin.
+
+Thu Jan 11 15:20:14 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h [#if __DECC]: Changes to support V5.x of DEC C.
+ (_DECC_V4SOURCE, __SOCKET_TYPEDEFS): Define these to avoid
+ duplicate u_long and u_short typedefs.
+ (__VMS_VER): If value indicates VMS V6.2 or later, redefine it to
+ indicate V6.1 in order to avoid conflicting prototype for getopt.
+
+Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * ChangeLog created.
--- /dev/null
+# Descrip.MMS -- Makefile for building GNU awk on VMS.
+#
+# usage:
+# $ MMS /Description=[.vms]Descrip.MMS gawk
+# possibly add `/Macro=("GNUC=1")' to compile with GNU C,
+# or add `/Macro=("GNUC=1","DO_GNUC_SETUP=1")' to compile with GNU C
+# on a system where GCC is not installed as a defined command,
+# or add `/Macro=("VAXC=1")' to compile with VAX C,
+# or add `/Macro=("VAXC=1","CC=cc/VAXC")' to compile with VAX C on
+# a system which has DEC C installed as the default compiler.
+#
+# gawk.exe :
+# This is the default target. DEC C has become the default compiler.
+#
+# awkgram.c :
+# If you don't have bison but do have VMS POSIX or DEC/Shell,
+# change the PARSER and PASERINIT macros to use yacc. If you don't
+# have either yacc or bison, you'll have to make sure that the
+# distributed version of "awkgram.c" has its modification date later
+# than the date of "awkgram.y", so that MMS won't try to build that
+# target. If you use bison and it is already defined system-wide,
+# comment out the PARSERINIT definition.
+#
+# install.help :
+# You can make the target 'install.help' to load the VMS help text
+# into a help library. Modify the HELPLIB macro if you don't want
+# to put entry into the regular VMS library. (If you use an alternate
+# help library, it must already exist; this target won't create it.)
+#
+# gawk.dvi :
+# If you have TeX, you can make the target 'gawk.dvi' to process
+# _The_GAWK_Manual_ from gawk.texi. You'll need to use a device
+# specific post-processor on gawk.dvi in order to get printable data.
+# The full output is approximately 325 pages.
+#
+
+# location of various source files, relative to the 'main' directory
+VMSDIR = [.vms]
+DOCDIR = [.doc]
+MAKEFILE = $(VMSDIR)Descrip.MMS
+
+# debugging &c !'ccflags' is an escape to allow external compile flags
+#CCFLAGS = /noOpt/Debug
+
+# a comma separated list of macros to define
+CDEFS = "GAWK","HAVE_CONFIG_H"
+
+.ifdef GNUC
+# assumes VAX
+CC = gcc
+CFLAGS = /Incl=([],$(VMSDIR))/Obj=[]/Def=($(CDEFS)) $(CCFLAGS)
+LIBS = gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library
+.ifdef DO_GNUC_SETUP
+# in case GCC command verb needs to be manually defined
+.first
+ set command gnu_cc:[000000]gcc
+.endif !DO_GNUC_SETUP
+.else !!GNUC
+.ifdef VAXC
+# always VAX; versions of VAX C older than V3.2 won't work
+CC = cc
+CFLAGS = /Incl=[]/Obj=[]/Opt=noInline/Def=($(CDEFS)) $(CCFLAGS)
+LIBS = sys$share:vaxcrtl.exe/Shareable
+.else !!VAXC
+# neither GNUC nor VAXC, assume DECC (same for either VAX or Alpha)
+CC = cc/DECC/Prefix=All
+CFLAGS = /Incl=[]/Obj=[]/Def=($(CDEFS)) $(CCFLAGS)
+LIBS = # DECC$SHR instead of VAXCRTL, no special link option needed
+.endif !VAXC
+.endif !GNUC
+
+
+PARSER = bison
+PARSERINIT = set command gnu_bison:[000000]bison
+#PARSER = yacc
+#PARSERINIT = yacc := posix/run/path=posix """/bin/yacc"
+#PARSERINIT = yacc := $shell$exe:yacc
+
+# this is used for optional target 'install.help'
+HELPLIB = sys$help:helplib.hlb
+#HELPLIB = sys$help:local.hlb
+
+#
+######## nothing below this line should need to be changed ########
+#
+
+ECHO = write sys$output
+NOOP = continue
+
+# object files
+AWKOBJ1 = array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,\
+ field.obj,gawkmisc.obj,getopt.obj,getopt1.obj,io.obj,main.obj,\
+ msg.obj,node.obj,random.obj,re.obj
+AWKOBJ2 = regex.obj,replace.obj,version.obj,eval.obj,profile.obj
+AWKOBJS = $(AWKOBJ1),$(AWKOBJ2)
+
+# VMSOBJS
+# VMS specific stuff
+VMSCODE = vms_misc.obj,vms_popen.obj,vms_fwrite.obj,vms_args.obj,\
+ vms_gawk.obj,vms_cli.obj
+VMSCMD = gawk_cmd.obj # built from .cld file
+VMSOBJS = $(VMSCODE),$(VMSCMD)
+
+# source and documentation files
+AWKSRC = array.c,builtin.c,ext.c,eval.c,dfa.c,field.c,gawkmisc.c,\
+ getopt.c,getopt1.c,io.c,main.c,msg.c,node.c,random.c,re.c,\
+ random.c,regcomp.c,regex.c,regex_internal.c,regexec.c,\
+ replace.c,version.c,eval.c,profile.c
+
+ALLSRC = $(AWKSRC),awkgram.y,awk.h,custom.h,dfa.h,getopt.h,\
+ gettext.h,mbsupport.h,protos.h,random.h
+
+VMSSRC = $(VMSDIR)gawkmisc.vms,$(VMSDIR)vms_misc.c,$(VMSDIR)vms_popen.c,\
+ $(VMSDIR)vms_fwrite.c,$(VMSDIR)vms_args.c,$(VMSDIR)vms_gawk.c,\
+ $(VMSDIR)vms_cli.c
+VMSHDRS = $(VMSDIR)redirect.h,$(VMSDIR)vms.h,$(VMSDIR)fcntl.h,\
+ $(VMSDIR)varargs.h,$(VMSDIR)unixlib.h
+VMSOTHR = $(VMSDIR)descrip.mms,$(VMSDIR)vmsbuild.com,$(VMSDIR)version.com,\
+ $(VMSDIR)gawk.hlp
+
+DOCS= $(DOCDIR)gawk.1,$(DOCDIR)gawk.texi,$(DOCDIR)texinfo.tex
+
+# Release of gawk
+REL=3.1
+PATCHLVL=5
+
+# generic target
+all : gawk
+ $(NOOP)
+
+# dummy target to allow building "gawk" in addition to explicit "gawk.exe"
+gawk : gawk.exe
+ $(ECHO) " GAWK "
+
+# rules to build gawk
+gawk.exe : $(AWKOBJS) $(VMSOBJS) gawk.opt
+ $(LINK) $(LINKFLAGS) gawk.opt/options
+
+gawk.opt : $(MAKEFILE) # create linker options file
+ open/write opt gawk.opt ! ~ 'cat <<close >gawk.opt'
+ write opt "! GAWK -- GNU awk"
+ @ write opt "$(AWKOBJ1)"
+ @ write opt "$(AWKOBJ2)"
+ @ write opt "$(VMSOBJS)"
+ @ write opt "psect_attr=environ,noshr !extern [noshare] char **"
+ @ write opt "stack=48 !preallocate more pages (default is 20)"
+ @ write opt "iosegment=128 !ditto (default is 32)"
+ write opt "$(LIBS)"
+ write opt "identification=""V$(REL).$(PATCHLVL)"""
+ close opt
+
+vms_misc.obj : $(VMSDIR)vms_misc.c
+vms_popen.obj : $(VMSDIR)vms_popen.c
+vms_fwrite.obj : $(VMSDIR)vms_fwrite.c
+vms_args.obj : $(VMSDIR)vms_args.c
+vms_gawk.obj : $(VMSDIR)vms_gawk.c
+vms_cli.obj : $(VMSDIR)vms_cli.c
+$(VMSCODE) : awk.h config.h $(VMSDIR)redirect.h $(VMSDIR)vms.h
+
+gawkmisc.obj : gawkmisc.c $(VMSDIR)gawkmisc.vms
+
+$(AWKOBJS) : awk.h gettext.h mbsupport.h regex.h dfa.h \
+ config.h $(VMSDIR)redirect.h
+random.obj : random.h
+builtin.obj : random.h
+awkgram.obj : awkgram.c awk.h
+dfa.obj : dfa.c dfa.h
+regex.obj : regex.c regcomp.c regex_internal.c regexec.c regex.h regex_internal.h
+
+# bison or yacc required
+awkgram.c : awkgram.y # foo.y :: yacc => y[_]tab.c, bison => foo_tab.c
+ @- if f$search("ytab.c") .nes."" then delete ytab.c;* !POSIX yacc
+ @- if f$search("y_tab.c") .nes."" then delete y_tab.c;* !DEC/Shell yacc
+ @- if f$search("awk_tab.c").nes."" then delete awk_tab.c;* !bison
+ - $(PARSERINIT)
+ $(PARSER) $(YFLAGS) $<
+ @- if f$search("ytab.c") .nes."" then rename/new_vers ytab.c $@
+ @- if f$search("y_tab.c") .nes."" then rename/new_vers y_tab.c $@
+ @- if f$search("awk_tab.c").nes."" then rename/new_vers awk_tab.c $@
+
+config.h : $(VMSDIR)vms-conf.h
+ copy $< $@
+
+$(VMSCMD) : $(VMSDIR)gawk.cld
+ set command $(CLDFLAGS)/object=$@ $<
+
+# special target for loading the help text into a VMS help library
+install.help : $(VMS)gawk.hlp
+ library/help $(HELPLIB) $< /log
+
+# miscellaneous other targets
+tidy :
+ - if f$search("*.*;-1").nes."" then purge
+ - if f$search("[.*]*.*;-1").nes."" then purge [.*]
+
+clean :
+ - delete *.obj;*,gawk.opt;*
+
+spotless : clean tidy
+ - if f$search("gawk.exe").nes."" then delete gawk.exe;*
+ - if f$search("gawk.dvi").nes."" then delete gawk.dvi;*
+ - if f$search("[.doc]texindex.exe").nes."" then delete [.doc]texindex.exe;*
+
+#
+# Note: this only works if you kept a copy of [.support]texindex.c
+# from a gawk 2.x distribution and put it into [.doc]texindex.c.
+# Also, depending on the fonts available with the version of TeX
+# you have, you might need to edit [.doc]texinfo.tex and change
+# the reference to "lcircle10" to be "circle10".
+#
+# build gawk.dvi from within the 'doc' subdirectory
+#
+gawk.dvi : [.doc]texindex.exe [.doc]gawk.texi
+ @ set default [.doc]
+ @ write sys$output " Warnings from TeX are expected during the first pass"
+ TeX gawk.texi
+ mcr []texindex gawk.cp gawk.fn gawk.ky gawk.pg gawk.tp gawk.vr
+ @ write sys$output " Second pass"
+ TeX gawk.texi
+ mcr []texindex gawk.cp gawk.fn gawk.ky gawk.pg gawk.tp gawk.vr
+ @ write sys$output " Third (final) pass"
+ TeX gawk.texi
+ -@ purge
+ -@ delete gawk.lis;,.aux;,gawk.%%;,.cps;,.fns;,.kys;,.pgs;,.toc;,.tps;,.vrs;
+ @ rename/new_vers gawk.dvi [-]*.*
+ @ set default [-]
+
+# Note: [.doc]texindex.c is not included with the gawk 3.x distribution.
+# Expect lots of "implicitly declared function" diagnostics from DEC C.
+#
+[.doc]texindex.exe : [.doc]texindex.c
+ @ set default [.doc]
+ $(CC) /noOpt/noList/Define=("lines=tlines") texindex.c
+ @ open/Write opt texindex.opt
+ @ write opt "texindex.obj"
+ @ write opt "$(LIBS)"
+ @ close opt
+ $(LINK) /noMap/Exe=texindex.exe texindex.opt/Options
+ -@ delete texindex.obj;*,texindex.opt;*
+ @ set default [-]
+
+#eof
--- /dev/null
+/* "fcntl.h" -- constants for BSD-style I/O routines (ala VAX C's <file.h>) */
+#define O_RDONLY 0
+#define O_WRONLY 1
+#define O_RDWR 2
+#define O_NDELAY 4
+#define O_NOWAIT 4
+#define O_APPEND 8
+#define O_CREAT 0x0200
+#define O_TRUNC 0x0400
+#define O_EXCL 0x0800
--- /dev/null
+! Gawk.Cld -- command defintion for GAWK
+! Pat Rankin, Nov'89
+! [ revised for 2.12, May'91 ]
+ module Gawk_Cmd
+define verb GAWK
+ synonym AWK
+! image gawk !usage $ DEFINE GAWK disk:[directory]GAWK
+ parameter p1, value(required,list), label=gawk_p1, prompt="data file(s)"
+ qualifier input, value(required,list,type=$infile), label=progfile
+ qualifier commands, value(required), label=program
+ qualifier field_separator, value(required), label=field_sep
+ qualifier reg_expr, value(type=reg_expr_keywords) !(OBSOLETE)
+ qualifier variables, value(required,list)
+ qualifier copyright
+ qualifier version
+ qualifier lint
+ qualifier posix
+ qualifier usage
+ qualifier strict, negatable
+ qualifier debug, negatable
+ qualifier output, value(type=$outfile,default="SYS$OUTPUT")
+ disallow progfile and program !or not progfile and not program
+define type reg_expr_keywords
+ keyword awk
+ keyword egrep, default !synonym for 'posix'
+ keyword posix !equivalent to 'egrep'
+!
+! p1 = data file list (possibly including 'var=value' contructs)
+!note: parameter required; use 'sys$input:' to read data from 'stdin'
+! /input = program source file ('-f progfile')
+! /commands = program source text ('program')
+!note: either input or commands, but not both; if neither, usage message given
+! /field_separator = character(s) delimiting record fields; default is "[ \t]"
+! /reg_expr = type of regular expressions: awk or posix (posix == egrep)
+!note: by default, use awk style; /reg_expr (w/o value), use egrep style
+! /variables = list of 'var=value' items for assignment prior to BEGIN
+! /posix = force POSIX compatability mode operation
+! /strict = force compatability mode operation (UN*X SYS V, Release 4)
+! /output = destination for print,printf (default is sys$output: ie, 'stdout')
+! /lint = scan the awk program for possible problems and warn about them
+! /debug = debugging mode
+!note: compilation options determine whether debug mode is valid
+! /usage = display 'usage' reminder [describing this VMS command syntax]
+! /version = show program version
+! /copyright = show abbreviated edition of FSF's copyright notice
+!
--- /dev/null
+! Gawk.Hlp
+! Pat Rankin, Jun'90
+! revised, Jun'91
+! revised, Jul'92
+! revised, Jan'95
+! revised, Apr'97
+! revised, Jan'03
+! Online help for GAWK.
+!
+1 GAWK
+ GAWK is GNU awk, the Free Software Foundation's implementation of
+ the awk programming language. awk is an interpretive language which
+ can handle many data-reformatting jobs with just a few lines of code.
+ It has powerful string manipulation and pattern matching capabilities
+ built in. This version is compatible with POSIX 1003.2 awk.
+
+ The VMS version of GAWK supports both the original UN*X-style command
+ interface and a DCL interface. The only setup requirement for GAWK
+ is to define it as a 'foreign' command: a DCL symbol with a value
+ which begins with '$'.
+ $ GAWK :== $disk:[directory]GAWK
+2 GNU_syntax
+ GAWK's UN*X-style interface uses the 'dash' convention for specifying
+ options and uses spaces to separate multiple arguments.
+
+ There are two main alternatives, depending on how the awk program is
+ to be passed to GAWK. Both alternatives share most options.
+
+ Usage: $ gawk [-W opts] [-F fs] [-v var=val] -f progfile [--] file ...
+ or $ gawk [-W opts] [-F fs] [-v var=val] [--] "program" file ...
+
+ The options are case-sensitive. On VMS, the DCL command interpreter
+ converts unquoted text into uppercase before passing it to the running
+ program. However, GAWK is written in 'C' and the C Run-Time Library
+ (VAXCRTL or DECC$SHR) converts unquoted text into *lowercase*.
+ Therefore, the -Fval and -W options must be enclosed in quotes.
+3 options
+ -f file use the specified file as the awk program source; if more
+ than one instance of -f is used, each file will be read
+ in succession
+ -Fstring define a value for the FS variable (field separator)
+ -v var=val assign a value of 'val' to the variable 'var'
+ -W 'options' additional gawk-specific options; multiple values may
+ be separated by commas, or by spaces if they're quoted,
+ or mulitple occurrences of -W may be used.
+ -W compat use awk "compatibility mode" to disable GAWK extensions
+ and get the behavior of UN*X awk.
+ -W copyright [or -W copyleft] display an abbreviated version of
+ the GNU copyright information
+ -W help list command line options (same as -W usage)
+ -W lint warn about suspect or non-portable awk program code
+ -W lint-old warn about constructs not available in original awk
+ -W posix compatibility mode with additional restrictions
+ -W re-interval evaluate '{' and '}' as intervals in regular expressions
+ -W traditional suppress POSIX and GNU regular expression extensions
+ -W usage list command line options (same as -W help)
+ -W version display program version number
+ -- don't check further arguments for leading dash
+3 program_text
+ If the '-f file' option is not used on the command line, then the
+ first "non-dash" argument is assumed to be a string of text containing
+ the awk source program. Here is a complete sample program:
+ $ gawk -- "BEGIN {print ""\nHello, World!\n""}"
+ This program would print a blank line (based on first "\n"), followed
+ by a line reading "Hello, World!", followed by another blank line
+ (since awk's 'print' statement includes the trailing 'newline').
+
+ On VMS, to include a quote character inside of a quoted string, two
+ successive quotes ("") must be used.
+3 data_files
+ After all dash-options are examined, and after the program text if
+ there were no occurrences of the -f option, remaining (space separated)
+ command line arguments are considered to be data files for the awk
+ program to process. If any of these actually contains an equals sign
+ (=), then it is interpreted as a variable assignment instead of a data
+ file. The syntax is 'variable_name=value'. For example, the command
+ $ gawk -f myprog.awk infile.one flag=2 start=0 infile.two
+ would read file 'infile.one' for the program in 'myprog.awk', then it
+ would set 'flag' to 2 and 'start' to 0, and finally it would read file
+ 'infile.two' for the program. Note that in a case like this, the two
+ assignments actually occur after the first file has been processed,
+ not at program startup when the command line is first scanned.
+3 IO_redirection
+ The command parsing in the VMS implementation of GAWK does some
+ emulation of a UN*X-style shell, where certain characters on the
+ command line have special meaning. In particular, the symbols '<',
+ '>', '|', '*', and '?' receive special handling before the main part
+ of the program has a chance to see them. The symbols '<' and '>'
+ perform some file manipulation from the command line:
+
+ <ifile open file 'ifile' (readonly) as 'stdin' [SYS$INPUT]
+ >nfile create 'nfile' as 'stdout' [SYS$OUTPUT], in stream-lf format
+ >>ofile append to 'ofile' for 'stdout'; create it if necessary
+ >&efile point 'stderr' [SYS$ERROR] at 'efile', but don't open it yet
+ >$vfile create 'vfile' as 'stdout', using RMS attributes appropriate
+ for a standard text file (variable length records with
+ implied carriage control)
+ >+bfile create 'bfile' as 'stdout' using binary mode
+ 2>&1 route error messages into the regular output stream
+ 1>&2 send output data to the error destination
+ <<sentinel error; reading stdin until 'sentinel' not supported
+ <-, >- error; closure of stdin or stdout from cmd line not supported
+ >>$vfile incorrect; would be interpreted as file "$vfile" in stream-lf
+ format rather than as file "vfile" in RMS 'text' format
+ | error; command line pipes not supported
+3 wildcard_expansion
+ The command parsing in the VMS implementation of GAWK does some
+ emulation of a UN*X-style shell, where certain characters on the
+ command line have special meaning. In particular, the symbols '<',
+ '>', '*', '%', and '?' receive special handling before the main part
+ of the program has a chance to see them. The symbols '*', '%' and '?'
+ are used as wildcards in filenames. '*' and '%' have their usual VMS
+ meanings of multiple character and single character wildcards,
+ respectively, and '?' is also treated as a single character wildcard.
+ Wildcard expansion only works for filenames specified in native VMS
+ filename syntax (eg, "[-.sibling]*"), not for ones specified pseudo-
+ Unix syntax (eg, "../sibling/*").
+
+ When a command line argument that should be a filename contains any
+ of the wildcard characters, a directory lookup is attempted for files
+ which match the specified pattern. If one or more matching files are
+ found, those filenames are put into the command line in place of the
+ original pattern. If no matching files are found, the original
+ pattern is left in place.
+2 DCL_syntax
+ GAWK's DCL-style interface is more or less a standard DCL command, with
+ one required parameter. Multiple values--when present--are separated
+ by commas.
+
+ There are two main alternatives, depending on how the awk program is
+ to be passed to GAWK. Both alternatives share most options.
+
+ Usage: GAWK /COMMANDS="awk program text" data_file[,data_file,...]
+ or GAWK /INPUT=awk_file data_file[,"Var=value",data_file,...]
+ ( or GAWK /INPUT=(awk_file1,awk_file2,...) data_file[,...] )
+3 Parameter
+ data_file[,datafile,...] (data_file data_file ...)
+ data_file[,"Var=value",...,data_file,...] (data_file Var=value &c)
+
+ Data file(s) for the awk program to process. If any of these
+ actually contains an equals sign (=), then it is interpreted as
+ a variable assignment instead of a data file. The syntax is
+ "variable_name=value". Quotes are required for non-file parameters.
+
+ For example, the command
+ $ gawk/input=myprog.awk infile.one,"flag=2","start=0",infile.two
+ would read file 'infile.one' for the program in 'myprog.awk', then it
+ would set 'flag' to 2 and 'start' to 0, and finally it would read file
+ 'infile.two' for the program. Note that in a case like this, the two
+ assignments actually occur after the first file has been processed,
+ not at program startup when the command line is first scanned.
+
+ Wildcard file lookups are attempted on data file specifications. See
+ subtopic 'GAWK GNU_syntax wildcard_expansion' for details.
+
+ At least one data_file parameter value is required. An exception is
+ made if /usage, /version, or /copyright is specified *and* if GAWK is
+ defined as a 'foreign' command rather than a 'native' DCL command.
+3 Qualifiers
+/COMMANDS
+ /COMMANDS="awk program text" (-- "awk program text")
+
+ For short programs, it is possible to include the complete program
+ on the command line. The quotes are required. Here is a complete
+ sample program:
+ $ gawk/commands="BEGIN {print ""\nHello, World!\n""}" NL:
+ This program would print a blank line (based on first "\n"), followed
+ by a line reading "Hello, World!", followed by another blank line
+ (since awk's 'print' statement includes the trailing 'newline').
+
+ To include a quote character inside of a quoted string, two
+ successive quotes ("") must be used.
+
+ Either /COMMANDS or /INPUT (but not both) must be supplied.
+/INPUT
+ /INPUT=(awk_file1,awk_file2) (-f awk_file1 -f awk_file2)
+
+ Used to specify one or more files containing the source code of
+ the awk program. If more than one file is used, separate them
+ with commas and enclose the list in parentheses.
+
+ Multiple source files are processed in order as if they had been
+ concatenated together.
+
+ Either /INPUT or /COMMANDS (but not both) must be supplied.
+/FIELD_SEPARATOR
+ /FIELD_SEPARATOR="FS_value" (-F"FS_value")
+
+ Assign a value to the built in variable FS (field separator).
+/VARIABLES
+ /VARIABLES=("Var1=val1","Var2=val2",...) (-v Var1=val1 -v Var2=val2)
+
+ Assign value(s) to the specified variable(s).
+/REG_EXPR
+ /REG_EXPR={AWK | EGREP | POSIX} (-a vs -e options [obsolete])
+
+ This qualifier is obsolete and has no effect.
+/STRICT
+ /[NO]STRICT (-"W compat" option)
+
+ Use strict awk compatibility mode (/strict) and suppress GAWK
+ extensions. The default is /NOSTRICT.
+/POSIX
+ /[NO]POSIX (-"W posix" option)
+
+ Use POSIX compatibility mode (/posix) and suppress GAWK extensions.
+ The default is /NOPOSIX. Slightly more restrictive than /strict.
+/LINT
+ /[NO]LINT (-"W lint" option)
+
+ Check the awk program cafefully for potential problems that might
+ be encountered if it were to be used with other awk implementations,
+ and print warnings for anything found. The default in /NOLINT.
+/VERSION
+ /VERSION (-"W version" option)
+
+ Print GAWK's version number.
+/COPYRIGHT
+ /COPYRIGHT (-"W copyright" or -"W copyleft" option)
+
+ Print a brief version of GAWK's copyright notice.
+/USAGE
+ /USAGE (comparable to -"W usage" or -"W help" option)
+
+ Print a compact summary of the command line options.
+
+ After the 'usage' message is printed, GAWK terminates regardless
+ of any other command line options.
+/OUTPUT
+ /OUTPUT=out_file (>$out_file)
+
+ Write program output into 'out_file'. The default is SYS$OUTPUT.
+2 awk_language
+ An awk program consists of one or more pattern-action pairs, sometimes
+ referred to as "rules". For each record of an input (data) file, the
+ rules are checked sequentially. Any pattern which matches the input
+ record triggers that rule's action. Actions are instructions which
+ resemble statements in the 'C' programming language. Patterns come
+ in several varieties, including field comparisons, regular expression
+ matching, and special cases defined by reserved keywords.
+
+ All awk keywords and variables are case-sensitive. Text matching is
+ also sensitive to character case unless the builtin variable IGNORECASE
+ is set to a non-zero value.
+3 rules
+ The syntax for a pattern-action 'rule' is simply
+ PATTERN { ACTION }
+ where the braces ({}) are required punctuation for the action.
+ Semicolons (;) or 'newlines' (ie, having the text on a separate line)
+ delimit multiple rules and also multiple actions within a given rule.
+ Either the pattern or the action may be omitted; an empty pattern
+ matches every record of the input file; a missing action (not an empty
+ action inside of braces), is an implicit request to print the current
+ record; an empty action (ie, {}) is legal but not very useful.
+3 patterns
+ There are several types of patterns available for awk rules.
+
+ expression an 'expression' is something to be evaluated (perhaps
+ a comparison or function call) which will
+ be considered true if non-zero (for numeric
+ results) or if non-null (for strings)
+ /regular_expression/ slashes (/) delimit a regular expression
+ which is used as a pattern
+ pattern1, pattern2 a pair of patterns separated by a comma (,),
+ which causes a range of records to trigger
+ the associated action; the records which
+ match the patterns are included in the range
+ <null> an omitted pattern (in this text, the string '<null>'
+ is displayed, but in an awk program, it
+ would really be blank) matches every record
+ BEGIN keyword for specifying a rule to be executed prior to
+ reading the 1st record of the 1st input file
+ END keyword for specifying a rule to be executed after
+ handling the last input record of last file
+4 examples
+ Some example patterns (mostly with the corresponding actions omitted)
+
+ NF > 0 # comparison expression: matches non-null records
+ $0 # implied comparison: also matches non-null records
+ $2 > 1000 && sum <= 999999 # slightly more elaborate expression
+ /x/ # regular expression matching any record with an 'x' in it
+ /^ / # reg-expr matching records beginning with a space
+ $1 == "start", $NF == "stop" # range pattern for input in which
+ some data lines begin with 'start' and/or end with
+ 'stop' in order to collect groups of records
+ { sum += $1 } # null pattern: it's action (add field #1 to
+ variable 'sum') would be executed for every record
+ BEGIN { sum = 0 } # keyword 'BEGIN': perform this action before
+ reading the input file (note: initialization to 0 is
+ unnecessary in awk)
+ END { print "total =", sum } # keyword 'END': perform this
+ action after the last input record has been processed
+3 actions
+ An 'action' is something to do when a given record has matched the
+ corresponding pattern in a rule. In general, actions resemble 'C'
+ statements and expressions. The action in a rule must be enclosed
+ in braces ({}).
+
+ Each action can contain more than one statement or expression to be
+ executed, provided that they're separated by semicolons (;) and/or
+ on separate lines.
+
+ An omitted action is equivalent to
+ { print $0 }
+ which prints the current record.
+3 operators
+ Relational operators
+ == compare for equality
+ != compare for inequality
+ <, <=, >, >= numerical or lexical comparison (less than, less or
+ equal, greater than, greater or equal, respectively)
+ ~ match against a regular expression
+ !~ match against a regular expression, but accept failed matches
+ instead of successful ones
+ Arithmetic operators
+ + addition
+ - subtraction
+ * multiplication
+ / division
+ % remainder
+ ^, ** exponentiation ('**' is a synonym for '^', unless POSIX
+ compatibility is specified, in which case it's invalid)
+ Boolean operators (aka Logical operators)
+ a value is considered false if it's 0 or a null string,
+ it is true otherwise; the result of a boolean operation
+ (and also of a comparison operation) will be 0 when false
+ or 1 when true
+ || or [expression (a || b) is true if either a is true or b
+ is true or both a and b are true; it is false otherwise;
+ b is not evaluated unless a is false (ie, short-circuit)]
+ && and [expression (a && b) is true if both a and b are true;
+ it is false otherwise; b is only evaluated if a is true]
+ ! not [expression (!a) is true if a is false, false otherwise]
+ in array membership; the keyword 'in' tests whether the value
+ on the left represents a current subscript in the array
+ named on the right
+ Conditional operator
+ ? : the conditional operator takes three operands; the first is
+ an expression to evaluate, the second is the expression to
+ use if the first was true, the third is the expression to
+ use if it was false [simple example (a < b ? b : a) gives
+ the maximum of a and b]
+ Assignment operators
+ = store the value on the right into the variable or array slot
+ on the left [expression (a = b) stores the value of b in a]
+ +=, -=, *=, /=, %=, ^=, **= perform the indicated arithmetic
+ operation using the current value of the variable or array
+ element of the left side and the expression on the right
+ side, then store the result in the left side
+ ++ increment by 1 [expression (++a) gets the current value of
+ a and adds 1 to it, stores that back in a, and returns the
+ new value; expression (a++) gets the current value of a,
+ adds 1 to it, stores that back in a, but returns the
+ original value of a]
+ -- decrement by 1 (analogous to increment)
+ String operators
+ there is no explicit operator for string concatenation;
+ two values and/or variables side-by-side are implicitly
+ concatenated into a string (numeric values are first
+ converted into their string equivalents)
+ Conversion between numeric and string values
+ there is no explicit operator for conversion; adding 0
+ to a string with force it to be converted to a number
+ (the numeric value will be 0 if the string does not
+ represent an integer or floating point number); the
+ reverse, converting a number into a string, is done by
+ concatenating a null string ("") to it [the expression
+ (5.75 "") evaluates to "5.75"]
+ Field 'operator'
+ $ prefixing a number or variable with a dollar sign ($)
+ causes the appropriate record field to be returned [($2)
+ gives the second field of the record, ($NF) gives the
+ last field (since the builtin variable NF is set to the
+ number of fields in the current record)]
+ Array subscript operator
+ , multi-dimensional arrays are simulated by using comma (,)
+ separated array indices; the actual index is generated
+ by replacing commas with the value of builtin SUBSEP,
+ then concatenating the expression into a string index
+ [comma is also used to separate arguments in function
+ calls and user-defined function definitions]
+ [comma is *also* used to indicate a range pattern in an
+ awk rule]
+ Escape 'operator'
+ \ In quoted character strings, the backslash (\) character
+ causes the following character to be interpreted in a
+ special manner [string "one\ntwo" has an embedded newline
+ character (linefeed on VMS, but treated as if it were both
+ carriage-return and linefeed); string "\033[" has an ASCII
+ 'escape' character (which has octal value 033) followed by
+ a 'right-bracket' character]
+ Backslash is also used in regular expressions
+ Redirection operators
+ < Read-from -- valid with 'getline'
+ > Write-to (create new file) -- valid with 'print' and 'printf'
+ >> Append-to (create file if it doesn't already exist)
+ | Pipe-from/to -- valid with 'getline', 'print', and 'printf'
+4 precedence
+ Operator precedence, listed from highest to lowest. Assignment,
+ conditional, and exponentiation operators group from right to left;
+ all others group from left to right. Parentheses may be used to
+ override the normal order.
+
+ field ($)
+ increment (++), decrement (--)
+ exponentiation (^, **)
+ unary plus (+), unary minus (-), boolean not (!)
+ multiplication (*), division (/), remainder (%)
+ addition (+), subtraction (-)
+ concatenation (no special symbol; implied by context)
+ relational (==, !=, <, >=, etc), and redirection (<, >, >>, |)
+ Relational and redirection operators have the same precedence
+ and use similar symbols; context distinguishes between them
+ matching (~, !~)
+ array membership ('in')
+ boolean and (&&)
+ boolean or (||)
+ conditional (? :)
+ assignment (=, +=, etc)
+4 escaped_characters
+ Inside of a quoted string or constant regular expression, the
+ backslash (\) character gives special meaning to the character(s)
+ after it. Special character letters are case sensitive.
+ \\ results in one backslash in the string
+ \a is an 'alert' (<ctrl/G>. the ASCII <bell> character)
+ \b is a backspace (BS, <ctrl/H>)
+ \f is a form feed (FF, <ctrl/L>)
+ \n 'newline' (<ctrl/J> [line feed treated as CR+LF]
+ \r carriage return (CR, <ctrl/M> [re-positions at the
+ beginning of the current line]
+ \t tab (HT, <ctrl/I>)
+ \v vertical tab (VT, <ctrl/K>)
+ \### is an arbitrary character, where '###' represents 1 to 3
+ octal (ie, 0 thru 7) digits
+ \x## is an alternate arbitrary character, where '##' represents
+ 1 or more hexadecimal (ie, 0 thru 9 and/or A through E
+ and/or a through e) digits; if more than two digits
+ follow, the result is undefined; not recognized if POSIX
+ compatibility mode is specified.
+
+ When a regular expression is represented in string form ("regex"
+ as opposed to /regex/), backslashes need to be paired. The first
+ one quotes the second during string processing, and the second one
+ remains to be used to quote whatever follows in regular expression
+ processing. For example, to match variable `xxx' against a period
+ character, use (xxx ~ "\\.") or (xxx ~ /\./); if you tried to use
+ (xxx ~ "\."), after string processing it would operate as (xxx ~ /./)
+ and end up matching any single character rather than just a period.
+3 statements
+ A statement refers to a unit of instruction found in the action
+ part of an awk rule, and also found in the definition of a function.
+ The distinction between action, statement, and expression usually
+ won't matter to an awk programmer.
+
+ Compound statements consist of multiple statements separated by
+ semicolons or newlines and enclosed within braces ({}). They are
+ sometimes referred to as 'blocks'.
+4 expressions
+ An expression such as 'a = 10' or 'n += i++' is a valid statement.
+
+ Function invocations such as 'reformat_field($3)' are also valid
+ statements.
+4 if-then-else
+ A conditional statement in awk uses the same syntax as for the 'C'
+ programming language: the 'if' keyword, followed by an expression
+ in parentheses, followed by a statement--or block of statements
+ enclosed within braces ({})--which will be executed if the expression
+ is true but skipped if it's false. This can optionally be followed
+ by the 'else' keyword and another statement--or block of statements--
+ which will be executed if (and only if) the expression was false.
+5 examples
+ Simple example showing a statement used to control how many numbers
+ are printed on a given line.
+ if ( ++i <= 10 ) #check whether this would be the 11th
+ printf(" %5d", k) #print on current line if not
+ else {
+ printf("\n %5d", k) #print on next line if so
+ i = 1 #and reset the counter
+ }
+ Another example ('next' is described under 'action-controls')
+ if ($1 > $2) { print "rejected"; next } else diff = $2 - $1
+4 loops
+ Three types of loop statements are available in awk. Each uses
+ the same syntax as 'C'. The simplest of the three is the 'while'
+ statement. It consists of the 'while' keyword, followed by an
+ expression enclosed within parentheses, followed by a statement--or
+ block of statements in braces ({})--which will be executed if the
+ expression evaluates to true. The expression is evaluated before
+ attempting to execute the statement; if it's true, the statement is
+ executed (the entire block of statements if there is a block) and
+ then the expression is re-evaluated.
+
+ The second type of loop is the do-while loop. It consists of the
+ 'do' keyword, followed by a statement (usually a block of statements
+ enclosed within braces), followed by the 'while' keyword, followed
+ by a test expression enclosed within parentheses. The statement--or
+ block--is always executed at least once. Then the test expression
+ is evaluated, and the statement(s) re-executed if the result was
+ true (followed by re-evaluation of the test, and so on).
+
+ The most complex of the three loops is the 'for' statement, and it
+ has a second variant that is not found in 'C'. The ordinary for-loop
+ consists of the 'for' keyword, followed by three semicolon-separated
+ expressions enclosed within parentheses, followed by a statement or
+ brace-enclosed block of statements. The first of the three
+ expressions is an initialization clause; it is done before starting
+ the loop. The second expression is used as a test, just like the
+ expression in a while-loop. It is checked before attempting to
+ execute the statement block, and then re-checked after each execution
+ (if any) of the block. The third expression is an 'increment' clause;
+ it is evaluated after an execution of the statement block and before
+ re-evaluation of the test (2nd) expression. Normally, the increment
+ clause will change a variable used in the test clause, in such a
+ fashion that the test clause will eventually evaluate to false and
+ cause the loop to finish.
+
+ Note to 'C' programmers: the comma (,) operator commonly used in
+ 'C' for-loop expressions is not valid in awk.
+
+ The awk-specific variant of the for-loop is used for processing
+ arrays. Its syntax is 'for' keyword, followed by variable_name 'in'
+ array_name (where 'var in array' is enclosed in parentheses),
+ followed by a statement (or block). Each valid subscript value for
+ the array in question is successively placed--in no particular
+ order--into the specified 'index' variable.
+5 while_example
+ # strip fields from the input record until there's nothing left
+ while (NF > 0) {
+ $1 = "" #this will affect the value of $0
+ $0 = $0 #this causes $0 and NF to be re-evaluated
+ print
+ }
+5 do_while_example
+ # This is a variation of the while_example; it gives a slightly
+ # different display due to the order of operation.
+ # echo input record until all fields have been stripped
+ do {
+ print #output $0
+ $1 = "" #this will affect the value of $0
+ $0 = $0 #this causes $0 and NF to be re-evaluated
+ } while (NF > 0)
+5 for_example
+ # echo command line arguments (won't include option switches)
+ for ( i = 0; i < ARGC; i++ ) print ARGV[i]
+
+ # display contents of builtin environment array
+ for (itm in ENVIRON)
+ print itm, ENVIRON[itm]
+4 loop-controls
+ There are two special statements--both from 'C'--for changing the
+ behavior of loop execution. The 'continue' statement is useful in
+ a compound (block) statement; when executed, it effectively skips
+ the rest of the block so that the increment-expression (only for
+ for-loops) and loop-termination expression can be re-evaluated.
+
+ The 'break' statement, when executed, effectively skips the rest
+ of the block and also treats the test expression as if it were
+ false (instead of actually re-evaluating it). In this case, the
+ increment-expression of a for-loop is also skipped.
+
+ Inside nested loops, both 'break' and 'continue' only apply to the
+ innermost loop. When in compatibility mode, 'break' or 'continue'
+ may be used outside of a loop; either will be treated like 'next'
+ (see action-controls).
+4 action-controls
+ There are two special statements for controlling statement execution.
+ The 'next' statement, when executed, causes the rest of the current
+ action and all further pattern-action rules to be skipped, so that
+ the next input record will be immediately processed. This is useful
+ if any early action knows that the current record will fail all the
+ remaining patterns; skipping those rules will reduce processing time.
+ An extended form, 'next file', is also available. It causes the
+ remainder of the current file to be skipped, and then either the
+ next input file will be processed, if any, or the END action will be
+ performed. 'next file' is not available in traditional awk.
+
+ The 'exit' statement causes GAWK execution to terminate. All open
+ files are closed, and no further processing is done. The END rule,
+ if any, is executed. 'exit' takes an optional numeric value as a
+ argument which is used as an exit status value, so that some sort
+ of indication of why execution has stopped can be passed on to the
+ user's environment.
+4 other_statements
+ The delete statement is used to remove an element from an array.
+ The syntax is 'delete' keyword followed by array name, followed
+ by index value enclosed in square brackets ([]). 'delete' may
+ also used on an array name, without any index specified, to delete
+ all its elements in a single operation.
+
+ The return statement is used in user-defined functions. The syntax
+ is the keyword 'return' optionally followed by a string or numeric
+ expression.
+
+ See also subtopic 'functions IO_functions' for a description of
+ 'print', 'printf', and 'getline'.
+3 fields
+ When an input record is read, it is automatically split into fields
+ based on the current values of FS (builtin variable defining field
+ separator expression) and RS (builtin variable defining record
+ separator character). The default value of FS is an expression
+ which matches one or more spaces and tabs; the default for RS is
+ newline. If the FIELDWIDTHS variable is set to a space separated
+ list of numbers (as in ``FIELDWIDTHS = "2 3 2"'') then the input
+ is treated as if it had fixed-width fields of the indicated sizes
+ and the FS value will be ignored.
+
+ The field prefix operator ($), is used to reference a particular
+ field. For example, $3 designates the third field of the current
+ record. The entire record can be referenced via $0 (and it holds
+ the actual input record, not the values of $1, $2, ... concatenated
+ together, so multiple spaces--when present--remain intact, unless
+ a new value gets assigned).
+
+ The builtin variable NF holds the number of fields in the current
+ record. $NF is therefore the value of the last field. Attempts to
+ access fields beyond NF result in null values (if a record contained
+ 3 fields, the value of $5 would be "").
+
+ Assigning a new value to $0 causes all the other field values (and NF)
+ to be re-evaluated. Changing a specific field will cause $0 to receive
+ a new value once it's re-evaluated, but until then the other existing
+ fields remain unchanged.
+3 variables
+ Variables in awk can hold both numeric and string values and do not
+ have to be pre-declared. In fact, there is no way to explicitly
+ declare them at all. Variable names consist of a leading letter
+ (either upper or lower case, which are distinct from each other)
+ or underscore (_) character followed by any number of letters,
+ digits, or underscores.
+
+ When a variable that didn't previously exist is referenced, it is
+ created and given a null value. A null value is treated as 0 when
+ used as a number, and is a string of zero characters in length if
+ used as a string.
+4 builtin_variables
+ GAWK maintains several 'built-in' variables. All have default values;
+ some are updated automatically. All the builtins have uppercase-only
+ names.
+
+ These builtin variables control how awk behaves
+ FS input field separator; default is a single space, which is
+ treated as if it were a regular expression for matching
+ one or more spaces and/or tabs; a value of " " also has a
+ second special-case side-effect of causing leading blanks
+ to be ignored instead of producing a null first field;
+ initial value can be specified on the command line with
+ the -F option (or /field_separator); the value can be a
+ regular expression
+ RS input record separator; default value is a newline ("\n");
+ the value can be multiple characters or a regular expression
+ OFS output field separator; value to place between variables in
+ a 'print' statement; default is one space; can be arbitrary
+ string
+ ORS output record separator; value to implicitly terminate 'print'
+ statement with; default is newline ("\n"); can be arbitrary
+ string
+ OFMT default output format used for printing numbers; default
+ value is "%.6g"
+ CONVFMT conversion format used for number-to-string conversions;
+ default value is also "%.6g", like OFMT; not used when the
+ number has a value which may be represented internally as
+ an exact integer (typically within -2147483648 to 2147483647)
+ SUBSEP subscript separator for array indices; used when an array
+ subscript is specified as a comma separated list of values:
+ the comma is replaced by SUBSEP and the resulting index
+ is a concatenation of the values and SUBSEP(s); default
+ value is "\034"; value may be arbitrary string
+ IGNORECASE string and regular expression matching flag; if true
+ (non-zero) matching ignores differences between upper and
+ lower case letters; affects the '~' and '!~' operators,
+ the 'index', 'match', 'split', 'sub', and 'gsub' functions,
+ and field splitting based on FS; default value is false (0);
+ has no effect if GAWK is in strict compatibility mode
+ FIELDWIDTHS space or tab separated list of width sizes; takes
+ precedence over FS when set, but is cleared if FS has a
+ value assigned to it; [note: the current implementation
+ of fixed-field input is considered experimental and is
+ expected to evolve over time]
+
+ These builtin variables provide useful information
+ NF number of fields in the current record
+ NR record number (accumulated over all files when more than one
+ input file is processed by the same program)
+ FNR current record number of the current input file; reset to 0
+ each time an input file is completed
+ RT record terminator, the input text which matched RS; not
+ available when the `-W traditional' option is used
+ RSTART starting position of substring matched by last invocation
+ of the 'match' function; set to 0 if a match fails and at
+ the start of each input record
+ RLENGTH length of substring matched by the last invocation of the
+ 'match' function; set to -1 if a match fails
+ FILENAME name of the input file currently being processed; the
+ special name "-" is used to represent the standard input
+ ENVIRON array of miscellaneous user environment values; the VMS
+ implementation of GAWK provides values for ["USER"] (the
+ username), ["PATH"] (current default directory), ["HOME"]
+ (the user's login directory), and "[TERM]" (terminal type
+ if available) [all info provided by C RTL's environ]
+ ERRNO information about the cause of failure for 'getline' or
+ 'close'; "0" if no such failure has occured.
+ ARGC number of elements in the ARGV array, counting [0] which is
+ the program name (ie, "gawk")
+ ARGV array of command-line arguments (in [0] to [ARGC-1]); the
+ program name (ie, "gawk") in held in ARGV[0]; command line
+ parameters (data files and "var=value" expressions, but not
+ program options or the awk program text string if present)
+ are stored in ARGV[1] through ARGV[ARGC-1]; the awk program
+ can change values of ARGC and ARGV[] during execution in
+ order to alter which files are processed or which between-
+ file assignments are made
+ ARGIND current index into ARGV[]
+4 arrays
+ awk supports associative arrays to collect data into tables. Array
+ elements can be either numeric or string, as can the indices used to
+ access them. Each array must have a unique name, but a given array
+ can hold both string and numeric elements at the same time. Arrays
+ are one-dimensional only, but multi-dimensional arrays can be
+ simulated using comma (,) separated indices, whereby a single index
+ value gets created by replacing commas with SUBSEP and concatenating
+ the resulting expression into a single string.
+
+ Referencing an array element is done with the expression
+ Array[Index]
+ where 'Array' represents the array's name and 'Index' represents a
+ value or expression used for a subscript. If the requested array
+ element did not exist, it will be created and assigned an initial
+ null value. To check whether an element exists without creating it,
+ use the 'in' boolean operator.
+ Index in Array
+ would check 'Array' for element 'Index' and return 1 if it existed
+ or 0 otherwise. To remove an element from an array, use the 'delete'
+ statement
+ delete Array[Index]
+ To remove all array elements at once, use
+ delete Array
+ Note: the latter is a gawk extension; also, there is no way to
+ delete an ordinary variable or an entire array; 'delete' only works
+ on array elements.
+
+ To process all elements of an array (in succession) when their
+ subscripts might be unknown, use the 'in' variant of the for-loop
+ for (Index in Array) { ... }
+3 functions
+ awk supports both built-in and user-defined functions. A function
+ may be considered a 'black-box' which accepts zero or more input
+ parameters, performs some calculations or other manipulations based
+ on them, and returns a single result.
+
+ The syntax for calling a function consists of the function name
+ immediately followed by an open parenthesis (left parenthesis '('),
+ followed by an argument list, followed by a closing parenthesis
+ (right parenthesis ')'). The argument list is a sequence of values
+ (numbers, strings, variables, array references, or expressions
+ involving the above and/or nested function calls), separated by
+ commas and optional white space.
+
+ The parentheses are required punctuation, except for the 'print' and
+ 'printf' builtin IO functions, where they're optional, and for the
+ builtin IO function 'getline', where they're not allowed. Some
+ functions support optional [trailing] arguments which can be simply
+ omitted (along with the corresponding comma if applicable).
+4 numeric_functions
+ Builtin numeric functions
+ int(n) returns the value of 'n' with any fraction truncated
+ [truncation of negative values is towards 0]
+ sqrt(n) the square root of n
+ exp(n) the exponential of n ('e' raised to the 'n'th power)
+ log(n) natural logarithm of n
+ sin(n) sine of n (in radians)
+ cos(n) cosine of n (radians)
+ atan2(m,n) arctangent of m/n (radians)
+ rand() random number in the range 0 to 1 (exclusive)
+ srand(s) sets the random number 'seed' to s, so that a sequence
+ of 'random' numbers can be repeated; returns the
+ previous seed value; srand() [argument omitted] sets
+ the seed to an 'unpredictable' value (based on date
+ and time, for instance, so should be unrepeatable)
+4 string_functions
+ Builtin string functions
+ index(s,t) search string s for substring t; result is 1-based
+ offset of t within s, or 0 if not found
+ length(s) returns the length of string s; either 'length()'
+ with its argument omitted or 'length' without any
+ parenthesized argument list will return length of $0
+ match(s,r) search string s for regular expression r; the offset
+ of the longest, left-most substring which matches
+ is returned, or 0 if no match was found; the builtin
+ variables RSTART and RLENGTH are also set [RSTART to
+ the return value and RLENGTH to the size of the
+ matching substring, or to -1 if no match was found]
+ split(s,a,f) break string s into components based on field
+ separator f and store them in array a (into elements
+ [1], [2], and so on); the last argument is optional,
+ if omitted, the value of FS is used; the return value
+ is the number of components found
+ sprintf(f,e,...) format expression(s) e using format string f and
+ return the result as a string; formatting is similar
+ to the printf function
+ sub(r,t,s) search string target s for regular expression r, and
+ if a match is found, replace the matching text with
+ substring t, then store the result back in s; if s
+ is omitted, use $0 for the string; the result is
+ either 1 if a match+substitution was made, or 0
+ otherwise; if substring t contains the character
+ '&', the text which matched the regular expression
+ is used instead of '&' [to suppress this feature
+ of '&', 'quote' it with a backslash (\); since this
+ will be inside a quoted string which will receive
+ 'backslash' processing before being passed to sub(),
+ *two* consecutive backslashes will be needed "\\&"]
+ gsub(r,t,s) similar to sub(), but gsub() replaces all nonoverlapping
+ substrings instead of just the first, and the return
+ value is the number of substitutions made
+ gensub(r,t,n,s) search string s ($0 if omitted) for regexp r and
+ replace the n'th occurrence with substring t; the
+ result is the new string and s (or $0) remains
+ unchanged; if n begins with letter "g" or "G" then
+ all matches are replaced instead of just the n'th;
+ if r has parenthesized subexpressions in it, t may
+ contain the special sequences \\0, \\1, through \\9
+ which expand into the value of the corresponding
+ subexpression; this function is a gawk extension
+ substr(s,p,l) extract a substring l characters long starting at
+ offset p in string s; l is optional, if omitted then
+ the remainder of the string (p thru end) is returned
+ tolower(s) return a copy of string s in which every uppercase
+ letter has been converted into lowercase
+ toupper(s) analogous to tolower(); convert lowercase to uppercase
+4 time_functions
+ Builtin time functions
+ systime() return the current time of day as the number of seconds
+ since some reference point; on VMS the reference point
+ is January 1, 1970, at 12 AM local time (not UTC)
+ strftime(f,t) format time value t using format f; if t is omitted,
+ the default is systime()
+5 time_formats
+ Formatting directives similar to the 'printf' & 'sprintf' functions
+ (each is introduced in the format string by preceding it with a
+ percent sign (%)); the directive is substituted by the corresponding
+ value
+ a abbreviated weekday name (Sun,Mon,Tue,Wed,Thu,Fri,Sat)
+ A full weekday name
+ b abbreviated month name (Jan,Feb,...)
+ B full month name
+ c date and time (Unix-style "aaa bbb dd HH:MM:SS YYYY" format)
+ C century prefix (19 or 20) [not century number, ie 20th]
+ d day of month as two digit decimal number (01-31)
+ D date in mm/dd/yy format
+ e day of month with leading space instead of leading 0 ( 1-31)
+ E ignored; following format character used
+ H hour (24 hour clock) as two digit number (00-23)
+ h abbreviated month name (Jan,Feb,...) [same as %b]
+ I hour (12 hour clock) as two digit number (01-12)
+ j day of year as three digit number (001-366)
+ m month as two digit number (01-12)
+ M minute as two digit number (00-59)
+ n 'newline' (ie, treat %n as \n)
+ O ignored; following format character used
+ p AM/PM designation for 12 hour clock
+ r time in AM/PM format ("II:MM:SS p")
+ R time without seconds ("HH:MM")
+ S second as two digit number (00-59)
+ t tab (ie, treat %t as \t)
+ T time ("HH:MM:SS")
+ U week of year (00-53) [first Sunday is first day of week 1]
+ V date (VMS-style "dd-bbb-YYYY" with 'bbb' forced to uppercase)
+ w weekday as decimal digit (0 [Sunday] through 6 [Saturday])
+ W week of year (00-53) [first _Monday_ is first day of week 1]
+ x date ("aaa bbb dd YYYY")
+ X time ("HH:MM:SS")
+ y year without century (00-99)
+ Y year with century (19yy-20yy)
+ Z time zone name (always "local" for VMS)
+ % literal percent sign (%)
+4 IO_functions
+ Builtin I/O functions
+ print x,... print the values of one or more expressions; if none
+ are listed, $0 is used; parentheses are optional;
+ when multiple values are printed, the current value
+ of builtin OFS (default is 1 space) is used to
+ separate them; the print line is implicitly
+ terminated with the current value of ORS (default
+ is newline); print does not have a return value
+ printf(f,x,...) print the values of one or more expressions, using
+ the specified format string; null strings are used
+ to supply missing values (if any); no between field
+ or trailing newline characters are printed, they
+ should be specified within the format string; the
+ argument-enclosing parentheses are optional;
+ printf does not have a return value
+ getline v read a record into variable v; if v is omitted, $0 is
+ used (and NF, NR, and FNR are updated); if v is
+ specified, then field-splitting won't be performed;
+ note: parentheses around the argument are *not*
+ allowed; return value is 1 for successful read, 0
+ if end of file is encountered, or -1 if some sort
+ of error occurred; [see 'redirection' for several
+ variants]
+ close(s) close a file or pipe specified by the string s; the
+ string used should have the same value as the one
+ used in a getline or print/printf redirection
+ fflush(s) flush output stream s; if s is omitted, stdout is
+ flushed; if it is specified but its value is an
+ empty string, all output streams are flushed
+ system(s) pass string s to executed by the operating system;
+ the command string is executed in a subprocess
+5 redirection
+ Both getline and print/printf support variant forms which use
+ redirection and pipes.
+
+ To read from a file (instead of from the primary input file), use
+ getline var < "file"
+ or getline < "file" (read into $0)
+ where the string "file" represents either an actual file name (in
+ quotes) or a variable which contains a file name string value or an
+ expression which evaluates to a string filename.
+
+ To create a pipe executing some command and read the result into
+ a variable (or into $0), use
+ "command" | getline var
+ or "command" | getline (read into $0)
+ where "command" is a literal string containing an operating system
+ command or a variable with a string value representing such a
+ command.
+
+ To output into a file other that the primary output, use
+ print x,... > "file" (or >> "file")
+ or printf(f,x,...) > "file" (or >> "file")
+ similar to the 'getline' example above. '>>' causes output to be
+ appended to an existing file if it exists, or create the file if
+ it doesn't already exist. '>' always creates a new file. The
+ alternate redirection method of '>$' (for RMS text file attributes)
+ is *only* available on the command line, not with 'print' or
+ 'printf' in the current release.
+
+ To output an error message, use 'print' or 'printf' and redirect
+ the output to file "/dev/stderr" (or equivalently to "SYS$ERROR:"
+ on VMS). 'stderr' will normally be the user's terminal, even if
+ ordinary output is being redirected into a file.
+
+ To feed awk output into another command, use
+ print x,... | "command" (similarly for 'printf')
+ similar to the second 'getline' example. In this case, output
+ from awk will be passed as input to the specified operating system
+ command. The command must be capable of reading input from 'stdin'
+ ("SYS$INPUT:" on VMS) in order to receive data in this manner.
+
+ The 'close' function operates on the "file" or "command" argument
+ specified here (either a literal string or a variable or expression
+ resulting in a string value). It completely closes the file or
+ pipe so that further references to the same file or command string
+ would re-open that file or command at the beginning. Closing a
+ pipe or redirection also releases some file-oriented resources.
+
+ Note: the VMS implementation of GAWK uses temporary files to
+ simulate pipes, so a command must finish before 'getline' can get
+ any input from it, and 'close' must be called for an output pipe
+ before any data can be passed to the specified command.
+5 formats
+ Formatting characters used by the 'printf' and 'sprintf' functions
+ (each is introduced in the format string by preceding it with a
+ percent sign (%))
+ % include a literal percent sign (%) in the result
+ c format the next argument as a single ASCII character
+ (prints first character of string argument, or corresponding
+ ASCII character if numeric argument, e.g. 65 is 'A')
+ s format the next argument as a string (numeric arguments are
+ converted into strings on demand)
+ d decimal number (ie, integer value in base 10)
+ i integer (equivalent to decimal)
+ o octal number (integer in base 8)
+ x hexadecimal number (integer in base 16) [lowercase]
+ X hexadecimal number [digits 'A' thru 'E' in uppercase]
+ f floating point number (digits, decimal point, fraction digits)
+ e exponential (scientific notation) number (digit, decimal
+ point, fraction digits, letter 'e', sign '+' or '-',
+ exponent digits)
+ g 'fractional' number in either 'e' or 'f' format, whichever
+ produces shorter result
+
+ Several optional modifiers can be placed between the initiating
+ percent sign and the format character (doesn't apply to %%).
+ - left justify (only matters when width specifier is present)
+ (space) for numeric specifiers, prefix nonnegative values with
+ a space and negative values with a minus sign
+ + for numeric specifiers, prefix nonnegative values with a plus
+ sign and negative values with a minus sign
+ # alternate form applicable to several of the format characters
+ (o, x, X, e, E, f, g, G)
+ NN width ['NN' represents 1 or more decimal digits]; actually
+ minimum width to use, longer items will not be truncated; a
+ leading 0 will cause right-justified numbers to be padded on
+ the left with zeroes instead of spaces when they're aligned
+ .MM precision [decimal point followed by 1 or more digits]; used
+ as maximum width for strings (causing truncation if they're
+ actually longer) or as number of fraction digits for 'f' or
+ 'e' numeric formats, or number of significant digits for 'g'
+ numeric format
+4 user_defined_functions
+ User-defined functions may be created as needed to simplify awk
+ programs or to collect commonly used code into one place. The
+ general syntax of a user-defined function is the 'function' keyword
+ followed by unique function name, followed by a comma-separated
+ parameter list enclosed in parentheses, followed by statement(s)
+ enclosed within braces ({}). A 'return' statement is customary
+ but is not required.
+ function FuncName(arg1,arg2) {
+ # arbitrary statements
+ return (arg1 + arg2) / 2
+ }
+ If a function does not use 'return' to specify an output value, the
+ result received by the caller will be unpredictable.
+
+ Functions may be placed in an awk program before, between, or after
+ the pattern-action rules. The abbreviation 'func' may be used in
+ place of 'function', unless POSIX compatibility mode is in effect.
+3 regular_expressions
+ A regular expression is a shorthand way of specifying a 'wildcard'
+ type of string comparison. Regular expression matching is very
+ fundamental to awk's operation.
+
+ Meta symbols
+ ^ matches beginning of line or beginning of string; note that
+ embedded newlines ('\n') create multi-line strings, so
+ beginning of line is not necessarily beginning of string
+ $ matches end of line or end of string
+ . any single character (except newline)
+ [ ] set of characters; [ABC] matches either 'A' or 'B' or 'C'; a
+ dash (other than first or last of the set) denotes a range
+ of characters: [A-Z] matches any upper case letter; if the
+ first character of the set is '^', then the sense of match
+ is reversed: [^0-9] matches any non-digit; several
+ characters need to be quoted with backslash (\) if they
+ occur in a set: '\', ']', '-', and '^'; within sets,
+ various special character class designations are recognized,
+ such as [:digit:] and [:punct:], as per POSIX
+ | alternation (similar to boolean 'or'); match either of two
+ patterns [for example "^start|stop$" matches leading 'start'
+ or trailing 'stop']
+ ( ) grouping, alter normal precedence [for example, "^(start|stop)$"
+ matches lines reading either 'start' or 'stop']
+ * repeated matching; when placed after a pattern, indicates that
+ the pattern should match any number of times [for example,
+ "[a-z][0-9]*" matches a lower case letter followed by zero or
+ more digits]
+ + repeated matching; when placed after a pattern, indicates that
+ the pattern should match one or more times ["[0-9]+" matches
+ any non-empty sequence of digits]
+ ? optional matching; indicates that the pattern can match zero or
+ one times ["[a-z][0-9]?" matches lower case letter alone or
+ followed by a single digit]
+ { } interval specification; {n} to match n times or {m,n} to match
+ at least m but not more than n times; only functional when
+ either the `-W posix' or `-W re-interval' options are used
+ \ quote; prevent the character which follows from having special
+ meaning; if the regexp is specified as a string, then the
+ backslash itself will need to be quoted by preceding it with
+ another backslash
+
+ A regular expression which matches a string or line will match against
+ the first (left-most) substring which meets the pattern and include
+ the longest sequence of characters which still meets that pattern.
+3 comments
+ Comments in awk programs are introduced with '#'. Anything after
+ '#' on a line is ignored by GAWK. It's a good idea to include an
+ explanation of what an awk program is doing and also who wrote it
+ and when.
+3 further_information
+ For complete documentation on GAWK, see "Effective AWK Programming"
+ by Arnold Robbins. The second edition (ISBN 1-57831-000-8) is jointly
+ published by SSC and the FSF (http://www.ssc.com).
+
+ Source text for it is present in the file GAWK.TEXI. A postscript
+ version is available via anonymous FTP from host gnudist.gnu.org in
+ directory /gnu/gawk, file gawk-{version}-doc.tar.gz where {version}
+ would be the current version number, such as 3.0.6.
+
+ Another source of documentation is "The AWK Programming Language"
+ by Aho, Weinberger, and Kernighan (1988), published by Addison-Wesley.
+ ISBN code is 0-201-07981-X.
+
+ Each of these works contains both a reference on the awk language
+ and a tutorial on awk's use, with many sample programs.
+3 authors
+ The awk programming language was originally created by Alfred V. Aho,
+ Peter J. Weinberger, and Brian W. Kernighan in 1977. The language
+ was revised and enhanced in a new version which was released in 1985.
+
+ GAWK, the GNU implementation of awk, was written in 1986 by Paul Rubin
+ and Jay Fenlason, with advice from Richard Stallman, and with
+ contributions from John Woods. In 1988 and 1989, David Trueman and
+ Arnold Robbins revised GAWK for compatibility with the newer awk.
+ Arnold Robbins is the current maintainer.
+
+ GAWK version 2.11.1 was ported to VMS by Pat Rankin in November, 1989,
+ with further revisions in the Spring of 1990. The VMS port was
+ incorporated into the official GNU distribution of version 2.13 in
+ Spring 1991. (Version 2.12 was never publically released.)
+2 release_notes
+ GAWK 3.1.2 handles parsing of the command line differently than
+ earlier versions for the case where there is a single token, which
+ often yielded a "missing required element" error in earlier versions.
+
+ [Note for 3.1.x: these release notes haven't been updated in quite
+ some time. Most of the information is still applicable though.]
+
+ GAWK 3.0.3 tested under VAX/VMS V6.2 and Alpha/VMS V6.2, April, 1997;
+ should be compatible with VMS versions V4.6 and later. Current source
+ code is compatible with DEC's DEC C v5.x or VAX C v3.2; also compiles
+ successfully with GNU C (tested with gcc-vms 2.7.1).
+3 AWK_LIBRARY
+ GAWK uses a built in search path when looking for a program file
+ specified by the -f option (or the /input qualifier) when that file
+ name does not include a device and/or directory. GAWK will first
+ look in the current default directory, then if the file wasn't found
+ it will look in the directory specified by the translation of logical
+ name "AWK_LIBRARY".
+3 known_problems
+ There are several known problems with GAWK running on VMS. Some can
+ be ignored, others require work-arounds.
+4 file_formats
+ If a file having the RMS attribute "Fortran carriage control" is
+ read as input, it will generate an empty first record if the first
+ actual record begins with a space (leading space becomes a newline).
+ Also, the last record of the file will give a "record not terminated"
+ warning. Both of these minor problems are due to the way that the
+ C Run-Time Library (VAXCRTL) converts record attributes.
+
+ Another poor feature without a work-around is that there's no way to
+ specify "append if possible, create with RMS text attributes if not"
+ with the current command line I/O redirection. '>>$' isn't supported.
+ Ditto for binary output; '>>+' isn't supported.
+4 RS_peculiarities
+ Changing the record separator to something other than newline ('\n')
+ will produce anomalous results for ordinary files. For example,
+ using RS = "\f" and FS = "\n" with the following input
+ |rec 1, line 1
+ |rec 1, line 2
+ |^L (form feed)
+ |rec 2, line 1
+ |rec 2, line 2
+ |^L (form feed)
+ |rec 3, line 1
+ |rec 3, line 2
+ |(end of file)
+ will produce two fields for record 1, but three fields each for
+ records 2 and 3. This is because the form-feed record delimiter is
+ on its own line, so awk sees a newline after it. Since newline is
+ now a field separator, records 2 and 3 will have null first fields.
+ The following awk code will work-around this problem by inserting
+ a null first field in the first record, so that all records can be
+ handled the same by subsequent processing.
+ # fix up for first record (RS != "\n")
+ FNR == 1 { if ( $0 == "" ) #leading separator
+ next #skip its null record
+ else #otherwise,
+ $0 = FS $0 #realign fields
+ }
+ There is a second problem with this same example. It will always
+ trigger a "record not terminated" warning when it reaches the end of
+ file. In the sample shown, there is no final separator; however, if
+ a trailing form-feed were present, it would produce a spurious final
+ record with two null fields. This occurs because the I/O system
+ sees an implicit newline at the end of the last record, so awk sees
+ a pair of null fields separated by that newline. The following code
+ fragment will fix that provided there are no null records (in this
+ case, that would be two consecutive lines containing just form-feeds).
+ # fix up for last record (RS != "\n")
+ $0 == FS { next } #drop spurious final record
+ Note that the "record not terminated" warning will persist.
+4 cmd_inconsistency
+ The DCL qualifier /OUTPUT is internally equivalent to '>$' output
+ redirection, but the qualifier /INPUT corresponds to the -f option
+ rather than to '<' input redirection.
+4 exit
+ The exit statement can optionally pass a final status value to the
+ operating system. GAWK expects a UN*X-style value instead of a
+ VMS status value, so 0 indicates success and non-zero indicates
+ failure. The final exit status will be 1 (VMS success) if 0 is
+ used, or even (VMS non-success) if non-zero is used.
+!3 changes
+3 prior_changes
+ Changes between version 3.0.6 and 2.15.6
+
+ General
+ RS can contain multiple characters or be a regexp
+ Regular expression interval support added
+ gensub() and fflush() functions added
+ memory leak(s) introduced in 3.0.2 or 3.0.1 fixed
+ the user manual has been substantially revised
+
+ VMS-specific
+ Switched to build with DEC C by default
+ Changes between version 2.15.6 and 2.14
+
+ General
+ Many obscure bugs fixed
+ `delete' may operate on an entire array
+ ARGIND and ERRNO builtin variables added
+
+ VMS-specific
+ `>+ file' binary-mode output redirection added
+ /variable=(foo=42) fixed
+ Floating point number formatting improved
+
+ Changes between version 2.14 and 2.13.2:
+
+ General
+ 'next file' construct added
+ 'continue' outside of any loop is treated as 'next'
+ Assorted bug fixes and efficiency improvements
+ _The_GAWK_Manual_ updated
+ Test suite expanded
+
+ VMS-specific
+ VMS POSIX support added
+ Disk I/O throughput enhanced
+ Pipe emulation improved and incorrect interaction with user-mode
+ redefinition of SYS$OUTPUT eliminated
+
+ Changes between version 2.13 and 2.11.1: (2.12 was not released)
+
+ General
+ CONVFMT and FIELDWIDTHS builtin control variables added
+ systime() and strftime() date/time functions added
+ 'lint' and 'posix' run-time options added
+ '-W' command line option syntax supercedes '-c', '-C', and '-V'
+ '-a' and '-e' regular expression options made obsolete
+ Various bug fixes and efficiency improvements
+ More platforms supported ('officially' including VMS)
+
+ VMS-specific
+ %g printf format fixed
+ Handling of '\' on command line modified; no longer necessary to
+ double it up
+ Problem redirecting stderr (>&efile) at same time as stdin (<ifile)
+ or stdout (>ofile) has been fixed
+ ``2>&1'' and ``1>&2'' redirection constructs added
+ Interaction between command line I/O redirection and gawk pipes
+ fixed; also, name used for pseudo-pipe temporary file expanded
+3 license
+ GAWK is covered by the "GNU General Public License", the gist of which
+ is that if you supply this software to a third party, you are expressly
+ forbidden to prevent them from supplying it to a fourth party, and if
+ you supply binaries you must make the source code available to them
+ at no additional cost. Any revisions or modified versions are also
+ covered by the same license. There is no warranty, express or implied,
+ for this software. It is provided "as is."
+
+ [Disclaimer: This is just an informal summary with no legal basis;
+ refer to the actual GNU General Public License for specific details.]
+!2 examples
+!
--- /dev/null
+/*
+ * gawkmisc.vms --- miscellanious gawk routines that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-1996, 2003 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Progamming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+char quote = '\'';
+char *defpath = DEFPATH;
+char envsep = ',';
+
+/* gawk_name --- pull out the "gawk" part from how the OS called us */
+
+char *
+gawk_name(filespec)
+const char *filespec;
+{
+ char *p, *q;
+
+ /* "device:[root.][directory.subdir]GAWK.EXE;n" -> "GAWK" */
+ p = strrchr(filespec, ']'); /* directory punctuation */
+ q = strrchr(filespec, '>'); /* alternate <international> punct */
+
+ if (p == NULL || q > p)
+ p = q;
+ p = strdup(p == NULL ? filespec : (p + 1));
+ if ((q = strrchr(p, '.')) != NULL)
+ *q = '\0'; /* strip .typ;vers */
+
+ return p;
+}
+
+/* os_arg_fixup --- fixup the command line */
+
+void
+os_arg_fixup(argcp, argvp)
+int *argcp;
+char ***argvp;
+{
+ (void) vms_arg_fixup(argcp, argvp);
+}
+
+/* os_devopen --- open special per-OS devices */
+
+int
+os_devopen(name, flag)
+const char *name;
+int flag;
+{
+ return vms_devopen(name, flag);
+}
+
+/* optimal_bufsize --- determine optimal buffer size */
+
+size_t
+optimal_bufsize(fd, stb)
+int fd;
+struct stat *stb;
+{
+
+ /* force all members to zero in case OS doesn't use all of them. */
+ memset(stb, '\0', sizeof(struct stat));
+
+ /*
+ * These values correspond with the RMS multi-block count used by
+ * vms_open() in vms/vms_misc.c.
+ */
+ if (isatty(fd) > 0)
+ return BUFSIZ;
+ else if (fstat(fd, stb) < 0)
+ return 8*512; /* conservative in case of DECnet access */
+ else
+ return 32*512;
+}
+
+/* ispath --- return true if path has directory components */
+
+int
+ispath(file)
+const char *file;
+{
+ for (; *file; file++) {
+ switch (*file) {
+ case ':':
+ case ']':
+ case '>':
+ case '/':
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* isdirpunct --- return true if char is a directory separator */
+
+int
+isdirpunct(c)
+int c;
+{
+ return (strchr(":]>/", c) != NULL);
+}
+
+/* os_close_on_exec --- set close on exec flag, print warning if fails */
+
+void
+os_close_on_exec(fd, name, what, dir)
+int fd;
+const char *name, *what, *dir;
+{
+ /* no-op */
+}
+
+/* os_isdir --- is this an fd on a directory? */
+
+#if ! defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+int
+os_isdir(fd)
+int fd;
+{
+ struct stat sbuf;
+
+ return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
+}
+
+/* os_is_setuid --- true if running setuid root */
+
+int
+os_is_setuid()
+{
+ return 0;
+}
+
+/* os_setbinmode --- set binary mode on file */
+
+int
+os_setbinmode (fd, mode)
+int fd, mode;
+{
+ return 0;
+}
+
+/* os_restore_mode --- restore the original mode of the console device */
+
+void
+os_restore_mode (fd)
+int fd;
+{
+ /* no-op */
+ return;
+}
--- /dev/null
+# The VMS POSIX `c89' command writes any/all diagnostic info to stdout
+# rather than stderr, confusing configure tests which capture error output.
+#
+# Also, the VMS linker issues a warning for any undefined symbol, but that
+# does not inhibit creation of the final executable file, again confusing
+# configure. As an added complication, there's not enough control of the
+# linker to put the map file with chosen name into the current directory.
+#
+if [ -f ~/_posix-cc.map ] ; then rm -f ~/_posix-cc.map* ; fi
+c89 -Wc,nowarn -Wl,nodebug -Wl,map=_posix-cc.map $* ; x=$?
+if [ -f ~/_posix-cc.map ] ; then
+ if [ -n "`fgrep LINK-W-USEUNDEF ~/_posix-cc.map`" ] ; then x=1 ; fi
+ rm -f ~/_posix-cc.map*
+fi
+if [ x -ne 0 ] ; then echo "c89 reports failure" 1>&2 && exit 1 ; fi
+exit 0
--- /dev/null
+/*
+ * redirect.h --- definitions for functions that are OS specific.
+ */
+
+/*
+ * Copyright (C) 1986, 88, 89, 91-93, 1996, 1997 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* This file is included by custom.h for VMS-POSIX, or first
+ by config.h (vms-conf.h) then again by awk.h for normal VMS. */
+
+#if defined(VMS_POSIX) || defined(IN_CONFIG_H)
+
+#define DEFAULT_FILETYPE ".awk"
+
+/* some macros to redirect some non-VMS-specific code */
+#define getopt gnu_getopt
+#define opterr gnu_opterr
+#define optarg gnu_optarg
+#define optind gnu_optind
+#define optopt gnu_optopt
+#define regcomp gnu_regcomp
+#define regexec gnu_regexec
+#define regfree gnu_regfree
+#define regerror gnu_regerror
+#ifndef VMS_POSIX
+#define strftime gnu_strftime /* always use missing/strftime.c */
+#define strcasecmp gnu_strcasecmp
+#define strncasecmp gnu_strncasecmp
+#ifndef VMS_V7
+#define tzset fake_tzset
+#define tzname fake_tzname
+#define daylight fake_daylight
+#define timezone fake_timezone
+#define altzone fake_altzone
+#endif
+#if !defined(__DECC) && !defined(VAXC2DECC) && !defined(__alpha)
+#define strcoll(s,t) strcmp((s),(t)) /* VAXCRTL lacks locale support */
+#endif
+#endif
+
+#ifdef STDC_HEADERS
+/* This is for getopt.c and alloca.c (compiled with HAVE_CONFIG_H defined),
+ to prevent diagnostics about various implicitly declared functions. */
+#include <stdlib.h>
+#include <string.h>
+#endif
+#ifndef VMS_POSIX
+/* This if for random.c. */
+#define gettimeofday vms_gettimeofday
+#ifndef __TIMEVAL
+#define __TIMEVAL 1
+struct timeval { long tv_sec, tv_usec; };
+#endif
+extern int gettimeofday(struct timeval *,void *);
+#endif
+
+#else /* awk.h, not POSIX */
+
+/* some macros to redirect to code in vms/vms_misc.c */
+#ifndef bcopy
+#define bcopy vms_bcopy
+#endif
+#define exit vms_exit
+#define open vms_open
+#define popen vms_popen
+#define pclose vms_pclose
+#define strerror vms_strerror
+#define strdup vms_strdup
+#define unlink vms_unlink
+#if defined(VAXC) || (defined(__GNUC__) && !defined(__alpha))
+#define fstat(fd,sb) VMS_fstat(fd,sb)
+#endif
+extern void exit P((int));
+extern int open P((const char *,int,...));
+extern char *strerror P((int));
+extern char *strdup P((const char *str));
+extern int vms_devopen P((const char *,int));
+# ifndef NO_TTY_FWRITE
+#define fwrite tty_fwrite
+#define fclose tty_fclose
+extern size_t fwrite P((const void *,size_t,size_t,FILE *));
+extern int fclose P((FILE *));
+# endif
+extern FILE *popen P((const char *,const char *));
+extern int pclose P((FILE *));
+extern void vms_arg_fixup P((int *,char ***));
+/* some things not in STDC_HEADERS */
+extern size_t gnu_strftime P((char *,size_t,const char *,const struct tm *));
+extern int unlink P((const char *));
+extern int getopt P((int,char **,char *));
+extern int isatty P((int));
+#ifndef fileno
+extern int fileno P((FILE *));
+#endif
+extern int close P((int));
+extern int dup P((int));
+extern int dup2 P((int, int));
+extern int read P((int, void *, int));
+extern int getpgrp P((void));
+extern void tzset P((void));
+
+#endif /* not VMS_POSIX and not IN_CONFIG_H */
+
+/*vms/redirect.h*/
--- /dev/null
+/* "unixlib.h" -- limited substitute for VAX C V3.x's <unixlib.h>,
+ * for use with VAX C V2.x and/or GNU C when building gawk.
+ */
+
+
+/* declare the global environ[] array */
+#ifdef VAXC
+extern char noshare **environ;
+#else
+# ifdef __GNUC__
+# define environ $$PsectAttributes_NOSHR$$environ
+# endif
+extern char **environ;
+#endif
+
+/* miscellaneous Unix emulation routines available in VAXCRTL */
+char *getenv(), *getcwd();
+
+char *ecvt(), *fcvt(), *gcvt();
+
+int getpid(), getppid();
+
+unsigned getuid();
+#ifndef _stdlib_h /* gcc's stdlib.h has these with conflicting types */
+unsigned getgid(), getegid(), geteuid();
+#endif
+int setgid(), setuid(); /* no-ops */
--- /dev/null
+/* "varargs.h" -- old style variable argument list manipulation (for VAX) */
+#ifndef __GNUC__
+
+ /* Use the system's macros with the system's compiler. */
+#include <varargs.h>
+
+#else /*__GNUC__*/
+
+# if defined(__VAX__) || defined(__vax__) || defined(VAX) || defined(vax)
+ /* These macros implement traditional (non-ANSI) varargs for GNU C on VAX */
+
+# if !defined(_VA_LIST) && !defined(_VA_LIST_)
+# define _VA_LIST
+# define _VA_LIST_
+typedef char *va_list;
+# endif
+
+# define va_alist _varargs
+# define va_dcl int va_alist;
+# define va_start(AP) AP = (va_list) &va_alist
+# define va_end(AP)
+
+# define _va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
+# define va_arg(AP,TYPE) \
+ (AP += _va_rounded_size(TYPE), \
+ *((TYPE *) (AP - _va_rounded_size(TYPE))))
+
+# if defined(__VMS__) || defined(__vms__) || defined(VMS) || defined(vms)
+ /* VAX C compatability macros */
+# define va_count(CNT) vaxc$va_count(&CNT) /* rtl routine */
+# define va_start_1(AP,OFFSET) AP = (va_list) (&va_alist + (OFFSET))
+# endif /* VMS */
+
+# endif /* VAX */
+
+#endif /*__GNUC__*/
--- /dev/null
+#ifndef CONFIG_H
+#define CONFIG_H
+/*
+ * config.h -- configuration definitions for gawk.
+ *
+ * For VMS (assumes V4.6 or later; tested on V5.5-2 and V7.1)
+ */
+
+/*
+ * Copyright (C) 1991-1992, 1995-1996, 1999, 2001, 2002, 2003, 2005 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* switch statements are enabled in awk programs */
+#undef ALLOW_SWITCH
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+#if 0
+/* Define to 1 if using alloca.c. */
+#define C_ALLOCA 1
+#else
+#define NO_ALLOCA /* vms/vms_fwrite.c needs this */
+#endif
+
+/* dynamic loading is possible */
+#undef DYNAMIC
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
+
+/* Define to the type of elements in the array set by `getgroups'. Usually
+ this is either `int' or `gid_t'. */
+#define GETGROUPS_T int
+
+/* Define to 1 if the `getpgrp' function requires zero arguments. */
+#define GETPGRP_VOID 1
+
+/* Define to 1 if you have the `alarm' function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define if the GNU dcgettext() function is already present or preinstalled.
+ */
+#undef HAVE_DCGETTEXT
+
+/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_FEOF_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FGETS_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETC_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you
+ don't. */
+#define HAVE_DECL__SNPRINTF 0
+
+/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you
+ don't. */
+#define HAVE_DECL__SNWPRINTF 0
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fmod' function. */
+#define HAVE_FMOD 1
+
+/* Define to 1 if you have the `fwprintf' function. */
+#undef HAVE_FWPRINTF
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getegid' function. */
+#undef HAVE_GETEGID
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define to 1 if you have the `getgrent' function. */
+#undef HAVE_GETGRENT
+
+/* Define to 1 if you have the `getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define to 1 if you have the `grantpt' function. */
+#undef HAVE_GRANTPT
+
+/* Define if you have the iconv() function. */
+#undef HAVE_ICONV
+
+/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+#undef HAVE_INTMAX_T
+
+/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
+#undef HAVE_INTTYPES_H
+
+/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
+ declares uintmax_t. */
+#undef HAVE_INTTYPES_H_WITH_UINTMAX
+
+/* Define to 1 if you have the `iswctype' function. */
+#undef HAVE_ISWCTYPE
+
+/* Define to 1 if you have the `iswlower' function. */
+#undef HAVE_ISWLOWER
+
+/* Define to 1 if you have the `iswupper' function. */
+#undef HAVE_ISWUPPER
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#undef HAVE_LANGINFO_CODESET
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the 'long double' type. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define if you have the 'long long' type. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the `mbrlen' function. */
+#undef HAVE_MBRLEN
+
+/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
+#undef HAVE_MBRTOWC
+
+/* Define to 1 if you have the <mcheck.h> header file. */
+#undef HAVE_MCHECK_H
+
+/* Define to 1 if you have the `memcmp' function. */
+#define HAVE_MEMCMP 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mempcpy' function. */
+#undef HAVE_MEMPCPY
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* we have the mktime function */
+#define HAVE_MKTIME 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* we have portals on /p on this system */
+#undef HAVE_PORTALS
+
+/* Define if your printf() function supports format strings with positions. */
+#undef HAVE_POSIX_PRINTF
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the <signum.h> header file. */
+#undef HAVE_SIGNUM_H
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* we have sockets on this system */
+#undef HAVE_SOCKETS
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
+ uintmax_t. */
+#undef HAVE_STDINT_H_WITH_UINTMAX
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stpcpy' function. */
+#undef HAVE_STPCPY
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME /* use the missing_d/strfime.c version */
+
+/* Define to 1 if cpp supports the ANSI # stringizing operator. */
+#ifdef VAXC
+#undef HAVE_STRINGIZE
+#else
+#define HAVE_STRINGIZE 1
+#endif
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if you have the `strtod' function. */
+#define HAVE_STRTOD 1
+
+/* Define to 1 if you have the `strtoul' function. */
+#define HAVE_STRTOUL 1
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if `tm_zone' is member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
+ `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
+#undef HAVE_ST_BLKSIZE
+
+/* Define to 1 if you have the `system' function. */
+#define HAVE_SYSTEM 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+ `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the `towlower' function. */
+#undef HAVE_TOWLOWER
+
+/* Define to 1 if you have the `towupper' function. */
+#undef HAVE_TOWUPPER
+
+/* Define to 1 if you have the `tsearch' function. */
+#undef HAVE_TSEARCH
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+ `tzname'. */
+#define HAVE_TZNAME 1 /* (faked in vms/vms_misc.c) */
+
+/* Define to 1 if you have the `tzset' function. */
+#define HAVE_TZSET 1 /* (faked in vms/vms_misc.c) */
+
+/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
+#undef HAVE_UINTMAX_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#ifdef __DECC
+#define HAVE_UNISTD_H 1
+#else
+#undef HAVE_UNISTD_H
+#endif
+
+/* Define if you have the unsigned long long type. */
+#undef HAVE_UNSIGNED_LONG_LONG
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define if you have the 'wchar_t' type. */
+#undef HAVE_WCHAR_T
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#undef HAVE_WCRTOMB
+
+/* Define to 1 if you have the `wcscoll' function. */
+#undef HAVE_WCSCOLL
+
+/* Define to 1 if you have the `wcslen' function. */
+#undef HAVE_WCSLEN
+
+/* Define to 1 if you have the `wctype' function. */
+#undef HAVE_WCTYPE
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#undef HAVE_WCTYPE_H
+
+/* systems should define this type here */
+#undef HAVE_WCTYPE_T
+
+/* systems should define this type here */
+#undef HAVE_WINT_T
+
+/* Define to 1 if you have the `__argz_count' function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define to 1 if you have the `__argz_next' function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define to 1 if you have the `__argz_stringify' function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define to 1 if you have the `__fsetlocking' function. */
+#undef HAVE___FSETLOCKING
+
+/* Define as const if the declaration of iconv() needs const. */
+#undef ICONV_CONST
+
+/* Define if integer division by zero raises signal SIGFPE. */
+#define INTDIV0_RAISES_SIGFPE 1
+
+/* disable lint checks */
+#undef NO_LINT
+
+/* Name of package */
+#define PACKAGE "gawk"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bug-gawk@gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "GNU Awk"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "GNU Awk 3.1.4c"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "gawk"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.1.4c"
+
+/* Define to 1 if *printf supports %F format */
+#undef PRINTF_HAS_F_FORMAT
+
+/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
+#undef PRI_MACROS_BROKEN
+
+/* Define if compiler has function prototypes */
+#define PROTOTYPES 1
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of a `unsigned int', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_INT 4
+
+/* The size of a `unsigned long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG 4
+
+/* Define as the maximum value of type 'size_t', if the system doesn't define
+ it. */
+#define SIZE_MAX 0xffffffffUL
+
+/* return type of sprintf */
+#define SPRINTF_RET int
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#define STACK_DIRECTION (-1)
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* strtod doesn't have C89 semantics */
+#define STRTOD_NOT_C89 1
+
+/* some systems define this type here */
+#undef TIME_T_IN_SYS_TYPES_H
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* force use of our version of strftime */
+#define USE_INCLUDED_STRFTIME 1
+
+/* Version number of package */
+#define VERSION "3.1.4"
+
+/* Define to 1 if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#define __PROTOTYPES 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to widest signed type if <inttypes.h> doesn't define. */
+#define intmax_t long int
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define as the type of the result of subtracting two pointers, if the system
+ doesn't define it. */
+#undef ptrdiff_t
+
+/* Define to empty if the C compiler doesn't support this keyword. */
+#undef signed
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#define ssize_t int
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to unsigned long or unsigned long long if <stdint.h> and
+ <inttypes.h> don't define. */
+#define uintmax_t unsigned long
+
+#if 0
+#include <custom.h> /* overrides for stuff autoconf can't deal with */
+#else
+
+/* Whether `time_t' is an unsigned type. */
+#define TIME_T_UNSIGNED 1
+
+/*******************************/
+/* Gawk configuration options. */
+/*******************************/
+
+#define ALLOW_SWITCH 1
+
+/*
+ * DEFPATH
+ * VMS: "/AWK_LIBRARY" => "AWK_LIBRARY:"
+ * The default search path for the -f option of gawk. It is used
+ * if the AWKPATH environment variable is undefined.
+ *
+ * Note: OK even if no AWK_LIBRARY logical name has been defined.
+ */
+
+#define DEFPATH ".,/AWK_LIBRARY"
+#define ENVSEP ','
+
+/*
+ * Extended source file access.
+ */
+#define DEFAULT_FILETYPE ".awk"
+
+/*
+ * Pipe handling.
+ */
+#define PIPES_SIMULATED 1
+
+/*
+ * VAXCRTL is pre-ANSI and does some variations of numeric formatting
+ * differently than gawk expects.
+ */
+#if defined(VAX) && !defined(__DECC)
+/* '0' format modifier for %e,%f,%g gives wrong results in many cases */
+#define VAXCRTL
+/* %g format chooses %e format when should use %f */
+#define GFMT_WORKAROUND 1
+#endif
+
+/*
+ * VAX C
+ *
+ * As of V3.2, VAX C is not yet ANSI-compliant. But it's close enough
+ * for GAWK's purposes. Comment this out for VAX C V2.4 and earlier.
+ * YYDEBUG definition is needed for combination of VAX C V2.x and Bison.
+ */
+#if defined(VAXC) && !defined(__STDC__)
+#define __STDC__ 0
+#define NO_TOKEN_PASTING
+#define signed /*empty*/
+#define inline /*empty*/
+#ifndef __DECC /* DEC C does not support #pragma builtins even in VAXC mode */
+#define VAXC_BUILTINS
+#endif
+/* #define YYDEBUG 0 */
+#define NO_MBSUPPORT /* VAX C's preprocessor can't handle mbsupport.h */
+#define RE_TOKEN_INIT_BUG /* regcomp.c */
+#endif
+
+/*
+ * DEC C
+ *
+ * Digital's ANSI complier.
+ */
+#ifdef __DECC
+ /* DEC C implies DECC$SHR, which doesn't have the %g problem of VAXCRTL */
+#undef GFMT_WORKAROUND
+ /* DEC C V5.x introduces incompatibilities with prior porting efforts */
+#define _DECC_V4_SOURCE
+#define __SOCKET_TYPEDEFS
+#if __VMS_VER >= 60200000
+# undef __VMS_VER
+# define __VMS_VER 60100000
+#endif
+#if __CRTL_VER >= 60200000
+# if __CRTL_VER >= 70301000
+# define CRTL_VER_V731
+# endif
+# undef __CRTL_VER
+# define __CRTL_VER 60100000
+#endif
+#if __DECC_VER >= 60400000 && !defined(DEBUG)
+/* disable "new feature in C99" diagnostics (for regex code);
+ NEWC99 ought to suffice but doesn't (at least in V6.4) */
+#pragma message disable (NEWC99,DESIGNATORUSE)
+#endif
+#endif /* __DECC */
+
+/*
+ * GNU C
+ *
+ * Versions of GCC (actually GAS) earlier than 1.38 don't produce the
+ * right code for ``extern const'' constructs, and other usages of
+ * const might not be right either. The old set of include files from
+ * the gcc-vms distribution did not contain prototypes, and this could
+ * provoke some const-related compiler warnings. If you've got an old
+ * version of gcc for VMS, define 'const' out of existance, and by all
+ * means obtain the most recent version!
+ *
+ * Note: old versions of GCC should also avoid defining STDC_HEADERS,
+ * because most of the ANSI-C required header files are missing.
+ */
+#ifdef __GNUC__
+/* #define const */
+/* #undef STDC_HEADERS */
+#ifndef STDC_HEADERS
+#define alloca __builtin_alloca
+#define environ $$PsectAttributes_NOSHR$$environ /* awful GAS kludge */
+#endif
+#undef REGEX_MALLOC /* use true alloca() in regex.c */
+#endif
+
+#define IN_CONFIG_H
+#include "vms/redirect.h"
+#undef IN_CONFIG_H
+
+#endif /*<custom.h>*/
+
+#endif /*CONFIG_H*/
--- /dev/null
+/*
+ * vms.h - miscellaneous definitions for use with VMS system services.
+ * Pat Rankin, Nov'89
+ */
+
+#if 0
+#include <iodef.h>
+#else
+#define IO$_WRITEVBLK 48 /* write virtual block */
+#define IO$V_CANCTRLO 6 /* cancel <ctrl/O> (ie, resume tty output) */
+#define IO$M_CANCTRLO (1 << IO$V_CANCTRLO)
+#endif
+
+#if 0
+#include <clidef.h>
+#include <cliverbdef.h>
+#include <fscndef.h>
+#else
+#define CLI$K_GETCMD 1
+#define CLI$K_VERB_MCR 33
+#define CLI$K_VERB_RUN 36
+#define FSCN$_FILESPEC 1
+#endif
+
+#if 0
+#include <climsgdef.h>
+#else
+#define CLI$_RUNUSED 0x00030000 /* value returned by $CLI for "RUN" */
+#define CLI$_SYNTAX 0x000310FC /* error signalled by CLI$DCL_PARSE */
+#define CLI$_INSFPRM 0x00038048 /* insufficient parameters */
+#define CLI$_VALREQ 0x00038150 /* missing required value */
+#define CLI$_CONFLICT 0x00038258 /* conflicting qualifiers */
+#define CLI$_NOOPTPRS 0x00038840 /* no option present */
+#endif
+
+#if 0
+#include <psldef.h>
+#else
+#define PSL$C_USER 3 /* user mode */
+#endif
+
+/* note: `ulong' and `u_long' end up conflicting with various header files */
+typedef unsigned long U_Long;
+typedef unsigned short U_Short;
+
+typedef struct _dsc { int len; char *adr; } Dsc; /* limited string descriptor */
+ /* standard VMS itemlist-3 structure */
+typedef struct _itm { U_Short len, code; void *buffer; U_Short *retlen; } Itm;
+
+#define vmswork(sts) ((sts)&1)
+#define vmsfail(sts) (!vmswork(sts))
+#define CondVal(sts) ((sts)&0x0FFFFFF8) /* strip severity & msg inhibit */
+#define Descrip(strdsc,strbuf) Dsc strdsc = {sizeof strbuf - 1, (char *)strbuf}
+
+extern int shell$is_shell P((void));
+extern U_Long lib$find_file P((const Dsc *, Dsc *, void *, ...));
+extern U_Long lib$find_file_end P((void *));
+#ifndef NO_TTY_FWRITE
+extern U_Long lib$get_ef P((long *));
+extern U_Long sys$assign P((const Dsc *, short *, long, const Dsc *));
+extern U_Long sys$dassgn P((short));
+extern U_Long sys$qio P((U_Long, U_Long, U_Long, void *,
+ void (*)(U_Long), U_Long,
+ const char *, int, int, U_Long, int, int));
+extern U_Long sys$synch P((long, void *));
+#endif /*!NO_TTY_FWRITE*/
+extern U_Long lib$spawn P((const Dsc *,const Dsc *,const Dsc *,
+ const U_Long *,const Dsc *,U_Long *,U_Long *,...));
+ /* system services for logical name manipulation */
+extern U_Long sys$trnlnm P((const U_Long *,const Dsc *,const Dsc *,
+ const unsigned char *,Itm *));
+extern U_Long sys$crelnm P((const U_Long *,const Dsc *,const Dsc *,
+ const unsigned char *,const Itm *));
+extern U_Long sys$crelog P((int,const Dsc *,const Dsc *,unsigned char));
+extern U_Long sys$dellnm P((const Dsc *,const Dsc *,const unsigned char *));
+
+extern void v_add_arg P((int, const char *));
+extern void vms_exit P((int));
+extern char *vms_strerror P((int));
+extern char *vms_strdup P((const char *));
+extern int vms_devopen P((const char *,int));
+extern int vms_execute P((const char *, const char *, const char *));
+extern int vms_gawk P((void));
+extern U_Long Cli_Present P((const char *));
+extern U_Long Cli_Get_Value P((const char *, char *, int));
+extern U_Long Cli_Parse_Command P((const void *, const char *));
+
--- /dev/null
+/* vms_args.c -- command line parsing, to emulate shell i/o redirection.
+ [ Escape sequence parsing now suppressed. ]
+
+ Copyright (C) 1991-1996, 1997 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
+ * [.vms]vms_arg_fixup - emulate shell's command line processing: handle
+ * stdio redirection, backslash escape sequences, and file wildcard
+ * expansion. Should be called immediately upon image startup.
+ *
+ * Pat Rankin, Nov'89
+ * rankin@pactechdata.com
+ *
+ * <ifile - open 'ifile' (readonly) as 'stdin'
+ * >nfile - create 'nfile' as 'stdout' (stream-lf format)
+ * >>ofile - append to 'ofile' for 'stdout'; create it if necessary
+ * >&efile - point 'stderr' (SYS$ERROR) at 'efile', but don't open
+ * >$vfile - create 'vfile' as 'stdout', using rms attributes
+ * appropriate for a standard text file (variable length
+ * records with implied carriage control)
+ * >+vfile - create 'vfile' as 'stdout' in binary mode (using
+ * variable length records with implied carriage control)
+ * 2>&1 - special case: direct error messages into output file
+ * 1>&2 - special case: direct output data to error destination
+ * <<sentinal - error; reading stdin until 'sentinal' not supported
+ * <-, >- - error: stdin/stdout closure not implemented
+ * | anything - error; pipes not implemented
+ * & <end-of-line> - error; background execution not implemented
+ *
+ * any\Xany - convert 'X' as appropriate; \000 will not work as
+ * intended since subsequent processing will misinterpret
+ *
+ * any*any - perform wildcard directory lookup to find file(s)
+ * any%any - " " ('%' is vms wildcard for '?' [ie, /./])
+ * any?any - treat like 'any%any' unless no files match
+ * *, %, ? - if no file(s) match, leave original value in arg list
+ *
+ *
+ * Notes: a redirection operator can have optional white space between it
+ * and its filename; the operator itself *must* be preceded by white
+ * space so that it starts a separate argument. '<' is ambiguous
+ * since "<dir>file" is a valid VMS file specification; leading '<' is
+ * assumed to be stdin--use "\<dir>file" to override. '>$' is local
+ * kludge to force stdout to be created with text file RMS attributes
+ * instead of stream format; file sharing is disabled for stdout
+ * regardless. Multiple instances of stdin or stdout or stderr are
+ * treated as fatal errors rather than using the first or last. If a
+ * wildcard file specification is detected, it is expanded into a list
+ * of filenames which match; if there are no matches, the original
+ * file-spec is left in the argument list rather than having it expand
+ * into thin air. No attempt is made to identify and make $(var)
+ * environment substitutions--must draw the line somewhere!
+ *
+ * Oct'91, gawk 2.13.3
+ * Open '<' with full sharing allowed, so that we can read batch logs
+ * and other open files. Create record-format output ('>$') with read
+ * sharing permited, so that others can read our output file to check
+ * progess. For stream output ('>' or '>>'), sharing is disallowed
+ * (for performance reasons).
+ *
+ * Sep'94, gawk 2.15.6 [pr]
+ * Add '>+' to force binary mode output, to enable better control
+ * for the user when the output destination is a mailbox or socket.
+ * (ORS = "\r\n" for tcp/ip.) Contributed by Per Steinar Iversen.
+ */
+
+#include "awk.h" /* really "../awk.h" */
+#include "vms.h"
+#include <lnmdef.h>
+
+ void v_add_arg(int, const char *);
+static char *skipblanks(const char *);
+static void vms_expand_wildcards(const char *);
+static U_Long vms_define(const char *, const char *);
+static char *t_strstr(const char *, const char *);
+#define strstr t_strstr /* strstr() missing from vaxcrtl for V4.x */
+
+static int v_argc, v_argz = 0;
+static char **v_argv;
+
+/* vms_arg_fixup() - scan argv[] for i/o redirection and wildcards and also */
+/* rebuild it with those removed or expanded, respectively */
+void
+vms_arg_fixup( int *pargc, char ***pargv )
+{
+ const char *f_in, *f_out, *f_err,
+ *out_mode, *rms_rfm, *rms_shr, *rms_mrs;
+ char **argv = *pargv;
+ int i, argc = *pargc;
+ int err_to_out_redirect = 0, out_to_err_redirect = 0;
+
+#ifdef CHECK_DECSHELL /* don't define this if linking with DECC$SHR */
+ if (shell$is_shell())
+ return; /* don't do anything if we're running DEC/Shell */
+#endif
+#ifndef NO_DCL_CMD
+ for (i = 1; i < argc ; i++) /* check for dash or other non-VMS args */
+ if (strchr("->\\|", *argv[i])) break; /* found => (i < argc) */
+ if (i >= argc && (v_argc = vms_gawk()) > 0) { /* vms_gawk => dcl_parse */
+ /* if we successfully parsed the command, replace original argv[] */
+ argc = v_argc, argv = v_argv;
+ v_argz = v_argc = 0, v_argv = NULL;
+ }
+#endif
+ v_add_arg(v_argc = 0, argv[0]); /* store arg #0 (image name) */
+
+ f_in = f_out = f_err = NULL; /* stdio setup (no filenames yet) */
+ out_mode = "w"; /* default access for stdout */
+ rms_rfm = "rfm=stmlf"; /* stream_LF format */
+ rms_shr = "shr=nil"; /* no sharing (for '>' output file) */
+ rms_mrs = "mrs=0"; /* no maximum record size */
+
+ for (i = 1; i < argc; i++) {
+ char *p, *fn;
+ int is_arg;
+
+ is_arg = 0; /* current arg does not begin with dash */
+ p = argv[i]; /* current arg */
+ switch (*p) {
+ case '<': /* stdin */
+ /*[should try to determine whether this is really a directory
+ spec using <>; for now, force user to quote them with '\<']*/
+ if ( f_in ) {
+ fatal("multiple specification of '<' for stdin");
+ } else if (*++p == '<') { /* '<<' is not supported */
+ fatal("'<<' not available for stdin");
+ } else {
+ p = skipblanks(p);
+ fn = (*p ? p : argv[++i]); /* use next arg if necessary */
+ if (i >= argc || *fn == '-')
+ fatal("invalid i/o redirection, null filespec after '<'");
+ else
+ f_in = fn; /* save filename for stdin */
+ }
+ break;
+ case '>': { /* stdout or stderr */
+ /*[vms-specific kludge '>$' added to force stdout to be created
+ as record-oriented text file instead of in stream-lf format]*/
+ int is_out = 1; /* assume stdout */
+ if (*++p == '>') /* '>>' => append */
+ out_mode = "a", p++;
+ else if (*p == '&') /* '>&' => stderr */
+ is_out = 0, p++;
+ else if (*p == '$') /* '>$' => kludge for record format */
+ rms_rfm = "rfm=var", rms_shr = "shr=get,upi",
+ rms_mrs = "mrs=32767", p++;
+ else if (*p == '+') /* '>+' => kludge for binary output */
+ out_mode = "wb", rms_rfm = "rfm=var",
+ rms_mrs = "mrs=32767", p++;
+ else /* '>' => create */
+ {} /* use default values initialized prior to loop */
+ p = skipblanks(p);
+ fn = (*p ? p : argv[++i]); /* use next arg if necessary */
+ if (i >= argc || *fn == '-') {
+ fatal("invalid i/o redirection, null filespec after '>'");
+ } else if (is_out) {
+ if (out_to_err_redirect)
+ fatal("conflicting specifications for stdout");
+ else if (f_out)
+ fatal("multiple specification of '>' for stdout");
+ else
+ f_out = fn; /* save filename for stdout */
+ } else {
+ if (err_to_out_redirect)
+ fatal("conflicting specifications for stderr");
+ else if (f_err)
+ fatal("multiple specification of '>&' for stderr");
+ else
+ f_err = fn; /* save filename for stderr */
+ }
+ } break;
+ case '2': /* check for ``2>&1'' special case'' */
+ if (strcmp(p, "2>&1") != 0)
+ goto ordinary_arg;
+ else if (f_err || out_to_err_redirect)
+ fatal("conflicting specifications for stderr");
+ else {
+ err_to_out_redirect = 1;
+ f_err = "SYS$OUTPUT:";
+ } break;
+ case '1': /* check for ``1>&2'' special case'' */
+ if (strcmp(p, "1>&2") != 0)
+ goto ordinary_arg;
+ else if (f_out || err_to_out_redirect)
+ fatal("conflicting specifications for stdout");
+ else {
+ out_to_err_redirect = 1;
+ /* f_out = "SYS$ERROR:"; */
+ } break;
+ case '|': /* pipe */
+ /* command pipelines are not supported */
+ fatal("command pipes not available ('|' encountered)");
+ break;
+ case '&': /* background */
+ /*[we could probably spawn or fork ourself--maybe someday]*/
+ if (*(p+1) == '\0' && i == argc - 1) {
+ fatal("background tasks not available ('&' encountered)");
+ break;
+ } else { /* fall through */
+ ; /*NOBREAK*/
+ }
+ case '-': /* argument */
+ is_arg = 1; /*(=> skip wildcard check)*/
+ default: /* other (filespec assumed) */
+ordinary_arg:
+ /* process escape sequences or expand wildcards */
+ v_add_arg(++v_argc, p); /* include this arg */
+ p = strchr(p, '\\'); /* look for backslash */
+ if (p != NULL) { /* does it have escape sequence(s)? */
+#if 0 /* disable escape parsing; it's now done elsewhere within gawk */
+ register int c;
+ char *q = v_argv[v_argc] + (p - argv[i]);
+ do {
+ c = *p++;
+ if (c == '\\')
+ c = parse_escape(&p);
+ *q++ = (c >= 0 ? (char)c : '\\');
+ } while (*p != '\0');
+ *q = '\0';
+#endif /*0*/
+ } else if (!is_arg && strchr(v_argv[v_argc], '=') == NULL) {
+ vms_expand_wildcards(v_argv[v_argc]);
+ }
+ break;
+ } /* end switch */
+ } /* loop */
+
+ /*
+ * Now process any/all I/O options encountered above.
+ */
+
+ /* must do stderr first, or vaxcrtl init might not see it */
+ /*[ catch 22: we'll also redirect errors encountered doing <in or >out ]*/
+ if (f_err) { /* define logical name but don't open file */
+ int len = strlen(f_err);
+ if (len >= (sizeof "SYS$OUTPUT" - sizeof "")
+ && strncasecmp(f_err, "SYS$OUTPUT:", len) == 0)
+ err_to_out_redirect = 1;
+ else
+ (void) vms_define("SYS$ERROR", f_err);
+ }
+ /* do stdin before stdout, so if we bomb we won't make empty output file */
+ if (f_in) { /* [re]open file and define logical name */
+ if (freopen(f_in, "r", stdin,
+ "ctx=rec", "shr=get,put,del,upd",
+ "mrs=32767", "mbc=32", "mbf=2"))
+ (void) vms_define("SYS$INPUT", f_in);
+ else
+ fatal("<%s (%s)", f_in, strerror(errno));
+ }
+ if (f_out) {
+ if (freopen(f_out, out_mode, stdout,
+ rms_rfm, rms_shr, rms_mrs,
+ "rat=cr", "mbc=32", "mbf=2"))
+ (void) vms_define("SYS$OUTPUT", f_out);
+ else
+ fatal(">%s%s (%s)", (*out_mode == 'a' ? ">" : ""),
+ f_out, strerror(errno));
+ }
+ if (err_to_out_redirect) { /* special case for ``2>&1'' construct */
+ (void) dup2(1, 2); /* make file 2 (stderr) share file 1 (stdout) */
+ (void) vms_define("SYS$ERROR", "SYS$OUTPUT:");
+ } else if (out_to_err_redirect) { /* ``1>&2'' */
+ (void) dup2(2, 1); /* make file 1 (stdout) share file 2 (stderr) */
+ (void) vms_define("SYS$OUTPUT", "SYS$ERROR:");
+ }
+
+#ifndef NO_DCL_CMD
+ /* if we replaced argv[] with our own, we can release it now */
+ if (argv != *pargv)
+ free((void *)argv), argv = NULL;
+#endif
+ *pargc = ++v_argc; /* increment to account for argv[0] */
+ *pargv = v_argv;
+ return;
+}
+
+/* vms_expand_wildcards() - check a string for wildcard punctuation; */
+/* if it has any, attempt a directory lookup */
+/* and store resulting name(s) in argv array */
+static void
+vms_expand_wildcards( const char *prospective_filespec )
+{
+ char *p, spec_buf[255+1], res_buf[255+1];
+ Dsc spec, result;
+ void *context;
+ register int len = strlen(prospective_filespec);
+
+ if (len >= sizeof spec_buf)
+ return; /* can't be valid--or at least we can't handle it */
+ strcpy(spec_buf, prospective_filespec); /* copy the arg */
+ p = strchr(spec_buf, '?');
+ if (p != NULL) /* change '?' single-char wildcard to '%' */
+ do *p++ = '%', p = strchr(p, '?');
+ while (p != NULL);
+ else if (strchr(spec_buf, '*') == strchr(spec_buf, '%') /* => both NULL */
+ && strstr(spec_buf, "...") == NULL)
+ return; /* no wildcards present; don't attempt file lookup */
+ spec.len = len, spec.adr = spec_buf;
+ result.len = sizeof res_buf - 1, result.adr = res_buf;
+
+ /* The filespec is already in v_argv[v_argc]; if we fail to match anything,
+ we'll just leave it there (unlike most shells, where it would evaporate).
+ */
+ len = -1; /* overload 'len' with flag value */
+ context = NULL; /* init */
+ while (vmswork(lib$find_file(&spec, &result, &context))) {
+ for (len = sizeof(res_buf)-1; len > 0 && res_buf[len-1] == ' '; len--) ;
+ res_buf[len] = '\0'; /* terminate after discarding trailing blanks */
+ v_add_arg(v_argc++, strdup(res_buf)); /* store result */
+ }
+ (void)lib$find_file_end(&context);
+ if (len >= 0) /* (still -1 => never entered loop) */
+ --v_argc; /* undo final post-increment */
+ return;
+}
+
+/* v_add_arg() - store string pointer in v_argv[]; expand array if necessary */
+void
+v_add_arg( int idx, const char *val )
+{
+#ifdef DEBUG_VMS
+ fprintf(stderr, "v_add_arg: v_argv[%d] ", idx);
+#endif
+ if (idx + 1 >= v_argz) { /* 'v_argz' is the current size of v_argv[] */
+ int old_size = v_argz;
+
+ v_argz = idx + 10; /* increment by arbitrary amount */
+ if (old_size == 0)
+ v_argv = (char **)malloc((unsigned)(v_argz * sizeof(char **)));
+ else
+ v_argv = (char **)realloc((char *)v_argv,
+ (unsigned)(v_argz * sizeof(char **)));
+ if (v_argv == NULL) { /* error */
+ fatal("%s: %s: can't allocate memory (%s)", "vms_args",
+ "v_argv", strerror(errno));
+ } else {
+ while (old_size < v_argz) v_argv[old_size++] = NULL;
+ }
+ }
+ v_argv[idx] = (char *)val;
+#ifdef DEBUG_VMS
+ fprintf(stderr, "= \"%s\"\n", val);
+#endif
+}
+
+/* skipblanks() - return a pointer to the first non-blank in the string */
+static char *
+skipblanks( const char *ptr )
+{
+ if (ptr)
+ while (*ptr == ' ' || *ptr == '\t')
+ ptr++;
+ return (char *)ptr;
+}
+
+/* vms_define() - assign a value to a logical name [define/process/user_mode] */
+static U_Long
+vms_define( const char *log_name, const char *trans_val )
+{
+ Dsc log_dsc;
+ static Descrip(lnmtable,"LNM$PROCESS_TABLE");
+ static U_Long attr = LNM$M_CONFINE;
+ static Itm itemlist[] = { {0,LNM$_STRING,0,0}, {0,0} };
+ static unsigned char acmode = PSL$C_USER;
+ unsigned len = strlen(log_name);
+
+ /* avoid "define SYS$OUTPUT sys$output:" for redundant ">sys$output:" */
+ if (strncasecmp(log_name, trans_val, len) == 0
+ && (trans_val[len] == '\0' || trans_val[len] == ':'))
+ return 0;
+
+ log_dsc.adr = (char *)log_name;
+ log_dsc.len = len;
+ itemlist[0].buffer = (char *)trans_val;
+ itemlist[0].len = strlen(trans_val);
+ return sys$crelnm(&attr, &lnmtable, &log_dsc, &acmode, itemlist);
+}
+
+/* t_strstr -- strstr() substitute; search 'str' for 'sub' */
+/* [strstr() was not present in VAXCRTL prior to VMS V5.0] */
+static char *t_strstr ( const char *str, const char *sub )
+{
+ register const char *s0, *s1, *s2;
+
+ /* special case: empty substring */
+ if (!*sub) return (char *)str;
+
+ /* brute force method */
+ for (s0 = s1 = str; *s1; s1 = ++s0) {
+ s2 = sub;
+ while (*s1++ == *s2++)
+ if (!*s2) return (char *)s0; /* full match */
+ }
+ return (char *)0; /* not found */
+}
--- /dev/null
+/*
+ * vms_cli.c - command line interface routines.
+ * Pat Rankin, Nov'89
+ * Routines called from vms_gawk.c for DCL parsing.
+ */
+
+#define P(foo) ()
+#include "config.h" /* in case we want to suppress 'const' &c */
+#include "vms.h"
+#ifndef _STRING_H
+#include <string.h>
+#endif
+
+extern U_Long CLI$PRESENT(const Dsc *);
+extern U_Long CLI$GET_VALUE(const Dsc *, Dsc *, short *);
+extern U_Long CLI$DCL_PARSE(const Dsc *, const void *, ...);
+extern U_Long sys$cli(void *, ...);
+extern U_Long sys$filescan(const Dsc *, void *, long *);
+extern void *lib$establish(U_Long (*handler)(void *, void *));
+extern U_Long lib$sig_to_ret(void *, void *); /* condition handler */
+
+/* Cli_Present() - call CLI$PRESENT to determine whether a parameter or */
+/* qualifier is present on the [already parsed] command line */
+U_Long
+Cli_Present( const char *item )
+{
+ Dsc item_dsc;
+ (void)lib$establish(lib$sig_to_ret);
+
+ item_dsc.len = strlen(item_dsc.adr = (char *)item);
+ return CLI$PRESENT(&item_dsc);
+}
+
+/* Cli_Get_Value() - call CLI$GET_VALUE to retreive the value of a */
+/* parameter or qualifier from the command line */
+U_Long
+Cli_Get_Value( const char *item, char *result, int size )
+{
+ Dsc item_dsc, res_dsc;
+ U_Long sts;
+ short len = 0;
+ (void)lib$establish(lib$sig_to_ret);
+
+ item_dsc.len = strlen(item_dsc.adr = (char *)item);
+ res_dsc.len = size, res_dsc.adr = result;
+ sts = CLI$GET_VALUE(&item_dsc, &res_dsc, &len);
+ result[len] = '\0';
+ return sts;
+}
+
+/* Cli_Parse_Command() - use the $CLI system service (undocumented) to */
+/* retreive the actual command line (which might be */
+/* "run prog" or "mcr prog [params]") and then call */
+/* CLI$DCL_PARSE to parse it using specified tables */
+U_Long
+Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
+{
+ struct { short len, code; void *adr; } fscn[2];
+ struct { char rqtype, rqindx, rqflags, rqstat; unsigned :32;
+ Dsc rdesc; unsigned :32; unsigned :32; unsigned :32; } cmd;
+ U_Long sts;
+ int ltmp;
+ char longbuf[8200];
+ (void)lib$establish(lib$sig_to_ret);
+
+ memset(&cmd, 0, sizeof cmd);
+ cmd.rqtype = CLI$K_GETCMD; /* command line minus the verb */
+ sts = sys$cli(&cmd, (void *)0, (void *)0); /* get actual command line */
+
+ if (vmswork(sts)) { /* ok => cli available & verb wasn't "RUN" */
+ /* invoked via symbol => have command line (which might be empty) */
+ /* [might also be invoked via mcr or dcl; that's ok] */
+ if (cmd.rqstat == CLI$K_VERB_MCR) {
+ /* need to strip image name from MCR invocation */
+ memset(fscn, 0, sizeof fscn);
+ fscn[0].code = FSCN$_FILESPEC; /* full file specification */
+ (void)sys$filescan(&cmd.rdesc, fscn, (long *)0);
+ cmd.rdesc.len -= fscn[0].len; /* shrink size */
+ cmd.rdesc.adr += fscn[0].len; /* advance ptr */
+ }
+ /* prepend verb and then parse the command line */
+ strcat(strcpy(longbuf, cmd_verb), " "), ltmp = strlen(longbuf);
+ if (cmd.rdesc.len + ltmp > sizeof longbuf)
+ cmd.rdesc.len = sizeof longbuf - ltmp;
+ strncpy(&longbuf[ltmp], cmd.rdesc.adr, cmd.rdesc.len);
+ cmd.rdesc.len += ltmp, cmd.rdesc.adr = longbuf;
+ sts = CLI$DCL_PARSE( &cmd.rdesc, cmd_tables);
+ }
+
+ return sts;
+}
--- /dev/null
+/* vms_fwrite.c - augmentation for the fwrite() function.
+
+ Copyright (C) 1991-1996 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "awk.h" /* really "../awk.h" */
+
+#ifndef NO_TTY_FWRITE
+#include "vms.h"
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef VAXC_BUILTINS
+#pragma builtins /* VAXC V3.0 & up */
+# define find_c(s,n,c) ((n) - _LOCC((c),(n),(s)))
+#else /*VAXC_BUILTINS*/
+static int find_c( const char *s, int n, char c ) {
+ register const char *t = (const char *)memchr(s, c, n);
+ return (t == 0 ? n : t - s); /* 0..n-1, or n if not found */
+}
+#endif /*VAXC_BUILTINS*/
+#define is_stdout(file_no) ((file_no) == 1) /* fileno(stdout) */
+#define is_stderr(file_no) ((file_no) == 2) /* fileno(stderr) */
+
+#define PREFIX_CR 0x008D0000 /* leading carriage return */
+#define POSTFIX_CR 0x8D000000 /* trailing carriage return (=> lf/cr) */
+
+static short channel[_NFILE] = {0};
+static FILE *prev_file = 0;
+static int prev_file_num;
+
+ /*
+ * VAXCRTL's fwrite() seems to flush after every character when
+ * writing to a terminal. This routine is a limited functionality
+ * substitute that is *much* faster. However, calls to fwrite()
+ * should not be mixed with other stdio calls to the same file
+ * unless fflush() is always called first. Also, this routine
+ * will not detect that a freopen() call has finished with the
+ * original terminal; tty_fclose() should be used to close a file.
+ */
+#ifdef fwrite
+# undef fwrite
+#endif
+/* tty_fwrite() - performance hack for fwrite() to a terminal */
+size_t
+tty_fwrite( const void *buf, size_t size, size_t number, FILE *file )
+{
+ static long evfn = -1;
+ short chan;
+ int file_num, result;
+
+ if (!size || !number)
+ return 0;
+ else if (!file || !*file)
+ return 0 * (errno = EBADF); /* kludge alert! */
+ else if (file == prev_file)
+ file_num = prev_file_num;
+ else /* note: VAXCRTL's fileno() is a function, not just a macro */
+ prev_file_num = file_num = fileno(file), prev_file = file;
+
+ chan = file_num < _NFILE ? channel[file_num] : -1;
+ if (chan == 0) { /* if not initialized, need to assign a channel */
+ if (isatty(file_num) > 0) { /* isatty: 1=yes, 0=no, -1=problem */
+ Dsc device;
+ char devnam[255+1];
+ fgetname(file, devnam); /* get 'file's name */
+ device.len = strlen(device.adr = devnam); /* create descriptor */
+ if (vmswork(sys$assign(&device, &chan, 0, (Dsc *)0))) {
+ /* get an event flag; use #0 if problem */
+ if (evfn == -1 && vmsfail(lib$get_ef(&evfn))) evfn = 0;
+ } else chan = 0; /* $ASSIGN failed */
+ }
+ /* store channel for later use; -1 => don't repeat failed init attempt */
+ channel[file_num] = (chan > 0 ? chan : -1);
+ }
+ if (chan > 0) { /* chan > 0 iff 'file' is a terminal */
+ struct _iosbw { U_Short status, count; U_Long rt_kludge; } iosb;
+ register U_Long sts = 1;
+ register char *pt = (char *)buf;
+ register int offset, pos, count = size * number;
+ U_Long cc_fmt, io_func = IO$_WRITEVBLK;
+ int extra = 0;
+ result = 0;
+ if (is_stderr(file_num)) /* if it's SYS$ERROR (stderr)... */
+ io_func |= IO$M_CANCTRLO; /* cancel ^O (resume tty output) */
+ while (count > 0) {
+ /* special handling for line-feeds to make them be 'newlines' */
+ offset = 0;
+ if (*pt == '\n') { /* got at least one leading line-feed */
+ cc_fmt = PREFIX_CR, extra++; /* precede 1st LF with a CR */
+ do offset++;
+ while (offset < count && *(pt + offset) == '\n');
+ } else
+ cc_fmt = 0;
+ /* look for another line-feed; if found, break line there */
+ pos = offset + find_c(pt + offset, count - offset, '\n');
+ if (pos >= BUFSIZ) pos = BUFSIZ - 1; /* throttle quota usage */
+ else if (pos < count) pos++, cc_fmt |= POSTFIX_CR, extra++;
+ /* wait for previous write, if any, to complete */
+ if (pt > (char *)buf) {
+ sts = sys$synch(evfn, &iosb);
+ if (vmswork(sts)) sts = iosb.status, result += iosb.count;
+ if (vmsfail(sts)) break;
+ }
+ /* queue an asynchronous write */
+ sts = sys$qio(evfn, chan, io_func, &iosb, (void (*)(U_Long))0, 0L,
+ pt, pos, 0, cc_fmt, 0, 0);
+ if (vmsfail(sts)) break; /*(should never happen)*/
+ pt += pos, count -= pos;
+ }
+ /* wait for last write to complete */
+ if (pt > (char *)buf && vmswork(sts)) {
+ sts = sys$synch(evfn, &iosb);
+ if (vmswork(sts)) sts = iosb.status, result += iosb.count;
+ }
+ if (vmsfail(sts)) errno = EVMSERR, vaxc$errno = sts;
+ else if (iosb.rt_kludge == 0) result = number + extra;
+ result -= extra; /* subtract the additional carriage-returns */
+ } else { /* use stdio */
+ /* Note: we assume that we're writing text, not binary data.
+ For stream format files, 'size' and 'number' are effectively
+ interchangable, and fwrite works fine. However, for record
+ format files, 'size' governs the maximum record length, so
+ fwrite(string, size(char), strlen(string), file)
+ will produce a sequence of 1-byte records, which is hardly
+ what we want in this (assumed) situation. Line-feeds ('\n')
+ are converted into newlines (ie, record separators) by the
+ run-time library, but strings that don't end with a newline
+ still become separate records. The simplest work around
+ is just to use fputs() instead of fwrite(); unfortunately,
+ we have to provide special treatment for NULs ('\0's).
+ At present, only stdout might be in record format (via
+ >$'filename' redirection on the command line).
+ */
+ if (size > 1) { /* not used by GAWK */
+ result = fwrite((void *)buf, size, number, file);
+ } else if (*((char *)buf + number - 1) == '\n' || !is_stdout(file_num)) {
+ result = fwrite((void *)buf, number, size, file);
+ result = result * number / size; /*(same as 'result = number')*/
+ } else {
+#ifdef NO_ALLOCA
+# define alloca(n) ((n) <= abuf_siz ? abuf : \
+ ((abuf_siz > 0 ? (free(abuf),0) : 0), \
+ (abuf = malloc(abuf_siz = (n)+20))))
+ static void *abuf = 0;
+ static size_t abuf_siz = 0;
+#endif /*NO_ALLOCA*/
+ register char *pt = (char *)buf;
+ register int pos, count = number;
+ if (pt[count] != '\0') { /*(out of bounds, but relatively safe)*/
+ pt = (char *)alloca(count + 1);
+ memcpy(pt, buf, count), pt[count] = '\0';
+ /* if exiting this block undoes the alloca(), we're hosed :-( */
+ }
+ result = 0;
+ while (count > 0) {
+ pos = find_c(pt, count, '\0');
+ if (fputs(pt, file) < 0) break;
+ if (pos < count) {
+ if (fputc('\0', file) < 0) break;
+ pos++; /* 0..n-1 -> 1..n */
+ }
+ result += pos, pt += pos, count -= pos;
+ }
+ }
+ }
+ return result;
+}
+#define fwrite(b,s,n,f) tty_fwrite((b),(s),(n),(f))
+
+#ifdef fclose
+# undef fclose
+#endif
+/* tty_fclose() - keep tty_fwrite() up to date when closing a file */
+int
+tty_fclose( FILE *file )
+{
+ if (file && *file) { /* note: VAXCRTL stdio has extra level of indirection */
+ int file_num = fileno(file);
+ short chan = file_num < _NFILE ? channel[file_num] : -1;
+ if (chan > 0)
+ (void)sys$dassgn(chan); /* deassign the channel (ie, close) */
+ if (file_num < _NFILE)
+ channel[file_num] = 0; /* clear stale info */
+ }
+ prev_file = 0; /* force tty_fwrite() to reset */
+ return fclose(file);
+}
+#define fclose(f) tty_fclose(f)
+
+#endif /*!NO_TTY_FWRITE*/
--- /dev/null
+/* vms_gawk.c -- parse GAWK command line using DCL syntax
+
+ Copyright (C) 1991-1993, 1996, 2003, 2005 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+/*
+ * vms_gawk.c - routines to parse the command line as a native DCL command
+ * rather than as a foreign command string.
+ * Pat Rankin, Nov'89
+ * [ revised for 2.12, May'91 ]
+ */
+
+#include "awk.h"
+#include "vms.h"
+#define COMMAND_NAME "GAWK" /* verb name & for 'usage' message(s) */
+#define USAGE_PROG_RQRD 1
+#define USAGE_FILE_RQRD 2
+#define USAGE_BAD_COMBO 3
+#define USAGE_RUN_CMD 4
+#define STS$M_INHIB_MSG 0x10000000
+
+#define Present(arg) vmswork(Cli_Present(arg))
+#define Get_Value(arg,buf,siz) vmswork(Cli_Get_Value(arg,buf,siz))
+
+#ifndef __ia64__
+extern void gawk_cmd(); /* created with $ SET COMMAND/OBJECT */
+#define GAWK_CMD ((const void *)gawk_cmd)
+#else /* linker on Itanium is much pickier about such things */
+#pragma extern_model save
+#pragma extern_model strict_refdef
+/* (could use globalvalue rather than _refdef if we omit GAWK_CMD's `&') */
+extern void *gawk_cmd;
+#pragma extern_model restore
+#define GAWK_CMD ((const void *)&gawk_cmd)
+#endif
+extern void _exit(int);
+static int vms_usage(int);
+
+#define ARG_SIZ 250
+union arg_w_prefix { /* structure used to simplify prepending of "-" */
+ char value[2+ARG_SIZ+1];
+ struct {
+ char prefix[2]; /* for "-?" */
+ char buf[ARG_SIZ];
+ char suffix[1]; /* room for '\0' */
+ } arg;
+};
+
+#define chk_option(qualifier,optname) \
+ if (Present(qualifier)) \
+ strcat(strcat(buf.arg.buf, W_cnt++ ? "," : ""), optname)
+
+
+/* vms_gawk() - parse GAWK command line using DCL and convert it into the */
+/* appropriate "-arg" values for compatability with GNU code */
+int
+vms_gawk()
+{
+ U_Long sts;
+ union arg_w_prefix buf;
+ char misc_args[10], *misc_argp;
+ int argc, W_cnt;
+ int native_dcl = 1; /* assume true until we know otherwise */
+
+ /* check "GAWK_P1"--it's required; its presence will tip us off */
+ sts = Cli_Present("GAWK_P1");
+ if (CondVal(sts) == CondVal(CLI$_SYNTAX)) {
+ native_dcl = 0; /* not invoked via a native command verb */
+ /* syntax error indicates that we weren't invoked as a native DCL
+ command, so we'll now attempt to generate a command from the
+ foreign command string and parse that.
+ */
+ sts = Cli_Parse_Command(GAWK_CMD, COMMAND_NAME);
+ if (vmswork(sts))
+ sts = Cli_Present("GAWK_P1");
+ }
+ if (vmswork(sts)) /* command parsed successfully */
+ v_add_arg(argc = 0, COMMAND_NAME); /* save "GAWK" as argv[0] */
+ else if (CondVal(sts) == CondVal(CLI$_INSFPRM))
+ return native_dcl ? vms_usage(USAGE_FILE_RQRD) : 0; /* insufficient parameters */
+ else if (CondVal(sts) == CondVal(CLI$_CONFLICT))
+ return vms_usage(USAGE_BAD_COMBO); /* conflicting qualifiers (/input+/command) */
+#if 0 /* 3.1.2: removed since this can't distinguish RUN vs fork+exec */
+ else if (CondVal(sts) == CondVal(CLI$_RUNUSED))
+ return vms_usage(USAGE_RUN_CMD); /* RUN GAWK won't work (no command line) */
+#endif
+ else
+ return 0; /* forced to rely on original parsing */
+
+ if (Present("USAGE")) /* give usage message and quit */
+ return vms_usage(0);
+ else if (! (Present("PROGRAM") || Present("PROGFILE")) )
+ return native_dcl ? vms_usage(USAGE_PROG_RQRD) : 0; /* missing required option */
+
+ misc_argp = misc_args;
+ *misc_argp++ = '-'; /* now points at &misc_args[1] */
+#if 0 /* as of 2.12, -a and -e are obsolete */
+ if (Present("REG_EXPR")) {
+ if (Present("REG_EXPR.AWK")) /* /reg_exp=awk -> -a */
+ *misc_argp++ = 'a';
+ else if (Present("REG_EXPR.EGREP") /* /reg_exp=egrep -> -e */
+ || Present("REG_EXPR.POSIX")) /* /reg_exp=posix -> -e */
+ *misc_argp++ = 'e';
+ }
+#endif /* 0 */
+#if 0 /* gawk 2.11.1 */
+ if (Present("STRICT")) /* /strict -> -c */
+ *misc_argp++ = 'c';
+ if (Present("COPYRIGHT")) /* /copyright -> -C */
+ *misc_argp++ = 'C';
+ if (Present("VERSION")) /* /version -> -V */
+ *misc_argp++ = 'V';
+#else /* gawk 2.12 and later */
+ W_cnt = 0, buf.arg.buf[0] = '\0';
+ strncpy(buf.arg.prefix, "-W", 2);
+ chk_option("LINT","lint");
+ chk_option("POSIX","posix");
+ chk_option("STRICT","compat");
+ chk_option("COPYRIGHT","copyright");
+ chk_option("VERSION","version");
+ if (W_cnt > 0) /* got something */
+ v_add_arg(++argc, strdup(buf.value));
+#endif /*0*/
+#ifdef DEBUG
+ if (Present("DEBUG")) {
+#if 0
+ int both = Present("DEBUG.ALL");
+ if (both || Present("DEBUG.EXECUTION"))
+ *misc_argp++ = 'd';
+ if (both || Present("DEBUG.PARSE"))
+#endif
+ *misc_argp++ = 'D';
+ }
+#endif
+ *misc_argp = '\0'; /* terminate misc_args[] */
+ if (misc_argp > &misc_args[1]) /* got something */
+ v_add_arg(++argc, misc_args); /* store it/them */
+
+ if (Present("FIELD_SEP")) { /* field separator */
+ strncpy(buf.arg.prefix, "-F", 2);
+ if (Get_Value("FIELD_SEP", buf.arg.buf, sizeof buf.arg.buf))
+ v_add_arg(++argc, strdup(buf.value));
+ }
+ if (Present("VARIABLES")) { /* variables to init prior to BEGIN */
+ strncpy(buf.arg.prefix, "-v", 2);
+ while (Get_Value("VARIABLES", buf.arg.buf, sizeof buf.arg.buf))
+ v_add_arg(++argc, strdup(buf.value));
+ }
+ if (Present("PROGFILE")) { /* program files, /input=file -> -f file */
+ strncpy(buf.arg.prefix, "-f", 2);
+ while (Get_Value("PROGFILE", buf.arg.buf, sizeof buf.arg.buf))
+ v_add_arg(++argc, strdup(buf.value));
+ v_add_arg(++argc, "--");
+ } else if (Present("PROGRAM")) { /* program text, /program -> 'text' */
+ v_add_arg(++argc, "--");
+ if (Get_Value("PROGRAM", buf.value, sizeof buf.value))
+ v_add_arg(++argc, strdup(buf.value));
+ }
+
+ /* we know that "GAWK_P1" is present [data files and/or 'var=value'] */
+ while (Get_Value("GAWK_P1", buf.value, sizeof buf.value))
+ v_add_arg(++argc, strdup(buf.value));
+
+ if (Present("OUTPUT")) { /* let other parser treat this as 'stdout' */
+ strncpy(buf.arg.prefix, ">$", 2);
+ if (Get_Value("OUTPUT", buf.arg.buf, sizeof buf.arg.buf))
+ v_add_arg(++argc, strdup(buf.value));
+ }
+
+ return ++argc; /*(increment to account for arg[0])*/
+}
+
+/* vms_usage() - display one or more messages and then terminate */
+static int /* note: usually doesn't return */
+vms_usage( int complaint )
+{
+ static const char
+ *usage_txt = "\n\
+usage: %s /COMMANDS=\"awk program text\" data_file[,data_file,...] \n\
+ or %s /INPUT=awk_file data_file[,\"Var=value\",data_file,...] \n\
+ or %s /INPUT=(awk_file1,awk_file2,...) data_file[,...] \n\
+",
+ *options_txt = "\n\
+options: /FIELD_SEPARATOR=\"FS_value\" \n\
+ - /VARIABLES=(\"Var1=value1\",\"Var2=value2\",...) \n\
+ - /LINT /POSIX /[NO]STRICT /VERSION /COPYRIGHT /USAGE \n\
+ - /OUTPUT=out_file \n\
+",
+ *no_prog = "missing required element: /COMMANDS or /INPUT",
+ *no_file = "missing required element: data_file \n\
+ (use \"SYS$INPUT:\" to read data lines from the terminal)",
+ *bad_combo = "invalid combination of qualifiers \n\
+ (/INPUT=awk_file and /COMMANDS=\"awk program\" are mutually exclusive)",
+ *run_used = "\"RUN\" was used; required command components missing";
+ int status, argc;
+
+ fflush(stdout);
+ switch (complaint) {
+ case USAGE_PROG_RQRD:
+ fprintf(stderr, "\n%%%s-W-%s, %s \n", COMMAND_NAME, "PROG_RQRD", no_prog);
+ status = CLI$_VALREQ | STS$M_INHIB_MSG;
+ break;
+ case USAGE_FILE_RQRD:
+ if (Present("USAGE")) {
+ status = 1; /* clean exit */
+ } else if (Present("COPYRIGHT") || Present("VERSION")) {
+ v_add_arg(argc=0, COMMAND_NAME); /* save "GAWK" as argv[0] */
+#if 0
+ v_add_arg(++argc, Present("COPYRIGHT") ? "-C" : "-V");
+#else
+ v_add_arg(++argc, "-W");
+ v_add_arg(++argc, Present("COPYRIGHT") ? "copyright" : "version");
+#endif
+ v_add_arg(++argc, "{}"); /* kludge to suppress 'usage' */
+ v_add_arg(++argc, "NL:"); /* dummy input for kludge */
+ return ++argc; /* count argv[0] too */
+ } else {
+ fprintf(stderr, "\n%%%s-W-%s, %s \n", COMMAND_NAME, "FILE_RQRD", no_file);
+ status = CLI$_INSFPRM | STS$M_INHIB_MSG;
+ }
+ break;
+ case USAGE_BAD_COMBO:
+ fprintf(stderr, "\n%%%s-W-%s, %s \n", COMMAND_NAME, "BAD_COMBO", bad_combo);
+ status = CLI$_CONFLICT | STS$M_INHIB_MSG;
+ break;
+ case USAGE_RUN_CMD:
+ fprintf(stderr, "\n%%%s-W-%s, %s \n", COMMAND_NAME, "RUN_CMD", run_used);
+ status = CLI$_NOOPTPRS | STS$M_INHIB_MSG;
+ break;
+ default:
+ status = 1;
+ break;
+ }
+ fprintf(stderr, usage_txt, COMMAND_NAME, COMMAND_NAME, COMMAND_NAME);
+ fprintf(stderr, options_txt);
+ fflush(stderr);
+
+ errno = EVMSERR;
+ vaxc$errno = status;
+ _exit(status);
+ /* NOTREACHED */
+ return 0;
+}
--- /dev/null
+/* vms_misc.c -- sustitute code for missing/different run-time library routines.
+
+ Copyright (C) 1991-1993, 1996-1997, 2001, 2003 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define creat creat_dummy /* one of gcc-vms's headers has bad prototype */
+#include "awk.h"
+#include "vms.h"
+#undef creat
+#include <fab.h>
+#ifndef O_RDONLY
+#include <fcntl.h>
+#endif
+#include <rmsdef.h>
+#include <ssdef.h>
+#include <stsdef.h>
+
+ /*
+ * VMS uses a completely different status scheme (odd => success,
+ * even => failure), so we'll trap calls to exit() and alter the
+ * exit status code. [VAXC can't handle this as a macro.]
+ */
+#ifdef exit
+# undef exit
+#endif
+void
+vms_exit( int final_status )
+{
+ exit(final_status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG));
+}
+#define exit(v) vms_exit(v)
+
+ /*
+ * In VMS's VAXCRTL, strerror() takes an optional second argument.
+ * #define strerror(errnum) strerror(errnum,vaxc$errno)
+ * is all that's needed, but VAXC can't handle that (gcc can).
+ * [The 2nd arg is used iff errnum == EVMSERR.]
+ */
+#ifdef strerror
+# undef strerror
+#endif
+extern char *strerror P((int,...));
+
+/* vms_strerror() -- convert numeric error code into text string */
+char *
+vms_strerror( int errnum )
+{
+ return ( errnum != EVMSERR ? strerror(errnum)
+ : strerror(EVMSERR, vaxc$errno) );
+}
+# define strerror(v) vms_strerror(v)
+
+ /*
+ * Miscellaneous utility routine, not part of the run-time library.
+ */
+/* vms_strdup() - allocate some new memory and copy a string into it */
+char *
+vms_strdup( const char *str )
+{
+ char *result;
+ int len = strlen(str);
+
+ emalloc(result, char *, len+1, "strdup");
+ return strcpy(result, str);
+}
+
+ /*
+ * VAXCRTL does not contain unlink(). This replacement has limited
+ * functionality which is sufficient for GAWK's needs. It works as
+ * desired even when we have the file open.
+ */
+/* unlink(file) -- delete a file (ignore soft links) */
+int
+unlink( const char *file_spec ) {
+ char tmp[255+1]; /*(should use alloca(len+2+1)) */
+ extern int delete(const char *);
+
+ strcpy(tmp, file_spec); /* copy file name */
+ if (strchr(tmp, ';') == NULL)
+ strcat(tmp, ";0"); /* append version number */
+ return delete(tmp);
+}
+
+ /*
+ * Work-around an open(O_CREAT+O_TRUNC) bug (screwed up modification
+ * and creation dates when new version is created), and also use some
+ * VMS-specific file options. Note: optional 'prot' arg is completely
+ * ignored; gawk doesn't need it.
+ */
+#ifdef open
+# undef open
+#endif
+extern int creat P((const char *,int,...));
+extern int open P((const char *,int,unsigned,...));
+
+/* vms_open() - open a file, possibly creating it */
+int
+vms_open( const char *name, int mode, ... )
+{
+ int result;
+
+ if (STREQN(name, "/dev/", 5)) {
+ /* (this used to be handled in vms_devopen(), but that is only
+ called when opening files for output; we want it for input too) */
+ if (strcmp(name + 5, "null") == 0) /* /dev/null -> NL: */
+ name = "NL:";
+ else if (strcmp(name + 5, "tty") == 0) /* /dev/tty -> TT: */
+ name = "TT:";
+ }
+
+ if (mode == (O_WRONLY|O_CREAT|O_TRUNC)) {
+ /* explicitly force stream_lf record format to override DECC$SHR's
+ defaulting of RFM to earlier file version's when one is present */
+ result = creat(name, 0, "rfm=stmlf", "shr=nil", "mbc=32");
+ } else {
+ struct stat stb;
+ const char *mbc, *shr = "shr=get", *ctx = "ctx=stm";
+
+ if (stat((char *)name, &stb) < 0) { /* assume DECnet */
+ mbc = "mbc=8";
+ } else { /* ordinary file; allow full sharing iff record format */
+ mbc = "mbc=32";
+ if ((stb.st_fab_rfm & 0x0F) < FAB$C_STM) shr = "shr=get,put,upd";
+ }
+ result = open(name, mode, 0, shr, mbc, "mbf=2");
+ }
+
+ /* This is only approximate; the ACP -> RMS -> VAXCRTL interface
+ discards too much potentially useful status information... */
+ if (result < 0 && errno == EVMSERR
+ && (vaxc$errno == RMS$_ACC || vaxc$errno == RMS$_CRE))
+ errno = EMFILE; /* redirect() should close 1 file & try again */
+
+ return result;
+}
+
+ /*
+ * Check for attempt to (re-)open known file.
+ */
+/* vms_devopen() - check for "SYS$INPUT" or "SYS$OUTPUT" or "SYS$ERROR" */
+int
+vms_devopen( const char *name, int mode )
+{
+ FILE *file = NULL;
+
+ if (strncasecmp(name, "SYS$", 4) == 0) {
+ name += 4; /* skip "SYS$" */
+ if (strncasecmp(name, "INPUT", 5) == 0 && (mode & O_WRONLY) == 0)
+ file = stdin, name += 5;
+ else if (strncasecmp(name, "OUTPUT", 6) == 0 && (mode & O_WRONLY) != 0)
+ file = stdout, name += 6;
+ else if (strncasecmp(name, "ERROR", 5) == 0 && (mode & O_WRONLY) != 0)
+ file = stderr, name += 5;
+ if (*name == ':') name++; /* treat trailing colon as optional */
+ }
+ /* note: VAXCRTL stdio has extra level of indirection (*file) */
+ return (file && *file && *name == '\0') ? fileno(file) : -1;
+}
+
+
+#define VMS_UNITS_PER_SECOND 10000000L /* hundreds of nanoseconds, 1e-7 */
+#define UNIX_EPOCH "01-JAN-1970 00:00:00.00"
+
+extern U_Long sys$bintim(), sys$gettim();
+extern U_Long lib$subx(), lib$ediv();
+
+ /*
+ * Get current time in microsecond precision.
+ */
+/* vms_gettimeofday() - get current time in `struct timeval' format */
+int
+vms_gettimeofday(struct timeval *tv, void *timezone__not_used)
+{
+ /*
+ Emulate unix's gettimeofday call; timezone argument is ignored.
+ */
+ static const Dsc epoch_dsc = { sizeof UNIX_EPOCH - sizeof "", UNIX_EPOCH };
+ static long epoch[2] = {0L,0L}; /* needs one time initialization */
+ const long thunk = VMS_UNITS_PER_SECOND;
+ long now[2], quad[2];
+
+ if (!epoch[0]) sys$bintim(&epoch_dsc, epoch); /* 1 Jan 0:0:0 1970 */
+ /* get current time, as VMS quadword time */
+ sys$gettim(now);
+ /* convert the quadword time so that it's relative to Unix epoch */
+ lib$subx(now, epoch, quad); /* quad = now - epoch; */
+ /* convert 1e-7 units into seconds and fraction of seconds */
+ lib$ediv(&thunk, quad, &tv->tv_sec, &tv->tv_usec);
+ /* convert fraction of seconds into microseconds */
+ tv->tv_usec /= (VMS_UNITS_PER_SECOND / 1000000);
+
+ return 0; /* success */
+}
+
+
+#ifndef VMS_V7
+ /*
+ * VMS prior to V7.x has no timezone support unless DECnet/OSI is used.
+ */
+/* these are global for use by missing/strftime.c */
+char *tzname[2] = { "local", "" };
+int daylight = 0, timezone = 0, altzone = 0;
+
+/* tzset() -- dummy to satisfy linker */
+void tzset(void)
+{
+ return;
+}
+#endif /*VMS_V7*/
+
+
+#ifndef CRTL_VER_V731
+/* getpgrp() -- there's no such thing as process group under VMS;
+ * job tree might be close enough to be useful though.
+ */
+int getpgrp(void)
+{
+ return 0;
+}
+#endif
+
+#ifndef __GNUC__
+void vms_bcopy( const char *src, char *dst, int len )
+{
+ (void) memcpy(dst, src, len);
+}
+#endif /*!__GNUC__*/
+
+
+/*----------------------------------------------------------------------*/
+#ifdef NO_VMS_ARGS /* real code is in "vms/vms_args.c" */
+void vms_arg_fixup( int *argc, char ***argv ) { return; } /* dummy */
+#endif
+
+#ifdef NO_VMS_PIPES /* real code is in "vms/vms_popen.c" */
+FILE *popen( const char *command, const char *mode ) {
+ fatal(" Cannot open pipe `%s' (not implemented)", command);
+ return NULL;
+}
+int pclose( FILE *current ) {
+ fatal(" Cannot close pipe #%d (not implemented)", fileno(current));
+ return -1;
+}
+int fork( void ) {
+ fatal(" Cannot fork process (not implemented)");
+ return -1;
+}
+#endif /*NO_VMS_PIPES*/
+/*----------------------------------------------------------------------*/
+
+
+/*
+ * The following code is taken from the GNU C preprocessor (cccp.c,
+ * 2.8.1 vintage) where it was used #if VMS. It is only needed for
+ * VAX C and GNU C on VAX configurations; DEC C's run-time library
+ * doesn't have the problem described.
+ *
+ * VMS_fstat() and VMS_stat() were static in cccp.c but need to be
+ * accessible to the whole program here. Also, the special handling
+ * for the null device has been introduced for gawk's benefit, to
+ * prevent --lint mode from giving spurious warnings about /dev/null
+ * being empty if it's used as an input file.
+ */
+
+#if defined(VAXC) || (defined(__GNUC__) && !defined(__alpha))
+
+/* more VMS hackery */
+#include <fab.h>
+#include <nam.h>
+
+extern unsigned long sys$parse(), sys$search();
+
+/* Work around a VAXCRTL bug. If a file is located via a searchlist,
+ and if the device it's on is not the same device as the one specified
+ in the first element of that searchlist, then both stat() and fstat()
+ will fail to return info about it. `errno' will be set to EVMSERR, and
+ `vaxc$errno' will be set to SS$_NORMAL due yet another bug in stat()!
+ We can get around this by fully parsing the filename and then passing
+ that absolute name to stat().
+
+ Without this fix, we can end up failing to find header files, which is
+ bad enough, but then compounding the problem by reporting the reason for
+ failure as "normal successful completion." */
+
+#undef fstat /* Get back to the library version. */
+
+int
+VMS_fstat (fd, statbuf)
+ int fd;
+ struct stat *statbuf;
+{
+ int result = fstat (fd, statbuf);
+
+ if (result < 0)
+ {
+ FILE *fp;
+ char nambuf[NAM$C_MAXRSS+1];
+
+ if ((fp = fdopen (fd, "r")) != 0 && fgetname (fp, nambuf) != 0)
+ result = VMS_stat (nambuf, statbuf);
+ /* No fclose(fp) here; that would close(fd) as well. */
+ }
+
+ if (result == 0 /* GAWK addition; fixup /dev/null flags */
+ && (statbuf->st_mode & S_IFREG)
+ && STREQ(statbuf->st_dev, "_NLA0:"))
+ {
+ statbuf->st_mode &= ~S_IFREG;
+ statbuf->st_mode |= S_IFCHR;
+ }
+
+ return result;
+}
+
+int
+VMS_stat (name, statbuf)
+ const char *name;
+ struct stat *statbuf;
+{
+ int result = stat (name, statbuf);
+
+ if (result < 0)
+ {
+ struct FAB fab;
+ struct NAM nam;
+ char exp_nam[NAM$C_MAXRSS+1], /* expanded name buffer for sys$parse */
+ res_nam[NAM$C_MAXRSS+1]; /* resultant name buffer for sys$search */
+
+ fab = cc$rms_fab;
+ fab.fab$l_fna = (char *) name;
+ fab.fab$b_fns = (unsigned char) strlen (name);
+ fab.fab$l_nam = (void *) &nam;
+ nam = cc$rms_nam;
+ nam.nam$l_esa = exp_nam, nam.nam$b_ess = sizeof exp_nam - 1;
+ nam.nam$l_rsa = res_nam, nam.nam$b_rss = sizeof res_nam - 1;
+ nam.nam$b_nop = NAM$M_PWD | NAM$M_NOCONCEAL;
+ if (sys$parse (&fab) & 1)
+ {
+ if (sys$search (&fab) & 1)
+ {
+ res_nam[nam.nam$b_rsl] = '\0';
+ result = stat (res_nam, statbuf);
+ }
+ /* Clean up searchlist context cached by the system. */
+ nam.nam$b_nop = NAM$M_SYNCHK;
+ fab.fab$l_fna = 0, fab.fab$b_fns = 0;
+ (void) sys$parse (&fab);
+ }
+ }
+
+ if (result == 0 /* GAWK addition; fixup /dev/null flags */
+ && (statbuf->st_mode & S_IFREG)
+ && STREQ(statbuf->st_dev, "_NLA0:"))
+ {
+ statbuf->st_mode &= ~S_IFREG;
+ statbuf->st_mode |= S_IFCHR;
+ }
+
+ return result;
+}
+#endif /* VAXC || (__GNUC__ && !__alpha) */
--- /dev/null
+/* [.vms]vms_popen.c -- substitute routines for missing pipe calls.
+
+ Copyright (C) 1991-1993, 1996 the Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef NO_VMS_PIPES
+
+#include "awk.h" /* really "../awk.h" */
+#include <stdio.h>
+
+#ifndef PIPES_SIMULATED
+
+FILE *
+popen( const char *command, const char *mode )
+{
+ fatal(" Cannot open pipe `%s' (not implemented)", command);
+ /* NOT REACHED */
+ return 0;
+}
+
+int
+pclose( FILE *current )
+{
+ fatal(" Internal error ('pclose' not implemented)");
+ /* NOT REACHED */
+ return -1;
+}
+
+int
+fork( void )
+{
+ fatal(" Internal error ('fork' not implemented)");
+ /* NOT REACHED */
+ return -1;
+}
+
+#else /*PIPES_SIMULATED*/
+ /*
+ * Simulate pipes using temporary files; hope that the user
+ * doesn't expect pipe i/o to be interleaved with other i/o ;-}.
+ *
+ * This was initially based on the MSDOS version, but cannot
+ * use a static array to hold pipe info, because there's no
+ * fixed limit on the range of valid 'fileno's. Another
+ * difference is that redirection is handled using LIB$SPAWN
+ * rather than constructing a command for system() which uses
+ * '<' or '>'.
+ */
+#include "vms.h"
+#include <errno.h>
+#include <lnmdef.h> /* logical name definitions */
+
+#ifndef STDC_HEADERS
+extern int strcmp P((const char*, const char *));
+#endif
+extern char *mktemp P((char *));
+
+static void push_logicals P((void));
+static void pop_logicals P((void));
+static Itm *save_translation P((const Dsc *));
+static void restore_translation P((const Dsc *, const Itm *));
+
+typedef enum { unopened = 0, reading, writing } pipemode;
+typedef struct pipe_info {
+ char *command;
+ char *name;
+ pipemode pmode;
+} PIPE;
+static PIPE *pipes;
+static int pipes_lim = 0;
+
+#define psize(n) ((n) * sizeof(PIPE))
+#define expand_pipes(k) do { PIPE *new_p; \
+ int new_p_lim = ((k) / _NFILE + 1) * _NFILE; \
+ emalloc(new_p, PIPE *, psize(new_p_lim), "expand_pipes"); \
+ if (pipes_lim > 0) \
+ memcpy(new_p, pipes, psize(pipes_lim)), free(pipes); \
+ memset(new_p + psize(pipes_lim), 0, psize(new_p_lim - pipes_lim)); \
+ pipes = new_p, pipes_lim = new_p_lim; } while(0)
+
+FILE *
+popen( const char *command, const char *mode )
+{
+ FILE *current;
+ char *name;
+ int cur;
+ pipemode curmode;
+
+ if (strcmp(mode, "r") == 0)
+ curmode = reading;
+ else if (strcmp(mode, "w") == 0)
+ curmode = writing;
+ else
+ return NULL;
+
+ /* make a name for the temporary file */
+ if ((name = mktemp(strdup("sys$scratch:gawk-pipe_XXXXXX.tmp"))) == 0)
+ return NULL;
+
+ if (curmode == reading) {
+ /* an input pipe reads a temporary file created by the command */
+ vms_execute(command, (char *)0, name); /* 'command >tempfile' */
+ }
+ if ((current = fopen(name, mode, "mbc=24", "mbf=2")) == NULL) {
+ free(name);
+ return NULL;
+ }
+ cur = fileno(current);
+ if (cur >= pipes_lim) expand_pipes(cur);
+ /* assert( cur >= 0 && cur < pipes_lim ); */
+ pipes[cur].name = name;
+ pipes[cur].pmode = curmode;
+ pipes[cur].command = strdup(command);
+ return current;
+}
+
+int
+pclose( FILE *current )
+{
+ int rval, cur = fileno(current);
+
+ /* assert( cur >= 0 && cur < pipes_lim ); */
+ if (pipes[cur].pmode == unopened)
+ return -1; /* should never happen */
+
+ rval = fclose(current); /* close temp file; if reading, we're done */
+ if (pipes[cur].pmode == writing) {
+ /* an output pipe feeds the temporary file to the other program */
+ rval = vms_execute(pipes[cur].command, pipes[cur].name, (char *)0);
+ }
+ /* clean up */
+ unlink(pipes[cur].name); /* get rid of the temporary file */
+ pipes[cur].pmode = unopened;
+ free(pipes[cur].name), pipes[cur].name = 0;
+ free(pipes[cur].command), pipes[cur].command = 0;
+ return rval;
+}
+
+ /*
+ * Create a process and execute a command in it. This is essentially
+ * the same as system() but allows us to specify SYS$INPUT (stdin)
+ * and/or SYS$OUTPUT (stdout) for the process.
+ * [With more work it could truly simulate a pipe using mailboxes.]
+ */
+int
+vms_execute( const char *command, const char *input, const char *output )
+{
+ Dsc cmd, in, out, *in_p, *out_p;
+ U_Long sts, cmpltn_sts;
+
+ cmd.len = strlen(cmd.adr = (char *)command);
+ if (input)
+ in.len = strlen(in.adr = (char *)input), in_p = ∈
+ else
+ in_p = 0;
+ if (output)
+ out.len = strlen(out.adr = (char *)output), out_p = &out;
+ else
+ out_p = 0;
+
+ push_logicals(); /* guard against user-mode definitions of sys$Xput */
+ sts = lib$spawn(&cmd, in_p, out_p, (U_Long *)0,
+ (Dsc *)0, (U_Long *)0, &cmpltn_sts);
+ pop_logicals(); /* restore environment */
+
+ if (vmswork(sts) && vmsfail(cmpltn_sts)) sts = cmpltn_sts;
+ if (vmsfail(sts)) {
+ errno = EVMSERR, vaxc$errno = sts;
+ return -1;
+ } else
+ return 0;
+}
+
+/*----*
+ This rigmarole is to guard against interference from the current
+ environment. User-mode definitions of SYS$INPUT and/or SYS$OUTPUT
+ will interact with spawned subprocesses--including LIB$SPAWN with
+ explicit input and/or output arguments specified--if they were
+ defined without the 'CONFINED' attribute. The definitions created
+ in vms_args.c as part of command line I/O redirection happened to
+ fall into this category :-(, but even though that's been fixed,
+ there's still the possibility of the user doing something like
+ |$ define/user sys$output foo.out
+ prior to starting the program. Without ``/name_attr=confine'',
+ that will really screw up pipe simulation, so we've got to work-
+ around it here. This is true whether pipes are implemented via
+ mailboxes or temporary files, as long as lib$spawn() is being used.
+
+ push_logicals() calls save_translation() the first time it's
+ invoked; the latter allocates some memory to hold a full logical
+ name translation and uses $trnlnm to fill that in. Then if either
+ sys$input or sys$output has a user-mode, non-confined translation,
+ push_logicals() will delete the definition(s) using $dellnm.
+ After the spawned command has returned, pop_logicals() is called;
+ it calls restore_translation() for any deleted values; the latter
+ uses $crllnm or $crelog to recreate the original definition.
+
+ SYS$ERROR is currently ignored; perhaps it should receive the same
+ treatment...
+*----*/
+
+ /* logical name table, and names of interest; these are all constant */
+static const Descrip(lnmtable,"LNM$PROCESS_TABLE");
+static const Descrip(sys_input,"SYS$INPUT");
+static const Descrip(sys_output,"SYS$OUTPUT");
+static const unsigned char acmode = PSL$C_USER; /* only care about user-mode */
+
+ /* macros for simplfying the code a bunch */
+#define DelTrans(l) sys$dellnm(&lnmtable, (l), &acmode)
+#define GetTrans(l,i) sys$trnlnm((U_Long *)0, &lnmtable, (l), &acmode, (i))
+#define SetTrans(l,i) sys$crelnm((U_Long *)0, &lnmtable, (l), &acmode, (i))
+ /* itemlist manipulation macros; separate versions for aggregate and scalar */
+#define SetItmA(i,c,p,r) ((i).code = (c), (i).len = sizeof (p),\
+ (i).buffer = (p), (i).retlen = (U_Short *)(r))
+#define SetItmS(i,c,p) ((i).code = (c), (i).len = sizeof *(p),\
+ (i).buffer = (p), (i).retlen = (U_Short *)0)
+#define EndItm0(i) ((i).code = (i).len = 0)
+
+ /* translate things once, then hold the results here for multiple re-use */
+static Itm *input_definition, *output_definition;
+
+static void
+push_logicals( void ) /* deassign sys$input and/or sys$output */
+{
+ static int init_done = 0;
+
+ if (!init_done) { /* do logical name lookups one-time only */
+ input_definition = save_translation(&sys_input);
+ output_definition = save_translation(&sys_output);
+ init_done = 1;
+ }
+ if (input_definition) DelTrans(&sys_input); /* kill sys$input */
+ if (output_definition) DelTrans(&sys_output); /* and sys$output */
+}
+
+static void
+pop_logicals( void ) /* redefine sys$input and/or sys$output */
+{
+ if (input_definition) restore_translation(&sys_input, input_definition);
+ if (output_definition) restore_translation(&sys_output, output_definition);
+}
+
+static Itm *
+save_translation( const Dsc *logname )
+{
+ Itm trans[4], *itmlst;
+ long trans_attr, max_trans_indx; /* 0-based translation index count */
+ unsigned char trans_acmode; /* translation's access mode */
+ unsigned itmlst_size;
+ register int i, j;
+
+ itmlst = 0;
+ /* Want translation index count for non-confined, user-mode definition;
+ unfortunately, $trnlnm does not provide that much control. Try to
+ fetch several values of interest, then decide based on the result.
+ */
+ SetItmS(trans[0], LNM$_MAX_INDEX, &max_trans_indx), max_trans_indx = -1;
+ SetItmS(trans[1], LNM$_ACMODE, &trans_acmode), trans_acmode = 0;
+ SetItmS(trans[2], LNM$_ATTRIBUTES, &trans_attr), trans_attr = 0;
+ EndItm0(trans[3]);
+ if (vmswork(GetTrans(logname, trans)) && max_trans_indx >= 0
+ && trans_acmode == PSL$C_USER && !(trans_attr & LNM$M_CONFINE)) {
+ /* Now know that definition of interest exists;
+ allocate and initialize an item list and associated buffers;
+ use three entries for each translation.
+ */
+ itmlst_size = (3 * (max_trans_indx + 1) + 1) * sizeof(Itm);
+ emalloc(itmlst, Itm *, itmlst_size, "save_translation");
+ for (i = 0; i <= max_trans_indx; i++) {
+ struct def { U_Long indx, attr; U_Short len;
+ char str[LNM$C_NAMLENGTH], eos; } *wrk;
+ emalloc(wrk, struct def *, sizeof (struct def), "save_translation");
+ wrk->indx = (U_Long)i; /* this one's an input value for $trnlnm */
+ SetItmS(itmlst[3*i+0], LNM$_INDEX, &wrk->indx);
+ SetItmS(itmlst[3*i+1], LNM$_ATTRIBUTES, &wrk->attr), wrk->attr = 0;
+ SetItmA(itmlst[3*i+2], LNM$_STRING, &wrk->str, &wrk->len), wrk->len = 0;
+ }
+ EndItm0(itmlst[3*i]); /* assert( i == max_trans_indx+1 ); */
+ /* Time to perform full logical name translation,
+ then update item list for subsequent restoration.
+ If there are any holes [don't know whether that's possible]
+ collapse them out of the list; don't want them at restore time.
+ */
+ if (vmswork(GetTrans(logname, itmlst))) {
+ for (i = 0, j = -1; i <= max_trans_indx; i++) {
+ U_Long *attr_p;
+ attr_p = itmlst[3*i+1].buffer; /* copy (void *) to true type */
+ if (*attr_p & LNM$M_EXISTS) {
+ *attr_p &= ~LNM$M_EXISTS; /* must clear this bit */
+ if (++j < i) itmlst[3*j+0] = itmlst[3*i+0],
+ itmlst[3*j+1] = itmlst[3*i+1],
+ itmlst[3*j+2] = itmlst[3*i+2];
+ if (itmlst[3*j+2].retlen) { /* fixup buffer length */
+ itmlst[3*j+2].len = *itmlst[3*j+2].retlen;
+ itmlst[3*j+2].retlen = (U_Short *)0;
+ }
+ }
+ }
+ if (++j < i) EndItm0(itmlst[3*j]);
+ } else /* should never happen; tolerate potential memory leak */
+ free(itmlst), itmlst = 0; /*('wrk' buffer(s) will become lost)*/
+ }
+ return itmlst;
+}
+
+static void
+restore_translation( const Dsc *logname, const Itm *itemlist )
+{
+ Dsc trans_val;
+ U_Long *attr_p;
+# define LOG_PROCESS_TABLE 2 /* <obsolete> */
+# define LOG_USERMODE PSL$C_USER
+
+ /* assert( itemlist[1].code == LNM$_ATTRIBUTES ); */
+ attr_p = itemlist[1].buffer; /* copy (void *) to (U_Long *) */
+ if (*attr_p & LNM$M_CRELOG) { /* check original creation method */
+ /* $crelog values can have only one translation;
+ so it'll be the first string entry in the itemlist.
+ */
+ /* assert( itemlist[2].code == LNM$_STRING ); */
+ trans_val.adr = itemlist[2].buffer;
+ trans_val.len = itemlist[2].len;
+ (void) sys$crelog(LOG_PROCESS_TABLE, logname, &trans_val, LOG_USERMODE);
+ } else {
+ /* $crelnm definition; itemlist could specify multiple translations,
+ but has already been setup properly for use as-is.
+ */
+ (void) SetTrans(logname, itemlist);
+ }
+}
+
+#endif /*PIPES_SIMULATED*/
+
+#endif /*!NO_VMS_PIPES*/
--- /dev/null
+$! vmsbuild.com -- Commands to build GAWK Pat Rankin, Dec'89
+$! revised, Mar'90
+$! gawk 2.13 revised, Jun'91
+$! gawk 2.14 revised, Sep'92
+$! gawk 2.15 revised, Oct'93
+$! gawk 3.0 revised, Dec'95
+$! gawk 3.0.1 revised, Nov'96
+$! gawk 3.1.0 revised, Mar'01
+$! gawk 3.1.1 revised, Apr'02
+$!
+$ REL = "3.1" !release version number
+$ PATCHLVL = "5"
+$!
+$!
+$ CCFLAGS = "/noList" ! "/noOpt/Debug"
+$ CDEFS = "GAWK,HAVE_CONFIG_H"
+$!
+$ if p1.eqs."" then p1 = "DECC" !default compiler
+$ if p1.eqs."GNUC"
+$ then
+$! assumes VAX
+$ CC = "gcc"
+$ if f$type(gcc).eqs."STRING" then CC = gcc
+$ CFLAGS = "/Incl=([],[.vms])/Obj=[]/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library"
+$ if p2.eqs."DO_GNUC_SETUP" then set command gnu_cc:[000000]gcc
+$ else !!GNUC
+$ if p1.eqs."VAXC"
+$ then
+$! always VAX; version V3.x of VAX C assumed (for V2.x, remove /Opt=noInline)
+$ CC = "cc"
+$ if f$trnlnm("DECC$CC_DEFAULT").nes."" then CC = "cc/VAXC"
+$ CFLAGS = "/Incl=[]/Obj=[]/Opt=noInline/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "sys$share:vaxcrtl.exe/Shareable"
+$ else !!VAXC
+$! neither GNUC nor VAXC, assume DECC (same for either VAX or Alpha)
+$ CC = "cc/DECC/Prefix=All"
+$ CFLAGS = "/Incl=[]/Obj=[]/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "" ! DECC$SHR instead of VAXCRTL, no special link option needed
+$ endif !VAXC
+$ endif !GNUC
+$!
+$ cc = CC + CFLAGS
+$ show symbol cc
+$!
+$ if f$search("config.h").nes."" then -
+ if f$cvtime(f$file_attr("config.h","RDT")).ges.-
+ f$cvtime(f$file_attr("[.vms]vms-conf.h","RDT")) then goto config_ok
+$ v = f$verify(1)
+$ copy [.vms]vms-conf.h []config.h
+$! 'f$verify(v)'
+$config_ok:
+$ if f$search("awkgram.c").nes."" then goto awkgram_ok
+$ write sys$output " You must process `awkgram.y' with ""yacc"" or ""bison"""
+$ if f$search("awkgram_tab.c").nes."" then - !bison was run manually
+ write sys$output " or else rename `awkgram_tab.c' to `awkgramtab.c'."
+$ if f$search("ytab.c").nes."" .or. f$search("y_tab.c").nes."" then - !yacc
+ write sys$output " or else rename `ytab.c' or `y_tab.c' to `awkgramtab.c'."
+$ exit
+$awkgram_ok:
+$ v = f$verify(1)
+$ cc array.c
+$ cc awkgram.c
+$ cc builtin.c
+$ cc dfa.c
+$ cc ext.c
+$ cc field.c
+$ cc gawkmisc.c
+$ cc getopt.c
+$ cc getopt1.c
+$ cc io.c
+$ cc main.c
+$ cc msg.c
+$ cc node.c
+$ cc random.c
+$ cc re.c
+$ cc regex.c
+$ cc replace.c
+$ cc version.c
+$ cc eval.c
+$ cc profile.c
+$ cc [.vms]vms_misc.c
+$ cc [.vms]vms_popen.c
+$ cc [.vms]vms_fwrite.c
+$ cc [.vms]vms_args.c
+$ cc [.vms]vms_gawk.c
+$ cc [.vms]vms_cli.c
+$ set command/Object=[]gawk_cmd.obj [.vms]gawk.cld
+$! 'f$verify(v)'
+$!
+$ close/noLog Fopt
+$ create gawk.opt
+! GAWK -- GNU awk
+array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,field.obj,gawkmisc.obj
+getopt.obj,getopt1.obj,io.obj,main.obj,msg.obj,node.obj,random.obj
+re.obj,regex.obj,replace.obj,version.obj,eval.obj,profile.obj
+[]vms_misc.obj,vms_popen.obj,vms_fwrite.obj,vms_args.obj
+[]vms_gawk.obj,vms_cli.obj,gawk_cmd.obj
+psect_attr=environ,noshr !extern [noshare] char **
+stack=48 !preallocate more pages (default is 20)
+iosegment=128 !ditto (default is 32)
+$ open/append Fopt gawk.opt
+$ write Fopt libs
+$ write Fopt "identification=""V''REL'.''PATCHLVL'"""
+$ close Fopt
+$!
+$ v = f$verify(1)
+$ link/exe=gawk.exe gawk.opt/options
+$! 'f$verify(v)'
+$ exit
--- /dev/null
+$! vmstest.com -- DCL script to perform test/Makefile actions for VMS
+$!
+$! Usage:
+$! $ set default [-.test]
+$! $ @[-.vms]vmstest.com bigtest
+$! This assumes that newly built gawk.exe is in the next directory up.
+$!
+$ echo = "write sys$output"
+$ cmp = "diff/Output=_NL:/Maximum=1"
+$ rm = "delete/noConfirm/noLog"
+$ gawk = "$sys$disk:[-]gawk"
+$ AWKPATH_srcdir = "define/User AWKPATH sys$disk:[]"
+$
+$ if p1.eqs."" then p1 = "bigtest"
+$ gosub 'p1'
+$ if p2.nes."" then gosub 'p2'
+$ if p3.nes."" then gosub 'p3'
+$ if p4.nes."" then gosub 'p4'
+$ if p5.nes."" then gosub 'p5'
+$ if p6.nes."" then gosub 'p6'
+$ if p7.nes."" then gosub 'p7'
+$ if p8.nes."" then gosub 'p8'
+$ exit
+$
+$all:
+$bigtest: bigtest_list = "basic unix_tests gawk_ext vms_tests"
+$ echo "bigtest"
+$bigtest_loop: bigtest_test = f$element(0," ",bigtest_list)
+$ bigtest_list = bigtest_list - bigtest_test - " "
+$ if bigtest_test.nes." " then gosub 'bigtest_test'
+$ if bigtest_list.nes."" then goto bigtest_loop
+$ return
+$
+$basic: basic_lst1 = "msg swaplns messages argarray longwrds" -
+ + " getline2 fstabplus compare arrayref rs fsrs rand" -
+ + " fsbs negexp asgext anchgsub splitargv awkpath nfset" -
+ + " reparse convfmt arrayparm paramdup nonl defref" -
+ + " nofmtch litoct resplit rswhite prmarscl sclforin" -
+ + " sclifin intprec childin noeffect numsubstr pcntplus" -
+ + " prmreuse math fldchg fldchgnf reindops sprintfc" -
+ + " backgsub tweakfld clsflnam mmap8k fnarray dynlj" -
+ + " substr eofsplit prt1eval splitwht back89 tradanch"
+$ basic_lst2 = "nlfldsep splitvar intest nfldstr nors" -
+ + " fnarydel noparms funstack clobber delarprm prdupval" -
+ + " nasty nasty2 zeroflag getnr2tm getnr2tb printf1" -
+ + " funsmnam fnamedat numindex subslash opasnslf" -
+ + " opasnidx arynocls getlnbuf arysubnm fnparydl" -
+ + " nlstrina octsub nlinstr ofmt hsprint ofmts parseme" -
+ + " splitdef fnaryscl fnasgnm ofmtbig paramtyp rsnul1nl" -
+ + " datanonl regeq redfilnm strtod leaddig arynasty" -
+ + " psx96sub addcomma"
+$ basic_lst3 = "rebt8b1 rebt8b2 leadnl funsemnl ofmtfidl" -
+ + " onlynl arrymem1 compare2 minusstr membug1 forsimp" -
+ + " concat1 longsub arrayprm2 arrayprm3 arryref2" -
+ + " arryref3 arryref4 arryref5 aryprm1 aryprm2 aryprm3" -
+ + " aryprm4 aryprm5 aryprm6 aryprm7 aryprm8 concat2" -
+ + " concat3 delarpm2 delfunc exitval2 fmttest fnarray2" -
+ + " fnmisc fordel getline getline3 gsubasgn gsubtest" -
+ + " gsubtst2 gsubtst4 gsubtst5 hex inputred iobug1"
+$ basic_lst4 = "manglprm nested nfneg noloop1 noloop2" -
+ + " nulrsend prec prtoeval rstest1 rstest2 rstest3" -
+ + " rstest4 rstest5 scalar sortempty splitarr strcat1" -
+ + " subsepnm synerr1 uninit2 uninit3 uninit4" -
+ + " uninitialized unterm wjposer1 zeroe0"
+$ echo "basic"
+$basic_loop1: basic_test = f$element(0," ",basic_lst1)
+$ basic_lst1 = basic_lst1 - basic_test - " "
+$ if basic_test.nes." " then gosub 'basic_test'
+$ if basic_lst1.nes."" then goto basic_loop1
+$basic_loop2: basic_test = f$element(0," ",basic_lst2)
+$ basic_lst2 = basic_lst2 - basic_test - " "
+$ if basic_test.nes." " then gosub 'basic_test'
+$ if basic_lst2.nes."" then goto basic_loop2
+$basic_loop3: basic_test = f$element(0," ",basic_lst3)
+$ basic_lst3 = basic_lst3 - basic_test - " "
+$ if basic_test.nes." " then gosub 'basic_test'
+$ if basic_lst3.nes."" then goto basic_loop3
+$basic_loop4: basic_test = f$element(0," ",basic_lst4)
+$ basic_lst4 = basic_lst4 - basic_test - " "
+$ if basic_test.nes." " then gosub 'basic_test'
+$ if basic_lst4.nes."" then goto basic_loop4
+$ return
+$
+$unix_tests: unix_tst_list = "fflush getlnhd pid pipeio1" -
+ + " pipeio2 poundbang strftlng"
+$ echo "unix_tests"
+$unix_tst_loop: unix_tst_test = f$element(0," ",unix_tst_list)
+$ unix_tst_list = unix_tst_list - unix_tst_test - " "
+$ if unix_tst_test.nes." " then gosub 'unix_tst_test'
+$ if unix_tst_list.nes."" then goto unix_tst_loop
+$ return
+$
+$gawk_ext: gawk_ext_list = "argtest badargs clos1way fieldwdth" -
+ + " fsfwfs gensub gnuops2 gnureops igncdym igncfs" -
+ + " ignrcase lint manyfiles nondec posix procinfs" -
+ + " regx8bit reint shadow sort1 strftime"
+$ echo "gawk_ext (gawk.extensions)"
+$gawk_ext_loop: gawk_ext_test = f$element(0," ",gawk_ext_list)
+$ gawk_ext_list = gawk_ext_list - gawk_ext_test - " "
+$ if gawk_ext_test.nes." " then gosub 'gawk_ext_test'
+$ if gawk_ext_list.nes."" then goto gawk_ext_loop
+$ return
+$
+$vms_tests: vms_tst_list = "vms_io1"
+$ echo "vms_tests"
+$vms_tst_loop: vms_tst_test = f$element(0," ",vms_tst_list)
+$ vms_tst_list = vms_tst_list - vms_tst_test - " "
+$ if vms_tst_test.nes." " then gosub 'vms_tst_test'
+$ if vms_tst_list.nes."" then goto vms_tst_loop
+$ return
+$
+$extra: extra_list = "regtest inftest inet"
+$ echo "extra"
+$extra_loop: extra_test = f$element(0," ",extra_list)
+$ extra_list = extra_list - extra_test - " "
+$ if extra_test.nes." " then gosub 'extra_test'
+$ if extra_list.nes."" then goto extra_loop
+$ return
+$
+$inet: inet_list = "inetechu inetecht inetdayu inetdayt"
+$ echo "inet"
+$ type sys$input:
+ The inet tests only work if gawk has been built with tcp/ip socket
+ support and your system supports the services "discard" at port 9
+ and "daytimed" at port 13.
+$inet_loop: inet_test = f$element(0," ",inet_list)
+$ inet_list = inet_list - inet_test - " "
+$ if inet_test.nes." " then gosub 'inet_test'
+$ if inet_list.nes."" then goto inet_loop
+$ return
+$
+$poundbang:
+$ echo "poundbang: useless for VMS, so skipped"
+$ return
+$
+$msg:
+$ echo "Any output from ""DIFF"" is bad news, although some differences"
+$ echo "in floating point values are probably benign -- in particular,"
+$ echo "some systems may omit a leading zero and the floating point"
+$ echo "precision may lead to slightly different output in a few cases."
+$ return
+$
+$swaplns: echo "swaplns"
+$ gawk -f swaplns.awk swaplns.in >tmp.
+$ cmp swaplns.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$messages: echo "messages"
+$ set noOn
+$ gawk -f messages.awk > out2 >& out3
+$ cmp out1.ok out1.
+$ if $status then rm out1.;
+$ cmp out2.ok out2.
+$ if $status then rm out2.;
+$ cmp out3.ok out3.
+$ if $status then rm out3.;
+$ set On
+$ return
+$
+$argarray: echo "argarray"
+$ define/User TEST "test" !this is useless...
+$ gawk -f argarray.awk ./argarray.in - >tmp.
+just a test
+$ cmp argarray.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fstabplus: echo "fstabplus"
+$ gawk -f fstabplus.awk >tmp.
+1 2
+$ cmp fstabplus.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fsrs: echo "fsrs"
+$ gawk -f fsrs.awk fsrs.in >tmp.
+$ cmp fsrs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$igncfs: echo "igncfs"
+$ gawk -f igncfs.awk igncfs.in >tmp.
+$ cmp igncfs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$longwrds: echo "longwrds"
+$ gawk -v "SORT=sort sys$input: tmp." -f longwrds.awk longwrds.in >_NL:
+$ cmp longwrds.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fieldwdth: echo "fieldwdth"
+$ gawk -v "FIELDWIDTHS=2 3 4" "{ print $2}" >tmp.
+123456789
+$ cmp fieldwdth.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ignrcase: echo "ignrcase"
+$ gawk -v "IGNORECASE=1" "{ sub(/y/, """"); print}" >tmp.
+xYz
+$ cmp ignrcase.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$regtest:
+$ if f$search("regtest.com").eqs.""
+$ then echo "regtest: not available"
+$ else echo "regtest"
+$ echo "Some of the output from regtest is very system specific, do not"
+$ echo "be distressed if your output differs from that distributed."
+$ echo "Manual inspection is called for."
+$ @regtest.com
+$ endif
+$ return
+$
+$posix: echo "posix"
+$ gawk -f posix.awk >tmp.
+1:2,3 4
+$ cmp posix.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$manyfiles: echo "manyfiles"
+$ if f$search("[.junk]*.*").nes."" then rm [.junk]*.*;*
+$ if f$parse("[.junk]").eqs."" then create/Dir/Prot=(O:rwed) [.junk]
+$ gawk "BEGIN { for (i = 1; i <= 300; i++) print i, i}" >tmp.
+$ echo "This may take quite a while..."
+$ echo ""
+$ gawk -f manyfiles.awk tmp. tmp.
+$ define/User sys$error _NL:
+$ define/User sys$output tmp.too
+$ search/Match=Nor/Output=_NL:/Log [.junk]*.* ""
+$!/Log output: "%SEARCH-S-NOMATCH, <filename> - <#> records" plus 1 line summary
+$ gawk "$4!=2{++count}; END{if(NR!=301||count!=1){print ""Failed!""}}" tmp.too
+$ rm tmp.;,tmp.too;,[.junk]*.*;*,[]junk.dir;
+$ return
+$
+$compare: echo "compare"
+$ gawk -f compare.awk 0 1 compare.in >tmp.
+$ cmp compare.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayref: echo "arrayref"
+$ gawk -f arrayref.awk >tmp.
+$ cmp arrayref.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rs: echo "rs"
+$ gawk -v "RS=" "{ print $1, $2}" rs.in >tmp.
+$ cmp rs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fsbs: echo "fsbs"
+$ gawk -v "FS=\" "{ print $1, $2 }" fsbs.in >tmp.
+$ cmp fsbs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$inftest: echo "inftest"
+$ !! echo "This test is very machine specific..."
+$ set noOn
+$ gawk -f inftest.awk >tmp.
+$ !! cmp inftest.ok tmp. !just care that gawk doesn't crash...
+$ if $status then rm tmp.;
+$ set On
+$ return
+$
+$getline2: echo "getline2"
+$ gawk -f getline2.awk getline2.awk getline2.awk >tmp.
+$ cmp getline2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rand: echo "rand"
+$ echo "The following line should just be 19 random numbers between 1 and 100"
+$ echo ""
+$ gawk -f rand.awk
+$ return
+$
+$negexp: echo "negexp"
+$ gawk "BEGIN { a = -2; print 10^a }" >tmp.
+$ cmp negexp.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$asgext: echo "asgext"
+$ gawk -f asgext.awk asgext.in >tmp.
+$ cmp asgext.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$anchgsub: echo "anchgsub"
+$ gawk -f anchgsub.awk anchgsub.in >tmp.
+$ cmp anchgsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitargv: echo "splitargv"
+$ gawk -f splitargv.awk splitargv.in >tmp.
+$ cmp splitargv.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$awkpath: echo "awkpath"
+$ define/User AWK_LIBRARY [],[.lib]
+$ gawk -f awkpath.awk >tmp.
+$ cmp awkpath.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nfset: echo "nfset"
+$ gawk -f nfset.awk nfset.in >tmp.
+$ cmp nfset.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$reparse: echo "reparse"
+$ gawk -f reparse.awk reparse.in >tmp.
+$ cmp reparse.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$argtest: echo "argtest"
+$ gawk -f argtest.awk -x -y abc >tmp.
+$ cmp argtest.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$badargs: echo "badargs"
+$ on error then continue
+$ gawk -f 2>&1 >tmp.too
+$! search/Match=Nor tmp. "patchlevel" /Output=tmp.
+$ gawk "/patchlevel/{next}; {gsub(""\"""",""'""); print}" <tmp.too >tmp.
+$ cmp badargs.ok tmp.
+$ if $status then rm tmp.;,tmp.too;
+$ return
+$
+$convfmt: echo "convfmt"
+$ gawk -f convfmt.awk >tmp.
+$ cmp convfmt.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayparm: echo "arrayparm"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f arrayparm.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp arrayparm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$paramdup: echo "paramdup"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f paramdup.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp paramdup.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nonl: echo "nonl"
+$ ! This one might fail, depending on the tool used to unpack the
+$ ! distribution. Some will add a final newline if the file lacks one.
+$ AWKPATH_srcdir
+$ gawk --lint -f nonl.awk _NL: >tmp. 2>&1
+$ cmp nonl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$defref: echo "defref"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk --lint -f defref.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp defref.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nofmtch: echo "nofmtch"
+$ AWKPATH_srcdir
+$ gawk --lint -f nofmtch.awk >tmp. 2>&1
+$ cmp nofmtch.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$strftime: echo "strftime"
+$ ! this test could fail on slow machines or on a second boundary,
+$ ! so if it does, double check the actual results
+$!! date | gawk -v "OUTPUT"=tmp. -f strftime.awk
+$ now = f$time()
+$ wkd = f$extract(0,3,f$cvtime(now,,"WEEKDAY"))
+$ mon = f$cvtime(now,"ABSOLUTE","MONTH")
+$ mon = f$extract(0,1,mon) + f$edit(f$extract(1,2,mon),"LOWERCASE")
+$ day = f$cvtime(now,,"DAY")
+$ tim = f$extract(0,8,f$cvtime(now,,"TIME"))
+$ tz = ""
+$ yr = f$cvtime(now,,"YEAR")
+$ if f$trnlnm("FTMP").nes."" then close/noLog ftmp
+$ open/Write ftmp strftime.in
+$ write ftmp wkd," ",mon," ",day," ",tim," ",tz," ",yr
+$ close ftmp
+$ gawk -v "OUTPUT"=tmp. -f strftime.awk strftime.in
+$ set noOn
+$ cmp strftime.ok tmp.
+$ if $status then rm tmp.;,strftime.ok;*,strftime.in;*
+$ set On
+$ return
+$
+$litoct: echo "litoct"
+$ gawk --traditional -f litoct.awk >tmp.
+ab
+$ cmp litoct.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gensub: echo "gensub"
+$ gawk -f gensub.awk gensub.in >tmp.
+$ cmp gensub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$resplit: echo "resplit"
+$ gawk -- "{ FS = "":""; $0 = $0; print $2 }" >tmp.
+a:b:c d:e:f
+$ cmp resplit.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rswhite: echo "rswhite"
+$ gawk -f rswhite.awk rswhite.in >tmp.
+$ cmp rswhite.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prmarscl: echo "prmarscl"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f prmarscl.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp prmarscl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sclforin: echo "sclforin"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f sclforin.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp sclforin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sclifin: echo "sclifin"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f sclifin.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp sclifin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$intprec: echo "intprec"
+$ gawk -f intprec.awk >tmp. 2>&1
+$ cmp intprec.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$childin: echo "childin: currently fails for the VMS port, so skipped"
+$ return
+$! note: this `childin' test currently [gawk 3.0.3] fails for vms
+$!!childin: echo "childin"
+$ echo "note: type ``hi<return><ctrl/Z>'",-
+ "' if testing appears to hang in `childin'"
+$!! @echo hi | gawk "BEGIN { ""cat"" | getline; print; close(""cat"") }" >tmp.
+$ gawk "BEGIN { ""type sys$input:"" | getline; print; close(""type sys$input:"") }" >tmp.
+hi
+$ cmp childin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$noeffect: echo "noeffect"
+$ AWKPATH_srcdir
+$ gawk --lint -f noeffect.awk >tmp. 2>&1
+$ cmp noeffect.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$numsubstr: echo "numsubstr"
+$ AWKPATH_srcdir
+$ gawk -f numsubstr.awk numsubstr.in >tmp.
+$ cmp numsubstr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gnureops: echo "gnureops"
+$ gawk -f gnureops.awk >tmp.
+$ cmp gnureops.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$pcntplus: echo "pcntplus"
+$ gawk -f pcntplus.awk >tmp.
+$ cmp pcntplus.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prmreuse: echo "prmreuse"
+$ if f$search("prmreuse.ok").eqs."" then create prmreuse.ok
+$ gawk -f prmreuse.awk >tmp.
+$ cmp prmreuse.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$math: echo "math"
+$ gawk -f math.awk >tmp.
+$ cmp math.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fflush:
+$ echo "fflush: hopeless for VMS, so skipped"
+$ return
+$!!fflush: echo "fflush"
+$ ! hopelessly Unix-specific
+$!! @fflush.sh >tmp.
+$ cmp fflush.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fldchg: echo "fldchg"
+$ gawk -f fldchg.awk fldchg.in >tmp.
+$ cmp fldchg.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fldchgnf: echo "fldchgnf"
+$ gawk -f fldchgnf.awk fldchgnf.in >tmp.
+$ cmp fldchgnf.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$reindops: echo "reindops"
+$ gawk -f reindops.awk reindops.in >tmp.
+$ cmp reindops.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sprintfc: echo "sprintfc"
+$ gawk -f sprintfc.awk sprintfc.in >tmp.
+$ cmp sprintfc.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getlnhd:
+$ echo "getlnhd: uses Unix-specific command so won't work on VMS"
+$ return
+$!!getlnhd: echo "getlnhd"
+$ gawk -f getlnhd.awk >tmp.
+$ cmp getlnhd.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$backgsub: echo "backgsub"
+$ gawk -f backgsub.awk backgsub.in >tmp.
+$ cmp backgsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$tweakfld: echo "tweakfld"
+$ gawk -f tweakfld.awk tweakfld.in >tmp.
+$ if f$search("errors.cleanup").nes."" then rm errors.cleanup;*
+$ cmp tweakfld.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$clsflnam: echo "clsflnam"
+$ if f$search("clsflnam.ok").eqs."" then create clsflnam.ok
+$ gawk -f clsflnam.awk clsflnam.in >tmp. 2>&1
+$ cmp clsflnam.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$mmap8k: echo "mmap8k"
+$ gawk "{ print }" mmap8k.in >tmp.
+$ cmp mmap8k.in tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnarray: echo "fnarray"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f fnarray.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp fnarray.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$dynlj: echo "dynlj"
+$ gawk -f dynlj.awk >tmp.
+$ cmp dynlj.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$substr: echo "substr"
+$ gawk -f substr.awk >tmp.
+$ cmp substr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$eofsplit: echo "eofsplit"
+$ if f$search("eofsplit.ok").eqs."" then create eofsplit.ok
+$ gawk -f eofsplit.awk >tmp.
+$ cmp eofsplit.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prt1eval: echo "prt1eval"
+$ gawk -f prt1eval.awk >tmp.
+$ cmp prt1eval.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitwht: echo "splitwht"
+$ gawk -f splitwht.awk >tmp.
+$ cmp splitwht.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$back89: echo "back89"
+$ gawk "/a\8b/" back89.in >tmp.
+$ cmp back89.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$tradanch: echo "tradanch"
+$ if f$search("tradanch.ok").eqs."" then create tradanch.ok
+$ gawk --traditional -f tradanch.awk tradanch.in >tmp.
+$ cmp tradanch.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nlfldsep: echo "nlfldsep"
+$ gawk -f nlfldsep.awk nlfldsep.in >tmp.
+$ cmp nlfldsep.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitvar: echo "splitvar"
+$ gawk -f splitvar.awk splitvar.in >tmp.
+$ cmp splitvar.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$intest: echo "intest"
+$ gawk -f intest.awk >tmp.
+$ cmp intest.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$pid: echo "pid"
+$ if f$search("pid.ok").eqs."" then create pid.ok
+$ if f$trnlnm("FTMP").nes."" then close/noLog ftmp
+$ open/Write ftmp _pid.in
+$ write ftmp f$integer("%x" + f$getjpi("","PID"))
+$ write ftmp f$integer("%x" + f$getjpi("","OWNER"))
+$ close ftmp
+$ gawk -f pid.awk _pid.in >tmp. >& _NL:
+$ rm _pid.in;
+$ cmp pid.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$strftlng: echo "strftlng"
+$ define/User TZ "UTC" !useless
+$ gawk -f strftlng.awk >tmp.
+$ cmp strftlng.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nfldstr: echo "nfldstr"
+$ if f$search("nfldstr.ok").eqs."" then create nfldstr.ok
+$ gawk "$1 == 0 { print ""bug"" }" >tmp.
+
+$ cmp nfldstr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nors: echo "nors"
+$!! there's no straightforward way to supply non-terminated input on the fly
+$!! @echo A B C D E | tr -d '\12' | $(AWK) '{ print $$NF }' - $(srcdir)/nors.in > _$@
+$!! so just read a line from sys$input instead
+$ gawk "{ print $NF }" - nors.in >tmp.
+A B C D E
+$ cmp nors.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnarydel: echo "fnarydel"
+$ gawk -f fnarydel.awk >tmp.
+$ cmp fnarydel.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$reint: echo "reint"
+$ gawk --re-interval -f reint.awk reint.in >tmp.
+$ cmp reint.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$noparms: echo "noparms"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f noparms.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp noparms.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$pipeio1: echo "pipeio1"
+$ cat = "TYPE" !close enough, as long as we avoid .LIS default suffix
+$ define/User test1 []test1.
+$ define/User test2 []test2.
+$ gawk -f pipeio1.awk >tmp.
+$ rm test1.;,test2.;
+$ cmp pipeio1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$pipeio2:
+$ echo "pipeio2: uses Unix-specific command so won't work on VMS"
+$ return
+$!!pipeio2: echo "pipeio2"
+$ cat = "gawk -- {print}"
+$ tr = "??" !unfortunately, no trivial substitution available...
+$ gawk -v "SRCDIR=." -f pipeio2.awk >tmp.
+$ cmp pipeio2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$funstack: echo "funstack"
+$ gawk -f funstack.awk funstack.in >tmp.
+$ cmp funstack.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$clobber: echo "clobber"
+$ gawk -f clobber.awk >tmp.
+$ cmp clobber.ok seq.
+$ if $status then rm seq.;*
+$ cmp clobber.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$delarprm: echo "delarprm"
+$ gawk -f delarprm.awk >tmp.
+$ cmp delarprm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prdupval: echo "prdupval"
+$ gawk -f prdupval.awk prdupval.in >tmp.
+$ cmp prdupval.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nasty: echo "nasty"
+$ set noOn
+$ gawk -f nasty.awk >tmp.
+$ call fixup_LRL nasty.ok
+$ call fixup_LRL tmp. "purge"
+$ cmp nasty.ok tmp.
+$ if $status then rm tmp.;
+$ set On
+$ return
+$
+$nasty2: echo "nasty2"
+$ set noOn
+$ gawk -f nasty2.awk >tmp.
+$ call fixup_LRL nasty2.ok
+$ call fixup_LRL tmp. "purge"
+$ cmp nasty2.ok tmp.
+$ if $status then rm tmp.;
+$ set On
+$ return
+$
+$zeroflag: echo "zeroflag"
+$ gawk -f zeroflag.awk >tmp.
+$ cmp zeroflag.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getnr2tm: echo "getnr2tm"
+$ gawk -f getnr2tm.awk getnr2tm.in >tmp.
+$ cmp getnr2tm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getnr2tb: echo "getnr2tb"
+$ gawk -f getnr2tb.awk getnr2tb.in >tmp.
+$ cmp getnr2tb.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$printf1: echo "printf1"
+$ gawk -f printf1.awk >tmp.
+$ cmp printf1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$funsmnam: echo "funsmnam"
+$ set noOn
+$ gawk -f funsmnam.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp funsmnam.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnamedat: echo "fnamedat"
+$ set noOn
+$ gawk -f fnamedat.awk < fnamedat.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp fnamedat.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$numindex: echo "numindex"
+$ set noOn
+$ gawk -f numindex.awk < numindex.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp numindex.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$subslash: echo "subslash"
+$ set noOn
+$ gawk -f subslash.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp subslash.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$opasnslf: echo "opasnslf"
+$ set noOn
+$ gawk -f opasnslf.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp opasnslf.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$opasnidx: echo "opasnidx"
+$ set noOn
+$ gawk -f opasnidx.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp opasnidx.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arynocls: echo "arynocls"
+$ gawk -v "INPUT"=arynocls.in -f arynocls.awk >tmp.
+$ cmp arynocls.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$igncdym: echo "igncdym"
+$ gawk -f igncdym.awk igncdym.in >tmp.
+$ cmp igncdym.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getlnbuf: echo "getlnbuf"
+$ gawk -f getlnbuf.awk getlnbuf.in >tmp.
+$ gawk -f gtlnbufv.awk getlnbuf.in >tmp2.
+$ cmp getlnbuf.ok tmp.
+$ if $status then rm tmp.;
+$ cmp getlnbuf.ok tmp2.
+$ if $status then rm tmp2.;
+$ return
+$
+$arysubnm: echo "arysubnm"
+$ gawk -f arysubnm.awk >tmp.
+$ cmp arysubnm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnparydl: echo "fnparydl"
+$ gawk -f fnparydl.awk >tmp.
+$ cmp fnparydl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nondec: echo "nondec"
+$ gawk -f nondec.awk >tmp.
+$ cmp nondec.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nlstrina: echo "nlstrina"
+$ AWKPATH_srcdir
+$ gawk -f nlstrina.awk >tmp.
+$ cmp nlstrina.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$octsub: echo "octsub"
+$ AWKPATH_srcdir
+$ gawk -f octsub.awk >tmp.
+$ cmp octsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nlinstr: echo "nlinstr"
+$ gawk -f nlinstr.awk nlinstr.in >tmp.
+$ cmp nlinstr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ofmt: echo "ofmt"
+$ gawk -f ofmt.awk ofmt.in >tmp.
+$ cmp ofmt.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$hsprint: echo "hsprint"
+$ gawk -f hsprint.awk >tmp.
+$ cmp hsprint.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fsfwfs: echo "fsfwfs"
+$ gawk -f fsfwfs.awk fsfwfs.in >tmp.
+$ cmp fsfwfs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ofmts: echo "ofmts"
+$ gawk -f ofmts.awk ofmts.in >tmp.
+$ cmp ofmts.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$parseme: echo "parseme"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f parseme.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp parseme.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitdef: echo "splitdef"
+$ gawk -f splitdef.awk >tmp.
+$ cmp splitdef.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnaryscl: echo "fnaryscl"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f fnaryscl.awk >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp fnaryscl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnasgnm: echo "fnasgnm"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f fnasgnm.awk < fnasgnm.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp fnasgnm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$lint: echo "lint"
+$ AWKPATH_srcdir
+$ gawk -f lint.awk >tmp. 2>&1
+$ cmp lint.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$procinfs: echo "procinfs"
+$ gawk -f procinfs.awk >tmp.
+$ cmp procinfs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sort1: echo "sort1"
+$ gawk -f sort1.awk >tmp.
+$ cmp sort1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ofmtbig: echo "ofmtbig"
+$ set noOn
+$ gawk -f ofmtbig.awk ofmtbig.in >tmp. 2>&1
+$ set On
+$ cmp ofmtbig.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$inetechu: echo "inetechu"
+$ echo "this test is for establishing UDP connections"
+$ set noOn
+$ gawk -- "BEGIN {print """" |& ""/inet/udp/0/127.0.0.1/9""}"
+$ set On
+$ return
+$
+$inetecht: echo "inetecht"
+$ echo "this test is for establishing TCP connections"
+$ set noOn
+$ gawk -- "BEGIN {print """" |& ""/inet/tcp/0/127.0.0.1/9""}"
+$ set On
+$ return
+$
+$inetdayu: echo "inetdayu"
+$ echo "this test is for bidirectional UDP transmission"
+$ set noOn
+$ gawk -f - nl:
+BEGIN { print "" |& "/inet/udp/0/127.0.0.1/13";
+ "/inet/udp/0/127.0.0.1/13" |& getline; print $0}
+$ set On
+$ return
+$
+$inetdayt: echo "inetdayt"
+$ echo "this test is for bidirectional TCP transmission"
+$ set noOn
+$ gawk -f - nl:
+BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13";
+ "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}
+$ set On
+$ return
+$
+$paramtyp: echo "paramtyp"
+$ gawk -f paramtyp.awk >tmp.
+$ cmp paramtyp.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rsnul1nl: echo "rsnul1nl"
+$ gawk -f rsnul1nl.awk rsnul1nl.in >tmp.
+$ cmp rsnul1nl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$datanonl: echo "datanonl"
+$ gawk -f datanonl.awk datanonl.in >tmp.
+$ cmp datanonl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$regeq: echo "regeq"
+$ gawk -f regeq.awk regeq.in >tmp.
+$ cmp regeq.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$redfilnm: echo "redfilnm"
+$ gawk -f redfilnm.awk srcdir="." redfilnm.in >tmp.
+$ cmp redfilnm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$strtod: echo "strtod"
+$ gawk -f strtod.awk strtod.in >tmp.
+$ cmp strtod.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$leaddig: echo "leaddig"
+$ gawk -v "x=2E" -f leaddig.awk >tmp.
+$ cmp leaddig.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$clos1way:
+$ echo "clos1way: uses unsupported `|&' redirection, so skipped"
+$ return
+$!!clos1way: echo "clos1way"
+$ gawk -f clos1way.awk >tmp.
+$ cmp clos1way.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arynasty: echo "arynasty"
+$ gawk -f arynasty.awk >tmp.
+$ cmp arynasty.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$shadow: echo "shadow"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk --lint -f shadow.awk >tmp. 2>&1
+$ set On
+$ cmp shadow.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$regx8bit: echo "regx8bit"
+$ gawk -f regx8bit.awk >tmp.
+$ cmp regx8bit.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$psx96sub: echo "psx96sub"
+$ gawk -f psx96sub.awk >tmp.
+$ cmp psx96sub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$addcomma: echo "addcomma"
+$ gawk -f addcomma.awk addcomma.in >tmp.
+$ cmp addcomma.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gnuops2: echo "gnuops2"
+$ gawk -f gnuops2.awk >tmp.
+$ cmp gnuops2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rebt8b1: echo "rebt8b1"
+$ gawk -f rebt8b1.awk >tmp.
+$ cmp rebt8b1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rebt8b2: echo "rebt8b2"
+$ gawk -f rebt8b2.awk >tmp.
+$ cmp rebt8b2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$leadnl: echo "leadnl"
+$ gawk -f leadnl.awk leadnl.in >tmp.
+$ cmp leadnl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$funsemnl: echo "funsemnl"
+$ gawk -f funsemnl.awk >tmp.
+$ cmp funsemnl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ofmtfidl: echo "ofmtfidl"
+$ gawk -f ofmtfidl.awk ofmtfidl.in >tmp.
+$ cmp ofmtfidl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$onlynl: echo "onlynl"
+$ gawk -f onlynl.awk onlynl.in >tmp.
+$ cmp onlynl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrymem1: echo "arrymem1"
+$ gawk -f arrymem1.awk >tmp.
+$ cmp arrymem1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$compare2: echo "compare2"
+$ gawk -f compare2.awk >tmp.
+$ cmp compare2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$minusstr: echo "minusstr"
+$ gawk -f minusstr.awk >tmp.
+$ cmp minusstr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$membug1: echo "membug1"
+$ gawk -f membug1.awk membug1.in >tmp.
+$ cmp membug1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$forsimp: echo "forsimp"
+$ gawk -f forsimp.awk >tmp.
+$ cmp forsimp.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$concat1: echo "concat1"
+$ gawk -f concat1.awk concat1.in >tmp.
+$ cmp concat1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$longsub: echo "longsub"
+$ gawk -f longsub.awk longsub.in >tmp.
+$!! the records here are too long for DIFF to handle
+$!! so assume success as long as gawk doesn't crash
+$!! call fixup_LRL longsub.ok
+$!! call fixup_LRL tmp. "purge"
+$!! cmp longsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayprm2: echo "arrayprm2"
+$ gawk -f arrayprm2.awk arrayprm2.in >tmp.
+$ cmp arrayprm2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayprm3: echo "arrayprm3"
+$ gawk -f arrayprm3.awk arrayprm3.in >tmp.
+$ cmp arrayprm3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arryref2: echo "arryref2"
+$ gawk -f arryref2.awk arryref2.in >tmp.
+$ cmp arryref2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arryref3: echo "arryref3"
+$ set noOn
+$ gawk -f arryref3.awk arryref3.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp arryref3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arryref4: echo "arryref4"
+$ set noOn
+$ gawk -f arryref4.awk arryref4.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp arryref4.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arryref5: echo "arryref5"
+$ set noOn
+$ gawk -f arryref5.awk arryref5.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp arryref5.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm1: echo "aryprm1"
+$ set noOn
+$ gawk -f aryprm1.awk aryprm1.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm2: echo "aryprm2"
+$ set noOn
+$ gawk -f aryprm2.awk aryprm2.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm3: echo "aryprm3"
+$ set noOn
+$ gawk -f aryprm3.awk aryprm3.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm4: echo "aryprm4"
+$ set noOn
+$ gawk -f aryprm4.awk aryprm4.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm4.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm5: echo "aryprm5"
+$ set noOn
+$ gawk -f aryprm5.awk aryprm5.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm5.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm6: echo "aryprm6"
+$ set noOn
+$ gawk -f aryprm6.awk aryprm6.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm6.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm7: echo "aryprm7"
+$ set noOn
+$ gawk -f aryprm7.awk aryprm7.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp aryprm7.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$aryprm8: echo "aryprm8"
+$ gawk -f aryprm8.awk aryprm8.in >tmp.
+$ cmp aryprm8.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$concat2: echo "concat2"
+$ gawk -f concat2.awk concat2.in >tmp.
+$ cmp concat2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$concat3: echo "concat3"
+$ gawk -f concat3.awk concat3.in >tmp.
+$ cmp concat3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$delarpm2: echo "delarpm2"
+$ gawk -f delarpm2.awk delarpm2.in >tmp.
+$ cmp delarpm2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$delfunc: echo "delfunc"
+$ set noOn
+$ gawk -f delfunc.awk delfunc.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp delfunc.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$exitval2: echo "exitval2 skipped"
+$ return
+$!!exitval2: echo "exitval2"
+$ gawk -f exitval2.awk exitval2.in >tmp.
+$ cmp exitval2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fmttest: echo "fmttest"
+$ gawk -f fmttest.awk fmttest.in >tmp.
+$ cmp fmttest.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnarray2: echo "fnarray2"
+$ set noOn
+$ gawk -f fnarray2.awk fnarray2.in >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp fnarray2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnmisc: echo "fnmisc"
+$ set noOn
+$ gawk -f fnmisc.awk fnmisc.in >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp fnmisc.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fordel: echo "fordel"
+$ gawk -f fordel.awk fordel.in >tmp.
+$ cmp fordel.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getline: echo "getline skipped"
+$ return
+$!!getline: echo "getline"
+$ gawk -f getline.awk getline.in >tmp.
+$ cmp getline.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getline3: echo "getline3"
+$ gawk -f getline3.awk getline3.in >tmp.
+$ cmp getline3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubasgn: echo "gsubasgn"
+$ set noOn
+$ gawk -f gsubasgn.awk gsubasgn.in >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp gsubasgn.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubtest: echo "gsubtest"
+$ gawk -f gsubtest.awk gsubtest.in >tmp.
+$ cmp gsubtest.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubtst2: echo "gsubtst2"
+$ gawk -f gsubtst2.awk gsubtst2.in >tmp.
+$ cmp gsubtst2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubtst3: echo "gsubtst3"
+$ gawk --re-interval -f gsubtst3.awk gsubtst3.in >tmp.
+$ cmp gsubtst3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubtst4: echo "gsubtst4"
+$ gawk -f gsubtst4.awk gsubtst4.in >tmp.
+$ cmp gsubtst4.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gsubtst5: echo "gsubtst5"
+$ gawk -f gsubtst5.awk gsubtst5.in >tmp.
+$ cmp gsubtst5.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$hex: echo "hex"
+$ gawk -f hex.awk hex.in >tmp.
+$ cmp hex.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$inputred: echo "inputred"
+$ gawk -f inputred.awk inputred.in >tmp.
+$ cmp inputred.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$iobug1: echo "iobug1"
+$ cat = "TYPE sys$input:"
+$ true = "exit 1" !success
+$ gawk -f iobug1.awk iobug1.in >tmp.
+$ cmp iobug1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$manglprm: echo "manglprm"
+$ gawk -f manglprm.awk manglprm.in >tmp.
+$ cmp manglprm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nested: echo "nested"
+$ gawk -f nested.awk nested.in >tmp.
+$ cmp nested.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nfneg: echo "nfneg"
+$ set noOn
+$ gawk -f nfneg.awk nfneg.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp nfneg.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$noloop1: echo "noloop1"
+$ gawk -f noloop1.awk noloop1.in >tmp.
+$ cmp noloop1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$noloop2: echo "noloop2"
+$ gawk -f noloop2.awk noloop2.in >tmp.
+$ cmp noloop2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nulrsend: echo "nulrsend"
+$ gawk -f nulrsend.awk nulrsend.in >tmp.
+$ cmp nulrsend.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prec: echo "prec"
+$ gawk -f prec.awk prec.in >tmp.
+$ cmp prec.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prtoeval: echo "prtoeval"
+$ gawk -f prtoeval.awk prtoeval.in >tmp.
+$ cmp prtoeval.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rstest1: echo "rstest1"
+$ gawk -f rstest1.awk rstest1.in >tmp.
+$ cmp rstest1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rstest2: echo "rstest2"
+$ gawk -f rstest2.awk rstest2.in >tmp.
+$ cmp rstest2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rstest3: echo "rstest3"
+$ gawk -f rstest3.awk rstest3.in >tmp.
+$ cmp rstest3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rstest4: echo "rstest4 skipped"
+$ return
+$!!rstest4: echo "rstest4"
+$ gawk -f rstest4.awk rstest4.in >tmp.
+$ cmp rstest4.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rstest5: echo "rstest5 skipped"
+$ return
+$!!rstest5: echo "rstest5"
+$ gawk -f rstest5.awk rstest5.in >tmp.
+$ cmp rstest5.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$scalar: echo "scalar"
+$ set noOn
+$ gawk -f scalar.awk scalar.in >tmp. 2>&1
+$ if .not.$status then call exit_code 2
+$ set On
+$ cmp scalar.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sortempty: echo "sortempty"
+$ gawk -f sortempty.awk sortempty.in >tmp.
+$ cmp sortempty.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitarr: echo "splitarr"
+$ gawk -f splitarr.awk splitarr.in >tmp.
+$ cmp splitarr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$strcat1: echo "strcat1"
+$ gawk -f strcat1.awk strcat1.in >tmp.
+$ cmp strcat1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$subsepnm: echo "subsepnm"
+$ gawk -f subsepnm.awk subsepnm.in >tmp.
+$ cmp subsepnm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$synerr1: echo "synerr1"
+$ set noOn
+$ gawk -f synerr1.awk synerr1.in >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp synerr1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$uninitialized: echo "uninitialized"
+$ gawk --lint -f uninitialized.awk uninitialized.in >tmp. 2>&1
+$ cmp uninitialized.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$uninit2: echo "uninit2"
+$ gawk --lint -f uninit2.awk uninit2.in >tmp. 2>&1
+$ cmp uninit2.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$uninit3: echo "uninit3"
+$ gawk --lint -f uninit3.awk uninit3.in >tmp. 2>&1
+$ cmp uninit3.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$uninit4: echo "uninit4"
+$ gawk --lint -f uninit4.awk uninit4.in >tmp. 2>&1
+$ cmp uninit4.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$unterm: echo "unterm"
+$ set noOn
+$ gawk -f unterm.awk unterm.in >tmp. 2>&1
+$ if .not.$status then call exit_code 1
+$ set On
+$ cmp unterm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$wjposer1: echo "wjposer1"
+$ gawk -f wjposer1.awk wjposer1.in >tmp.
+$ cmp wjposer1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$zeroe0: echo "zeroe0"
+$ gawk -f zeroe0.awk zeroe0.in >tmp.
+$ cmp zeroe0.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$vms_io1: echo "vms_io1"
+$ if f$search("vms_io1.ok").eqs.""
+$ then create vms_io1.ok
+Hello
+$ endif
+$ ! define/User dbg$input sys$command:
+$ gawk /Input=sys$input _NL: /Output=tmp.
+# prior to 3.0.4, gawk crashed doing any redirection after closing stdin
+BEGIN { print "Hello" >"/dev/stdout" }
+$ cmp vms_io1.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$clean:
+$ if f$search("tmp.") .nes."" then rm tmp.;*
+$ if f$search("tmp.too") .nes."" then rm tmp.too;*
+$ if f$search("out%.") .nes."" then rm out%.;*
+$ if f$search("strftime.ok").nes."" then rm strftime.ok;*
+$ if f$search("test%.") .nes."" then rm test%.;*
+$ if f$search("seq.") .nes."" then rm seq.;*
+$ if f$search("_pid.in") .nes."" then rm _pid.in;*
+$ if f$search("[.junk]*.*").nes."" then rm [.junk]*.*;*
+$ if f$parse("[.junk]") .nes."" then rm []junk.dir;1
+$ return
+$
+$! make sure that the specified file's longest-record-length field is set;
+$! otherwise DIFF will choke if any record is longer than 512 bytes
+$fixup_LRL: subroutine
+$ lrl = 0 !VMS V5.5-2 didn't support the LRL argument yet
+$ define/user sys$error nl:
+$ define/user sys$output nl:
+$ lrl = f$file_attribute(p1,"LRL")
+$ if lrl.eq.0 then lrl = f$file_attribute(p1,"MRS")
+$ if lrl.eq.0
+$ then convert/fdl=sys$input: 'p1' *.*
+file
+ organization sequential
+record
+ format stream_lf
+ size 32767
+$ if $status .and. p2.eqs."purge" then rm 'p1';-1
+$ else cmp nl: nl: !deassign/user sys${error,output}
+$ endif
+$ endsubroutine !fixup_LRL
+$
+$! add a fake "EXIT CODE" record to the end of the temporary output file
+$! to simulate the ``|| echo EXIT CODE $$? >>_$@'' shell script usage
+$exit_code: subroutine
+$ if f$trnlnm("FTMP").nes."" then close/noLog ftmp
+$ open/Append ftmp tmp.
+$ write ftmp "EXIT CODE: ",p1
+$ close ftmp
+$ endsubroutine !exit_code
+$
+$!NOTREACHED
+$ exit
--- /dev/null
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+
+scriptversion=2005-02-02.22
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case "$1" in
+ '')
+ echo "$0: No files given. Try \`$0 --help' for more information." 1>&2
+ exit 1
+ ;;
+ --basedir)
+ basedir=$2
+ shift 2
+ ;;
+ -h|--h*)
+ cat <<\EOF
+Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+
+Wrapper for lex/yacc invocations, renaming files as desired.
+
+ INPUT is the input file
+ OUTPUT is one file PROG generates
+ DESIRED is the file we actually want instead of OUTPUT
+ PROGRAM is program to run
+ ARGS are passed to PROG
+
+Any number of OUTPUT,DESIRED pairs may be used.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v|--v*)
+ echo "ylwrap $scriptversion"
+ exit $?
+ ;;
+esac
+
+
+# The input.
+input="$1"
+shift
+case "$input" in
+ [\\/]* | ?:[\\/]*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Relative path. Make it absolute.
+ input="`pwd`/$input"
+ ;;
+esac
+
+pairlist=
+while test "$#" -ne 0; do
+ if test "$1" = "--"; then
+ shift
+ break
+ fi
+ pairlist="$pairlist $1"
+ shift
+done
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+ [\\/]* | ?:[\\/]*) ;;
+ *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines. But that might take us over the 14-char limit.
+dirname=ylwrap$$
+trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
+mkdir $dirname || exit 1
+
+cd $dirname
+
+case $# in
+ 0) $prog "$input" ;;
+ *) $prog "$@" "$input" ;;
+esac
+ret=$?
+
+if test $ret -eq 0; then
+ set X $pairlist
+ shift
+ first=yes
+ # Since DOS filename conventions don't allow two dots,
+ # the DOS version of Bison writes out y_tab.c instead of y.tab.c
+ # and y_tab.h instead of y.tab.h. Test to see if this is the case.
+ y_tab_nodot="no"
+ if test -f y_tab.c || test -f y_tab.h; then
+ y_tab_nodot="yes"
+ fi
+
+ # The directory holding the input.
+ input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
+ # Quote $INPUT_DIR so we can use it in a regexp.
+ # FIXME: really we should care about more than `.' and `\'.
+ input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'`
+
+ while test "$#" -ne 0; do
+ from="$1"
+ # Handle y_tab.c and y_tab.h output by DOS
+ if test $y_tab_nodot = "yes"; then
+ if test $from = "y.tab.c"; then
+ from="y_tab.c"
+ else
+ if test $from = "y.tab.h"; then
+ from="y_tab.h"
+ fi
+ fi
+ fi
+ if test -f "$from"; then
+ # If $2 is an absolute path name, then just use that,
+ # otherwise prepend `../'.
+ case "$2" in
+ [\\/]* | ?:[\\/]*) target="$2";;
+ *) target="../$2";;
+ esac
+
+ # We do not want to overwrite a header file if it hasn't
+ # changed. This avoid useless recompilations. However the
+ # parser itself (the first file) should always be updated,
+ # because it is the destination of the .y.c rule in the
+ # Makefile. Divert the output of all other files to a temporary
+ # file so we can compare them to existing versions.
+ if test $first = no; then
+ realtarget="$target"
+ target="tmp-`echo $target | sed s/.*[\\/]//g`"
+ fi
+ # Edit out `#line' or `#' directives.
+ #
+ # We don't want the resulting debug information to point at
+ # an absolute srcdir; it is better for it to just mention the
+ # .y file with no path.
+ #
+ # We want to use the real output file name, not yy.lex.c for
+ # instance.
+ #
+ # We want the include guards to be adjusted too.
+ FROM=`echo "$from" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+ TARGET=`echo "$2" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+
+ sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
+ -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
+
+ # Check whether header files must be updated.
+ if test $first = no; then
+ if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
+ echo "$2" is unchanged
+ rm -f "$target"
+ else
+ echo updating "$2"
+ mv -f "$target" "$realtarget"
+ fi
+ fi
+ else
+ # A missing file is only an error for the first file. This
+ # is a blatant hack to let us support using "yacc -d". If -d
+ # is not specified, we don't want an error when the header
+ # file is "missing".
+ if test $first = yes; then
+ ret=1
+ fi
+ fi
+ shift
+ shift
+ first=no
+ done
+else
+ ret=$?
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End: